wiki:library_locks

Version 10 (modified by laurent, 10 years ago) (diff)

--

The user_lock library

The user_lock.c and user_lock.h files define two types of services:

  • user-level atomic access functions, to increment a shared counter.
  • user-level spin-locks, to obtain exclusive access to a shared resource in a parallel multi-tasks application.

The proposed spin-lock implement a waiting queue service, to enforce fairness and avoid live-lock situations. Each lock (giet_lock_t object) occupies a complete 64 bytes cache line to avoid false sharing.

The user_lock_t being shared by several tasks, should be defined as a global variable in the application code. It is possible to control precisely the placement of a specific lock on a specific physical memory bank by defining a specific vseg in the application mapping.

Distributed version are available in user_sqt_lock.c and user_sqt_lock.h files.

Access functions

unsigned int atomic_increment( unsigned int* shared, unsigned int increment)

This function uses a LL/SC to atomically increment a shared variable.

  • ptr : pointer on the shared variable
  • increment : increment value.

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 functions

The sqt_lock can be used in multi-clusters architectures, and is implemented as a - physically distributed - Synchronisation-Quad-Tree (SQT). 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.