[net.unix] need help with unix semifors, possible OS bug

eklhad@ihnet.UUCP (K. A. Dahlke) (07/25/84)

/* sem_vax.c: test of vax/unix semifors */

/* This program seems to run on some machines (e.g. ibm370/unix5.0.3,
*  3b-20s/unix5.0.5, etc),
*  but not on our development machine (i.e. vax11780/unix5.0)
*  Actually, it does work sometimes, especially under light loads.
*  Unfortunately, we NEED semifors!!!!! 
*
*  This program becomes 4 processes which communicate via one semifor (simple)
*  Each process does a blocking decrement, a gets(), and an increment
*  in a forever loop.
*  The semifor starts at 1, so one process (first up) can decrement and begin.
*  After the user enters a line, it increments the semifor,
*  allowing the next-scheduled process to decrement it, and ask for input.
*  At no time should two processes be waiting on the tty.
*  It is a simple exclussive-access program.
*  Sometimes, I enter return, and get two (or more) "waiting input" lines.
*  Sometimes it is broke from the start, and i get multiple lines
*  without entering anything.
*  The problem is not deterministically reproducable.
*  Try entering input about every 15 seconds, when the Vax is busy.
*
*  Is it just a 5.0 bug that has been fixed?
*  Should i try to get a later release?
*  Is it a vax/unix bug?
*/

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

/* semop structures */
static struct sembuf decr[]= {
	{0,-1,SEM_UNDO}
};

static struct sembuf incr[]= {
	{0,1,SEM_UNDO}
};


main(){
	key_t mkey;
	int id2;

	mkey = (getgid()<<16);
	id2 = semget(mkey,1,IPC_CREAT|0660);
	if(id2<0){ 
		puts("bad semget"); 
		exit(0); 
	}
	if(semctl(id2,0,SETVAL,1)){
		puts("cannot set value to 0 (initially)");
		exit(0);
	}
	printf("val %d\n",semctl(id2,0,GETVAL,0));

	/* one process becomes 4 */
	fork(); 
	fork();

	while(1){
		char s[30];

		if(semop(id2,decr,1)<0)
			printf("bad call to semop(), errno %d\n",errno);
		/* mutual-exclussive begin */
		printf("process %d, val %d: awaiting input\n"
		,getpid(),semctl(id2,0,GETVAL,0));
		gets(s);
		/* Using sleep(15) instead of gets(s) does not help */
		/* mutual-exclussive end */
		if(semop(id2,incr,1)<0)
			printf("bad call to semop(), errno %d\n",errno);

	}
}
-- 

Karl Dahlke    ihnp4!ihnet!eklhad

rcd@opus.UUCP (Dick Dunn) (08/01/84)

What the hell is a semifor?

1.  It's for hauling things.  Ain't you ever seen a semi, you fool?

2.  It's a for-loop that terminates by a break statement in the middle
    (a solution to the  "n 1/2 iteration" problem).
-- 
Dick Dunn	{hao,ucbvax,allegra}!nbires!rcd		(303)444-5710 x3086
	...Keep your day job 'til your night job pays.