From: smant@nlr.nl (smant g.a.)
Newsgroups: comp.sys.sgi
Subject: Re: 4Dgifts: Shared Memory example
Date: 11 Jan 93 12:45:00 GMT

According to Dave Englund:
> 
> I'm looking at the sample codes in the
> /usr/people/4Dgifts/examples/unix  directory. The one problem I'm
> having is with the "shmem1" and "shmem2" example. This does nothing. I
> looked at the code and see that something is supposed to print
> somewhere, but that's not what happens. I'm running under 4.0.4 on a
> Crimson XS24. 
> All of the other samples in this directory seem to work fine. Any
> words of wisdom? Thanks in advance...
> 

A few months ago I also had some problems getting the sem_op1.c & sem_op2.c
to run correctly. There are some typos in the examples:

===========================================================================

/*
 *   sem_op1.c:
 *
 *    This set of programs (sem_op1 and sem_op2) illustrates a simple
 *  implementation of semaphore operations.  To demonstrate, first 
 *  execute sem_op1 (in the background ("sem_op1 &"), or from another
 *  window/shell), and then execute sem_op2.
 *
 *  References:  INTRO(2), SEMGET(2), SEMOP(2), SEMCTL(2), SIGNAL(2)
 *
 *                                     George Smith - 1987
 *
 */

#include <stdio.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define SEMKEY                10  /* Why not ? */
#define Program               "sem_op1"

/*
 *      This is the declaration as it appears in sem.h:
 *  struct sembuf {
 *      ushort  sem_num;        / semaphore # /
 *      short   sem_op;         / semaphore operation /
 *      short   sem_flg;        / operation flags /
 *  };
 */

struct sembuf sem_ar;
/*
 the int should be ushort here, and the 2 should be 1:

int  sig_array[2];
^^^           ^^^
 */
ushort sig_array[1];
int i, cleanup();
unsigned int count;
int semid;


main ()
{

/* Open semaphore */
/*
 the 2 should be 1 here:
        if( ( semid=semget(SEMKEY,2,0777|IPC_CREAT)) == -1) {
                                 ^^^
 */
        if( ( semid=semget(SEMKEY,1,0777|IPC_CREAT)) == -1) {
                printf("\n Can't open semaphor ( %s ) \n",Program);
                fflush(stdout);
                exit(-1);
        }

/* Catch signals */
/*      for(i=1; i<21 ; i++ ) 
                signal(i , cleanup );
*/

        
/* Set up initial value of 1 , 1 */
/*
 the array is now of length 1,
 and should be initialized to 0 in stead of 1:

        sig_array[0] = sig_array[1] = 1 ;
                     ^^^^^^^^^^^^^^^ ^^^
        if( semctl(semid,2,SETALL,sig_array) == -1 ) {
                        ^^^
 */

        sig_array[0] = 0 ;
        if( semctl(semid,1,SETALL,sig_array) == -1 ) {
                printf("\n Can't do semctl (%s)\n",Program);
                fflush(stdout);
                cleanup();
        }

/* Pause until sig_array[0] increments  */
        sem_ar.sem_num = 0 ;
        sem_ar.sem_op = -1 ;
        sem_ar.sem_flg = SEM_UNDO ;

        if(semop(semid, &sem_ar , 1 ) == -1 ) {
                printf("\n Can't do semop ( %s ) \n" , Program );
                fflush(stdout);
                cleanup() ;
        }


        printf("\n **> Was waiting on Increment , Now i am awake ( %s )\n",
                                                                Program);
        fflush(stdout);

/* Remove semid from system */

        cleanup();
}


cleanup() {

/*
 the number of semaphores has been reduced to 1:
        semctl(semid, 2 , IPC_RMID,0 );
                    ^^^^^
 */
        semctl(semid, 1 , IPC_RMID,0 );
        exit(1) ;
}        

===========================================================================

/* 
 *   sem_op2.c:
 *
 *     This set of programs (sem_op1 and sem_op2) illustrates a simple 
 *  implementation of semaphore operations.  To demonstrate, first 
 *  execute sem_op1 (in the background--i.e. "sem_op1 &"--or from another
 *  window/shell, and then execute sem_op2.
 *
 *  References:  INTRO(2), SEMGET(2), SEMOP(2), SEMCTL(2), SIGNAL(2)
 *
 *                                     George Smith - 1987
 */

#include <stdio.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define SEMKEY                10  /* Why not ? */
#define Program                "sem_op2"

/* 
 *     This is the declaration as it appears in sem.h:
 *
 *  struct sembuf {
 *      ushort  sem_num;        / semaphore # /
 *      short   sem_op;         / semaphore operation /
 *      short   sem_flg;        / operation flags /
 *  };
 *
 */

struct sembuf sem_ar;
/*
 the int should be ushort here, and the 2 should be 1:

int  sig_array[2];
^^^           ^^^
 */
ushort  sig_array[1];
int out_val[2];
int i;
unsigned int count;
int semid;
int val, num;


main () {

        void cleanup();
/* Open semaphore */
/*
 the 2 should be 1 here:
        if( ( semid=semget(SEMKEY,2,0777|IPC_CREAT)) == -1) {
                                 ^^^
 */
        if( ( semid=semget(SEMKEY,1,0777|IPC_CREAT)) == -1) {
                printf("\n Can't open semaphor ( %s ) \n",Program);
                fflush(stdout);
                exit(-1);
        }

/* Catch signals */
        for(i=1; i<21 ; i++ ) 
                signal(i , cleanup);

        

/* Get the value of the semaphores and print */
/*
 the number of semaphores has been reduced to 1:
        for( i=0 ; i<2 ; i++ ) {
 */
        for( i=0 ; i<1 ; i++ ) {
                if( (val =semctl(semid, i , GETVAL, out_val )) == -1 ){
                        printf("\n Can't read semval ( %s ) \n",Program);
                        fflush(stdout);
                        exit(-1);
                }
                printf("\n Semval [%d]: %d ",i,val );
                fflush(stdout);
        }

        printf("\n");
        fflush(stdout);

/* Incremewnt 0  */
        sem_ar.sem_num = 0 ;
        sem_ar.sem_op = 1;
        sem_ar.sem_flg = SEM_UNDO ;
        if( semop(semid, &sem_ar , 1 ) == -1 ) {
                printf("\n Can't do semop ( %s ) " ,Program );
                fflush(stdout);
                cleanup();
        }
        
/* sleep then die */
        sleep(1);
        cleanup();
}


void cleanup() {

/*
 the number of semaphores has been reduced to 1:
        semctl(semid, 2 , IPC_RMID,0 );
                    ^^^^^
 */
        semctl(semid, 1 , IPC_RMID,0 );
        exit(1) ;
}        

===========================================================================

-- 
Best Regards, Geert Albert Smant.
------------------------------------------------------------------------
Ing. G.A. Smant (Informatics Division, IR-NOP)
National Aerospace Laboratory (NLR)           Email:   smant@nlr.nl
Voorsterweg  31,  8316 PR Marknesse           Phone: (+31)(0)5274 - 8418
P.O. Box    153,  8300 AD Emmeloord                  (+31)(0)5274 - 8444
The Netherlands                               Fax:   (+31)(0)5274 - 8210
------------------------------------------------------------------------