= GIET-VM / Locks access functions = [[PageOutline]] The [source:soft/giet_vm/giet_common/locks.c locks.c] and [source:soft/giet_vm/giet_common/locks.h locks.h] files define the functions used by the kernel to take & release locks protecting exclusive access to a shared resource. The GIET_VM kernel define three types of spin-lock: 1. The '''simple_lock_t''' implements a spin-lock without waiting queue. It is only used by the TTY0 access functions, to get exclusive access to the TTY0 kernel terminal. 2. The '''spin_lock_t''' implements a spin-lock with a waiting queue (based on a ticket allocator scheme), to enforce fairness and avoid live-lock situations. The GIET_LOCK_MAX_TICKET define the wrapping value for the ticket allocator. This lock must be initialised. 3. The '''sbt_lock_t''' spin-lock can be used when a single lock protect a unique resource that can be used by any task running on a 2D mesh of clusters. The lock is implemented as a Sliced Binary Tree of ''partial'' locks distributed on all cluster of a 2D mesh. It is intended to avoid contention on a single cluster when all tasks try to access the same lock. All the lock access functions are prefixed by "_" to remind that they can only be executed by a processor in kernel mode. The '''simple_lock_t''', '''sbt_lock_t''', and '''spin_lock_t''' structures are implemented to have one single lock in a 64 bytes cache line, and should be aligned on a cache line boundary. == Atomic access functions == === unsigned int '''_atomic_increment'''( unsigned int * shared , unsigned int increment ) === This blocking function use a LL/SC to atomically increment a shared variable. * '''shared''' : pointer on the shared variable * '''increment''' : increment value == Simple lock access functions == === void '''_simple_lock_acquire'''( simple_lock_t * lock ) === This blocking function does not implement any ordered allocation, and is not distributed. It returns only when the lock as been granted. === void '''_simple_lock_release'''( simple_lock_t * lock ) === This function releases the lock, and can be used for lock initialisation. It must always be called after a successful _simple_lock_acquire(). == Queuing Lock Access functions == === void '''_lock_init'''( spin_lock_t * lock ) === This function initializes the lock ticket allocator. === void '''_lock_acquire'''( spin_lock_t * lock ) === This blocking function uses the atomic_increment() function, to implement a ticket allocator and provide ordered access to the protected resource. It returns only when the lock as been granted. === void '''_lock_release'''( spin_lock_t * lock ) === This function releases the lock, but cannot be used for lock initialisation. It must always be called after a successful _lock_acquire(). == Distributed Lock Access functions == === void '''sbt_lock_init'''( sbt_lock_t* lock, unsigned int ntasks ) === === void '''sbt_lock_acquire'''( sbt_lock_t* lock ) === === void '''sbt_lock_release'''( sbt_lock_t* lock ) ===