All pastes #1711530 Raw Edit

bblum

public text v1 · immutable
#1711530 ·published 2009-12-11 22:17 UTC
rendered paste body
extern int yield(int pid);extern int xchg(int *foo, int bar);#define IN_USE 1#define AVAILABLE 0struct mutex_waiter {	struct mutex_waiter *next;	struct mutex_waiter *prev;	int pid;};struct mutex {	volatile int lock;	volatile int owner;	struct mutex_waiter *wait_list;};static inline void wait_list_add(struct mutex *m,				 struct mutex_waiter *node){	node->prev = m->wait_list->prev;	node->next = &m->wait_list;	if (node->prev)		m->wait_list.prev->next = node;	m->wait_list.prev = node;}static inline int wait_list_pop(struct mutex *m){	int pid;	if (!m->wait_list.next)		return 0;	pid = m->wait_list.next->pid;	m->wait_list.next->next->prev = &m->wait_list;	m->wait.list.next = m->wait_list.next->next;	return pid;}void spin_lock_lock(int *lock){	while (xchg(lock, IN_USE) == IN_USE)		yield(-1);}void spin_lock_unlock(int *lock){	*lock = AVAILABLE;}void mutex_lock(struct mutex *m){	int pid = getpid();	struct mutex_waiter node;	spin_lock_lock(&m->lock);	if (!m->owner) {		/* have the lock */		m->owner = pid;	} else {		node.pid = pid;		wait_list_add(m, &node);		while (m->owner != pid) {			spin_lock_unlock(&m->lock);			yield(m->owner);			spin_lock_lock(&m->lock);		}		/* have the lock */	}	spin_lock_unlock(&m->lock);	return;}void mutex_unlock(struct mutex *m){	spin_lock_lock(&m->lock);	m->owner = wait_list_pop(m);	spin_lock_unlock(&m->lock);}