
/* y.cpp */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
// #include <ncursesw/curses.h>
#define LOCK_SEMA   -1
#define UNLOCK_SEMA  1
#define KEY  1234567L     

static int semid = -1;

int printSemaValue(int line, const char *pStr) {

   int semVal0(0), semVal1(0);

   semVal0 = semctl (semid, 0, GETVAL);
   if (semVal0 < 0) {
      printf ("retcode < 0 from semct (%d, 0, GETVAL)\n\n", semid);
      return semVal0;
   }

   semVal1 = semctl (semid, 1, GETVAL);
   if (semVal1 < 0) {
      printf ("retcode < 0 from semct (%d, 1, GETVAL)\n\n", semid);
      return semVal1;
   }

   printf ("\n");
   // flash();

   printf ("semVal0 GETVAL %d\n", semVal0);
   // flash();

   printf ("semVal1 GETVAL %d\n%s, in Line %d\n", semVal1, pStr, line);
   // flash();

   return 1;

} 

static int init_semaphore (void) {

   int semVal0(0), semVal1(0);

   semid = semget (KEY, 0, IPC_PRIVATE);
   if (semid < 0) {
      printf ("\n sema was not created\n");
      return semid;
   }

   semVal0 = semctl (semid, 0, GETVAL);
   if (semVal0 < 0) {
      printf ("retcode < 0 from semct (%d, 0, GETVAL)\n\n", semid);
      return semVal0;
   }

   semVal1 = semctl (semid, 1, GETVAL);
   if (semVal0 < 0) {
      printf ("retcode < 0 from semct (%d, 1, GETVAL)\n\n", semid);
      return semVal1;
   }

   return 1;
}

static int semaOp (int op, int semNum) {
   struct sembuf semaphore;
   semaphore.sem_num = semNum;
   semaphore.sem_op  = op;
   semaphore.sem_flg = SEM_UNDO;
   if( semop (semid, &semaphore, 1) == -1) {
      return -1;
   }
   return 1;
}

int main (void) {
   long loop, res;

   res = init_semaphore ();
   if (res < 0) {
      printf ("\nretcode < 0 from init_semaphore\n");

      semctl(semid, 1, IPC_RMID, 0);

      return res;
   }

   printSemaValue(__LINE__, "After init_semaphore()");

   for (loop =0; loop<100000; ++loop) {

      printf ("\nloop = %ld\n", loop);
      // flash();

      res = semaOp (LOCK_SEMA, 1);
      if (res < 0) {
         int err = errno;
         if (err == ERANGE)
            printf ("In Line %d: LOCK_SEMA 1 was not successful, errno = %d (ERANGE)\n", 
				__LINE__, errno);
         else
            printf ("In Line %d: LOCK_SEMA 1 was not successful, errno = %d\n", 
				__LINE__, errno);
         
         break;
      }

      //usleep (3);

      res = semaOp (UNLOCK_SEMA, 0);
      if (res < 0) {
         int err = errno;
         if (err == ERANGE) {
            printf ("In Line %d: UNLOCK_SEMA 0 was not successful, errno = %d (ERANGE)\n", 				__LINE__, errno);
         }
         else {
            printf ("In Line %d: UNLOCK_SEMA 0 was not successful, errno = %d\n", 
			__LINE__, errno);
         }
   
         break;
      }

      printf ("\n");

   } // for ...

   // semctl(semid, 0, IPC_RMID, 0);

   return 1;
}

