rendered paste bodyextern 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);}