Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Semaphore code Wanted to arbitrate Shared Memory.

6 views
Skip to first unread message

Curtis Siemens

unread,
Apr 10, 1995, 3:00:00 AM4/10/95
to
We have a few processes that each read and/or write some shared memory.

We currently use 1 semaphore for each piece of data in the shared memory.
The problems is that there is heavy semaphore usage, and our current
simple implementation allows only one process to look at a piece of
data at 1 time.

What I think we need to move towards is a 'read-lock & write-lock'
semaphore(s), so that many reader's could read at the same time, while
only 1 writer would be allowed to update the particular data and
every other reader/writer would be blocked.

Does anyone have some C source code that does this that they would
be willing to send me? Or does anyone know where I could download
some source like this?

thanks,
Curtis Siemens (sie...@mprgate.mpr.ca)

Joe Seigh

unread,
Apr 11, 1995, 3:00:00 AM4/11/95
to

Try this. This also will fail lock requests if an exclusive holder of
the lock terminates abnormally possibly leaving the data in an inconsistent
state.

#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/mode.h>

int initialize(int *semid, char *path, char id) {
key_t key;
unsigned short val[3]={1, 0, 0};

if ((key=ftok(path, id))<0)
return -1;

if ((*semid=semget(key, 3, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR))>=0) {
semctl(*semid, 0, SETALL, val);
}
else
if (errno==EEXIST) {
if ((*semid=semget(key, 3, S_IRUSR|S_IWUSR))<0) {
return -1;
}
}
else {
return -1;
}
return 0;
}
int acquire_shared(int semid) {
struct sembuf sb[4];
sb[0].sem_flg= 0; sb[0].sem_num=0; sb[0].sem_op=-1;
sb[1].sem_flg= SEM_UNDO; sb[1].sem_num=1; sb[1].sem_op=+1;
sb[2].sem_flg= 0; sb[2].sem_num=0; sb[2].sem_op=+1;
sb[3].sem_flg=IPC_NOWAIT; sb[3].sem_num=2; sb[3].sem_op= 0;
return semop(semid, sb, 4);
}
int release_shared(int semid) {
struct sembuf sb[1];
sb[0].sem_flg=SEM_UNDO; sb[0].sem_num=1; sb[0].sem_op=-1;
return semop(semid, sb, 1);
}
int acquire_exclusive(int semid) {
struct sembuf sb[2];
int rc;
sb[0].sem_flg= SEM_UNDO; sb[0].sem_num=0; sb[0].sem_op=-1;
sb[1].sem_flg=IPC_NOWAIT; sb[1].sem_num=2; sb[1].sem_op= 0;
if ((rc=semop(semid, sb, 2))<0)
return rc;
sb[0].sem_flg= 0; sb[0].sem_num=1; sb[0].sem_op= 0;
sb[1].sem_flg= 0; sb[1].sem_num=2; sb[1].sem_op=+1;
if ((rc=semop(semid, sb, 2))<0 && errno!=EIDRM) {
sb[0].sem_flg= SEM_UNDO; sb[0].sem_num=0; sb[0].sem_op=+1;
if (semop(semid, sb, 1)<0)
abort();
}
return rc;
}
int release_exclusive(int semid) {
struct sembuf sb[2];
/* reset flag */
sb[0].sem_flg=SEM_UNDO; sb[0].sem_num=0; sb[0].sem_op=+1;
sb[1].sem_flg= 0; sb[1].sem_num=2; sb[1].sem_op=-1;
return semop(semid, sb, 2);
}
int cleanup(int semid) {
return semctl(semid,0,IPC_RMID,0);
}


--
Joe Seigh

0 new messages