Version 12 (modified by 10 years ago) (diff) | ,
---|
The user_lock library
The user_lock.c and user_lock.h files define two types of locks:
- user_lock_t : this lock uses a ticket allocation mechanism to enforce fairness and avoid live-locks. This lock is located in one single cluster, and the placement can be controlled by defining a specific vseg in the application mapping.
- sqt_lock_t : this distributed lock can be used to avoid quadratic latency, when the protected resource is shared by a large number or threads. The SQT (Synchronization Quad-Tree) is distributed on all clusters of the mesh.
Each lock (user_lock_t object, or distributed sqt_lock_node_t) occupies a complete 64 bytes cache line to avoid false sharing.
The user_lock_t and sqt_lock_t being shared by several threads, should be defined as a global variable in the application code.
Atomic access functions
Both types of locks use the atomic_increment() function, that can be directly used by the applications.
unsigned int atomic_increment( unsigned int* shared, unsigned int increment)
This blocking function uses a LL/SC to atomically increment a shared variable.
- ptr : pointer on the shared variable
- increment : increment value.
Simple lock access functions
void lock_init( user_lock_t * lock )
This function should be called by one single task.
- lock : pointer on the user_lock_t structure.
void lock_acquire( user_lock_t * lock )
This blocking function returns only when the lock has been successfully taken.
- lock : pointer on the user_lock_t structure.
void lock_release( user_lock_t * lock )
This function releases the lock. It must be called by a task after a successful lock_acquire().
- lock : pointer on the user_lock_t structure.
Distributed lock access functions
The SQT topology is completely defined by the (x_size / y_size) parameters, with the following constraints:
- The involved clusters form a mesh(x_size * y_size).
- The lower left involved cluster is cluster(0,0).
- All involved clusters must contain a heap_x_y vseg declared in the mapping.
- The number of involved tasks in a given cluster is the same for all involved clusters.
void sqt_lock_init( sqt_lock_t * lock )
This function should be called by one single task.
- lock : pointer on the sqt_lock_t structure.
void sqt_lock_acquire( sqt_lock_t * lock )
This blocking function returns only when all locks of the distributed tree have been successfully taken.
- lock : pointer on the sqt_lock_t structure.
void sqt_lock_release( sqt_lock_t * lock )
This function releases the lock. It must be called by a task after a successful lock_acquire().
- lock : pointer on the sqt_lock_t structure.