Skip to content

Sync artifacts

Sudheer edited this page Jan 14, 2023 · 9 revisions

unix like OS provide synchronization artifacts viz. mutex locks and semaphores. Mutexes can be used to synchronize threads only, while semaphores can be used by more than one processes in the system.

In certain situations, what is necessary is a mechanism of mutual exclusion or read write lock achieved via a busy wait instead of putting the calling thread to sleep and waking it upon availability of the artifact. This is so in cases where the expected contention is very less (usually one or two threads occasionally accessing the artifact).

The set of functions listed here are intended for such situations, where it is necessary to programmatically ensure that code is protected against effects of concurrent reads/writes, while the actual concurrency is less. The implementation of sync in these functions is achieved through usage of std atomic operations.

Read write lock

A read-write lock is an artifact that allows more than one threads to hold a read lock, while allowing one and only one thread to hold the write lock. Also while one thread is holding write lock, any other thread will not be able to acquire read lock.

typedef struct ev_rwlock_s ev_rwlock_type;*

#include <ev_rwlock.h>

ev_rwlock_type ev_rwlock_init(ev_rwlock_type s);

DESCRIPTION:
	Allocates and initializes a new rw-lock artifact
ARGUMENTS:
	void
RETURN:
	ev_rwlock_type : A new rw-lock artifact.

void ev_rwlock_destroy(ev_rwlock_type s);

DESCRIPTION:
	Clears up and frees a previously created lock.
ARGUMENTS:
	ev_rwlock_type s : A lock that has been previously created using ev_rwlock_init
RETURN:
	void
void ev_rwlock_destroy(ev_rwlock_type s);

int ev_rwlock_rdlock(ev_rwlock_type s);

DESCRIPTION:
	Sets the read lock in the given input rw-lock. This operation prevents
	other threads from locking the same rw-lock for write operation, while 
	other threads wanting a read permission on the same articat are still allowed.
	Read lock cannot be obtained while another thread holds a write lock.
	
	The operation spins until the read lock is attained
ARGUMENTS:
	ev_rwlock_type s: An rw-lock artifact created through ***ev_rwlock_init***
RETURN:
	0 indicating successful acquisition of lock
int ev_rwlock_rdlock(ev_rwlock_type s);

int ev_rwlock_rdunlock(ev_rwlock_type s);

DESCRIPTION:
	Unsets the read lock (releases the lock) in the given input rw-lock.
	If this is the last thread releasing the lock and if a thread is waiting for write lock
	the waiting thread will acquire write lock after this operation.

ARGUMENTS:
	ev_rwlock_type s: An rw-lock artifact created through ***ev_rwlock_init***
RETURN:
	0 indicating successful acquisition of lock
int ev_rwlock_rdunlock(ev_rwlock_type s);

int ev_rwlock_wrlock(ev_rwlock_type s);

DESCRIPTION:
	Sets the write lock in the given rw-lock.
	If there are other threads having read/write lock then this operation blocks.
	While one thread is attempting to acquire a write lock, other threads will be prevented
	from further acquiring read/write lock.

	The operation spins until the read lock is attained
ARGUMENTS:
	ev_rwlock_type s: An rw-lock artifact created through ***ev_rwlock_init***
RETURN:
	0 indicating successful acquisition of lock
int ev_rwlock_wrlock(ev_rwlock_type s);

int ev_rwlock_wrunlock(ev_rwlock_type s);

DESCRIPTION:
	Releases the previously acquired write lock
	This will unblock other threads waiting to acquire read/write lock

	The operation spins until the read lock is attained
ARGUMENTS:
	ev_rwlock_type s: An rw-lock artifact created through ***ev_rwlock_init***
RETURN:
	0 indicating successful acquisition of lock
int ev_rwlock_wrunlock(ev_rwlock_type s);

Spin lock

Implementation of mutual exchange through usage of std atomic variable and by using busy wait

#include <ev_spin_lock.h>

spin_lock_p_type create_spin_lock(ev_rwlock_type s);

DESCRIPTION:
	Allocates and initializes a new spin-lock artifact

ARGUMENTS:
	void

RETURN:
	spin_lock_p_type : A new spin-lock artifact.

void destroy_spin_lock(spin_lock_p_type s);

DESCRIPTION:
	Clears up and frees a previously created spin-lock.

ARGUMENTS:
	spin_lock_p_type s : A lock that has been previously created using create_spin_lock

RETURN:
	void

int ev_spin_try_lock(spin_lock_p_type s);

DESCRIPTION:
	Sets the spin-lock structure as locked.
	It will not be possible for another thread to lock while one thread has
	locked the structure.
	
	The operation does not spin while the lock is unavailable, instead it returns
	immediately.

ARGUMENTS:
	spin_lock_p_type s: An spin-lock artifact created through ***create_spin_lock***

RETURN:
	0 indicating unsuccessful acquisition of lock
	1 indicating successful acquisition of lock

void ev_spin_lock(spin_lock_p_type s);

DESCRIPTION:
	Sets the spin-lock structure as locked.
	It will not be possible for another thread to lock while one thread has
	locked the structure.

	The operation does not return while the lock is unavailable

ARGUMENTS:
	spin_lock_p_type s: An spin-lock artifact created through ***create_spin_lock***

RETURN:
	void

void ev_spin_unlock(spin_lock_p_type s);

DESCRIPTION:
	Unsets the lock (releases the lock) in the given input spin-lock.

ARGUMENTS:
	spin_lock_p_type s: An spin-lock artifact created through ***create_spin_lock***
	and locked through either ev_spin_lock or ev_spin_try_lock

RETURN:
	void

MCS (Mellor Crummey and Scott) spin lock

Mellor Crummey and Scott presented a spinlock that avoids network contention by having processors spin on local memory locations Their algorithm is equivalent to a lockfree queue with a special access pattern The authors provide a complex and unintuitive proof of the correctness of their algorithm

typedef atomic_uintptr_t ev_mcs_lock_type;

#include <ev_mcs_lock.h>

void mcs_init(ev_mcs_lock_type *p);

DESCRIPTION:
	Initializes the ev_mcs_lock_type input

ARGUMENTS:
	ev_mcs_lock_type * p : lock variable

RETURN:
	void

int mcs_relinquish(ev_mcs_lock_type , void );

DESCRIPTION:
	Relinquishes a previously acquired lock

ARGUMENTS:
	ev_mcs_lock_type * : A lock that has been previously initialized using ***mcs_init***
	void * access: The ticket (access) that was returned when *** mcs_get_access *** was called

RETURN:
	int : 0

void * mcs_get_access(ev_mcs_lock_type *);

DESCRIPTION:
	Acquires the lock through mcs algorithm
	It will not be possible for another thread to lock while one thread has
	locked the structure.
	
	The operation does not return while the lock is unavailable

ARGUMENTS:
	ev_mcs_lock_type *: AA lock that has been previously initialized using ***mcs_init***

RETURN:
	void * access: The ticket which the caller should return at the time of relinquishment