我使用futex系统调用实现了互斥和变量变量。我相信我的实现是正确的,但希望由其他人验证。如果你们中的一些人可以验证它的正确性,那将是一个很大的帮助。
任何有关进一步改进互斥锁和变量变量性能的建议也将受到赞赏。
#ifndef __SYNCHRONIZATION__
#define __SYNCHRONIZATION__
#include <unistd.h>
#include <limits.h>
#include <sys/syscall.h>
#include <linux/futex.h>
#include "types.h"
#include "assembly.h"
typedef UINT32 mutex;
typedef struct condvar condvar;
struct condvar {
mutex *m;
int seq;
};
void mutex_init(mutex *m) {
*m = 0;
}
void mutex_destroy(mutex *m) {
*m = 0;
}
void mutex_lock(mutex *m) {
UINT32 c;
if((c = __sync_val_compare_and_swap(m, 0, 1)) != 0) {
do {
if((c == 2) || __sync_val_compare_and_swap(m, 1, 2) != 0)
syscall(SYS_futex, m, FUTEX_WAIT_PRIVATE, 2, NULL, NULL, 0);
} while((c = __sync_val_compare_and_swap(m, 0, 2)) != 0);
}
}
void mutex_unlock(mutex *m) {
if(__sync_fetch_and_sub(m, 1) != 1) {
*m = 0;
syscall(SYS_futex, m, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0);
}
}
void cond_init(condvar *c, mutex *m) {
c->m = m;
c->seq = 0;
}
void cond_destroy(condvar *c) {
c->m = NULL;
c->seq = 0;
}
void cond_signal(condvar *c) {
__sync_fetch_and_add(&(c->seq), 1);
syscall(SYS_futex, &(c->seq), FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0);
}
void cond_broadcast(condvar *c) {
__sync_fetch_and_add(&(c->seq), 1);
syscall(SYS_futex, &(c->seq), FUTEX_REQUEUE_PRIVATE, 1, (void *) INT_MAX, c->m, 0);
}
void cond_wait(condvar *c) {
UINT32 oldSeq = c->seq;
mutex_unlock(c->m);
syscall(SYS_futex, &(c->seq), FUTEX_WAIT_PRIVATE, oldSeq, NULL, NULL, 0);
while (xchg32(c->m, 2)) {
syscall(SYS_futex, c->m, FUTEX_WAIT_PRIVATE, 2, NULL, NULL, 0);
}
}
#endif
由于
Sudhanshu