Eucalyptus的封锁没有级别,没有类型,只有一种,就是互斥锁,就是把互斥量,条件变量封装到一起了,来实现操作系统中的PV操作,
直接看下面的函数,可直接看懂
typedef struct sem_struct {
int sysv;
sem_t * posix;
pthread_mutex_t mutex;
pthread_cond_t cond;
int usemutex, mutwaiters, mutcount;
char * name;
} sem;
sem * sem_alloc (const int val, const char * name)
{
DECLARE_ARG;
sem * s = malloc (sizeof (sem));
if (s==NULL) return NULL;
bzero (s, sizeof (sem));
s->sysv = -1;
if (name && !strcmp(name, "mutex")) { /* use pthread mutex */
s->usemutex = 1;
s->mutcount = val;
s->mutwaiters = 0;
pthread_mutex_init(&(s->mutex), NULL);
pthread_cond_init(&(s->cond), NULL);
} else if (name) { /* named semaphores */
if ( sem_unlink (name) == 0) { /* clean up in case previous sem holder crashed */
logprintfl (EUCAINFO, "sem_alloc(): cleaning up old semaphore %s/n", name);
}
if ((s->posix = sem_open (name, O_CREAT | O_EXCL, 0644, val))==SEM_FAILED) {
free (s);
return NULL;
}
s->name = strdup (name);
} else { /* SYS V IPC semaphores */
s->sysv = semget (IPC_PRIVATE, /* private to process & children */
1, /* only need one */
IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR /* user-only */);
if (s->sysv<0) {
free (s);
return NULL;
}
/* set the value */
arg.val = val;
if (semctl(s->sysv, 0, SETVAL, arg) == -1) {
free (s);
return NULL;
}
}
return s;
}
int sem_p (sem * s)
{
int rc;
if (s && s->usemutex) {
rc = pthread_mutex_lock(&(s->mutex));
s->mutwaiters++;
while(s->mutcount == 0) {
pthread_cond_wait(&(s->cond), &(s->mutex));
}
s->mutwaiters--;
s->mutcount--;
rc = pthread_mutex_unlock(&(s->mutex));
return(rc);
}
if (s && s->posix) {
return sem_wait(s->posix);
}
if (s && s->sysv > 0) {
struct sembuf sb = {0, -1, 0};
return semop (s->sysv, &sb, 1);
}
return -1;
}
int sem_v (sem * s)
{
int rc;
if (s && s->usemutex) {
rc = pthread_mutex_lock(&(s->mutex));
if (s->mutwaiters > 0) {
rc = pthread_cond_signal(&(s->cond));
}
s->mutcount++;
rc = pthread_mutex_unlock(&(s->mutex));
return(rc);
}
if (s && s->posix) {
return sem_post(s->posix);
}
if (s && s->sysv > 0) {
struct sembuf sb = {0, 1, 0};
return semop (s->sysv, &sb, 1);
}
return -1;
}
void sem_free (sem * s)
{
DECLARE_ARG;
if (s && s->posix) {
sem_close (s->posix);
sem_unlink (s->name);
free (s->name);
}
if (s && s->sysv > 0) {
semctl (s->sysv, 0, IPC_RMID, arg); /* TODO: check return */
}
free (s);
}