home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume02 / phil < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  29.6 KB

  1. From mipos3!omepd!littlei!uunet!husc6!necntc!ncoast!allbery Sat Apr  9 16:59:52 PDT 1988
  2. Article 338 of comp.sources.misc:
  3. Path: td2cad!mipos3!omepd!littlei!uunet!husc6!necntc!ncoast!allbery
  4. From: jrp@rducky.UUCP (Jim Pickering)
  5. Newsgroups: comp.sources.misc
  6. Subject: v02i085: phil -- Example of the "Dining Philosophers" problem (System V)
  7. Message-ID: <8804030618.AA28087@csun.edu>
  8. Date: 3 Apr 88 06:18:38 GMT
  9. Sender: allbery@ncoast.UUCP
  10. Reply-To: jrp@rducky.UUCP (Jim Pickering)
  11. Lines: 675
  12. Approved: allbery@ncoast.UUCP
  13. comp.sources.misc: Volume 2, Issue 85
  14. Submitted-By: "Jim Pickering" <jrp@rducky.UUCP>
  15. Archive-Name: phil
  16.  
  17. comp.sources.misc: Volume 2, Issue 85
  18. Submitted-By: "Jim Pickering" <jrp@rducky.UUCP>
  19. Archive-Name: phil
  20.  
  21. [An example of the "dining philosophers" problem in process synchronization,
  22. implemented via System V semaphores.  Should be educational both with regard
  23. to process synchronization and to semaphore usage.  ++bsa]
  24.  
  25. #--------------------------------CUT HERE-------------------------------------
  26. #! /bin/sh
  27. #
  28. # This is a shell archive.  Save this into a file, edit it
  29. # and delete all lines above this comment.  Then give this
  30. # file to sh by executing the command "sh file".  The files
  31. # will be extracted into the current directory owned by
  32. # you with default permissions.
  33. #
  34. # The files contained herein are:
  35. #
  36. # -rw-r--r--  1 jrp     users     27897 Apr  2 15:14 phil.c
  37. #
  38. echo 'x - phil.c'
  39. if test -f phil.c; then echo 'shar: not overwriting phil.c'; else
  40. sed 's/^X//' << '________This_Is_The_END________' > phil.c
  41. X/***********************************************************************/
  42. X/**                             PHIL.C                                **/
  43. X/**                                                                   **/
  44. X/**                       (c) COPYRIGHT 1988                          **/
  45. X/**                       JAMES R. PICKERING                          **/
  46. X/**                       ALL RIGHTS RESERVED                         **/
  47. X/**                                                                   **/
  48. X/** Jim Pickering               || (n)   ..csustan!polyslo!rducky!jrp **/
  49. X/**                             || (s)   ..sdsu!polyslo!rducky!jrp    **/
  50. X/** Arroyo Grande, CA 93420     ||       jrp@rducky.UUCP              **/
  51. X/** (805) 473-1037                                                    **/
  52. X/**                                                                   **/
  53. X/**  DESCRIPTION:  This file contains a program which demonstrates    **/
  54. X/**   Dijkstra's Dining Philosophers Problem (see "Cooperating        **/
  55. X/**   Sequential Processes," Technical Report EWD-123, Technological  **/
  56. X/**   University, Eindhoven, The Netherlands, (1965)).  It is con-    **/
  57. X/**   sidered a classic process synchronization problem.  It is       **/
  58. X/**   implemented using SVR2 semaphores and curses.  With this as an  **/
  59. X/**   example, you may be able to figure out how to use SV semaphores.**/
  60. X/**                                                                   **/
  61. X/**  PROBLEM DESCRIPTION:  Five philosophers spend their lives        **/
  62. X/**   thinking and eating.  They share a common table.  Each has his/ **/
  63. X/**   her own chair.  At the center of the table is a bowl of rice.   **/
  64. X/**   The table is laid with five chopsticks (see figure below).  When**/
  65. X/**   a philosopher thinks, he/she (the hell with this he/she crap ...**/
  66. X/**   all philosophers referenced furthur are hermaphrodites and will **/
  67. X/**   be refered to as 'he') does not eat, and vice versa. When a     **/
  68. X/**   philosopher is hungry he tries to pick up the two chopsticks    **/
  69. X/**   that are closest to him.  He may only pick up one stick at a    **/
  70. X/**   time.  When he has both chopsticks, he eats without releasing   **/
  71. X/**   his chopsticks.  When he is finished eating, he puts down both  **/
  72. X/**   chopsticks and starts thinking.                                 **/
  73. X/**                                                                   **/
  74. X/**                        PHIL1    |    PHIL2                        **/
  75. X/**                   \                           /                   **/
  76. X/**                                                                   **/
  77. X/**                PHIL5          (rice)           PHIL3              **/
  78. X/**                                                                   **/
  79. X/**                                                                   **/
  80. X/**                     /         PHIL4        \                      **/
  81. X/**                                                                   **/
  82. X/**  COMPILE:  cc -O -s -o phil phil.c -lcurses                       **/
  83. X/***********************************************************************/
  84. X/**  FUNCTIONS:                                                       **/
  85. X/**               void clean_die()                                    **/
  86. X/**               void die()                                          **/
  87. X/**               void sleeper()                                      **/
  88. X/**               void hungry(p_num)                                  **/
  89. X/**                       int p_num;                                  **/
  90. X/**               void thinking(p_num)                                **/
  91. X/**                       int p_num;                                  **/
  92. X/**               void eating(p_num)                                  **/
  93. X/**                       int p_num;                                  **/
  94. X/**               void killit(semid,array_ptr)                        **/
  95. X/**                       int semid, *array_ptr;                      **/
  96. X/**               void cleanup()                                      **/
  97. X/**               void printit(p_num,action)                          **/
  98. X/**                       int p_num, action;                          **/
  99. X/**               bool V_semaphore(sem_num)                           **/
  100. X/**                    int sem_num;                                   **/
  101. X/**               bool P_semaphore(sem_num,block)                     **/
  102. X/**                    int sem_num;                                   **/
  103. X/**                    bool block;                                    **/
  104. X/***********************************************************************/
  105. X
  106. Xstatic char philc[] = "@(#)phil1.c    1.1 JAMES R. PICKERING 3/23/88";
  107. X
  108. X#include     <sys/types.h>
  109. X#include     <sys/ipc.h>
  110. X#include     <sys/sem.h>
  111. X#include     <curses.h>
  112. X#include     <signal.h>
  113. X#include     <errno.h>
  114. X
  115. X#define     NUM_CHILDREN     5     /* number of dining philosophers  */
  116. X                                   /* don't change this!!!!!!!!!!!!  */
  117. X                                   /* the display routines depend on */
  118. X                                   /* this.                          */
  119. X
  120. X#define     SLEEP_TIME       10    /* maximum amount of time (minus 1)
  121. X                                      in seconds the child processes
  122. X                                      eat and think.                   */
  123. X
  124. X#define     EATING           1
  125. X#define     THINKING         2
  126. X#define     HAS_ONE          3
  127. X#define     HUNGRY           4
  128. X
  129. Xvoid die();
  130. Xvoid clean_die();
  131. Xvoid sleeper();
  132. Xvoid hungry();
  133. Xvoid thinking();
  134. Xvoid eating();
  135. Xvoid killit();
  136. Xvoid cleanup();
  137. Xvoid printit();
  138. Xbool V_semaphore();
  139. Xbool P_semaphore();
  140. X
  141. Xint semid;    /* the semaphore set id */
  142. Xint pid_array[NUM_CHILDREN];   /* array of children's pids */
  143. X
  144. Xmain()
  145. X{
  146. X
  147. X        /************************************************/
  148. X        /*variable declarations for semaphore definition*/
  149. X        /************************************************/
  150. X
  151. X        key_t key;
  152. X        int opperm, nsems;
  153. X        int opperm_flags;
  154. X
  155. X        /****************************************************/
  156. X        /*variable declarations for semaphore initialization*/
  157. X        /****************************************************/
  158. X
  159. X        struct semid_ds semid_ds;
  160. X        int i, length;
  161. X        int retrn;
  162. X        union semnum
  163. X        {
  164. X                int val;
  165. X                struct semid_ds *buf;
  166. X                ushort array[25];
  167. X        } arg;
  168. X
  169. X
  170. X        /*******************************************************/
  171. X        /*variable declarations for dining philosophers problem*/
  172. X        /*******************************************************/
  173. X
  174. X        int p_num;
  175. X
  176. X        /***********************************/
  177. X        /*get a semaphore set from the O.S.*/
  178. X        /***********************************/
  179. X
  180. X        key = IPC_PRIVATE;
  181. X        opperm = 0600;
  182. X        opperm_flags = (opperm | IPC_CREAT | IPC_EXCL);
  183. X        nsems = NUM_CHILDREN;
  184. X        if((semid = semget(key,nsems,opperm_flags)) == -1)
  185. X        {
  186. X                perror("The semget call failed with semget(key,nsems,opperm_flags).");
  187. X                exit(0);
  188. X        }
  189. X
  190. X        /************************************************/
  191. X        /*initialize the five semaphores in the set to 1*/
  192. X        /************************************************/
  193. X
  194. X        arg.buf = &semid_ds;
  195. X        if ((retrn = semctl(semid,0,IPC_STAT,arg.buf)) == -1)
  196. X        {
  197. X                perror("The semctl call failed on finding the number of semaphores with semctl(semid,0,IPC_STAT,arg.buf).");
  198. X                exit(0);
  199. X        }
  200. X        length = arg.buf -> sem_nsems;
  201. X        for (i=0; i<length; i++)
  202. X                arg.array[i] = 1;
  203. X        if ((retrn = semctl(semid,0,SETALL,arg.array)) == -1)
  204. X        {
  205. X                perror("The semctl call failed on initializing the semaphores with semctl(semid,0,SETALL,arg.array).");
  206. X                exit(0);
  207. X        }
  208. X
  209. X        /**********************************************/
  210. X        /*fork off five dining philosophers (children)*/
  211. X        /**********************************************/
  212. X
  213. X        for (i=1; i<=NUM_CHILDREN; i++)
  214. X        {
  215. X                if ((pid_array[i-1] = fork()) == 0)
  216. X                {
  217. X                        initscr();
  218. X                        (void)signal(SIGHUP,clean_die);
  219. X                        (void)signal(SIGQUIT,clean_die);
  220. X                        (void)signal(SIGINT,clean_die);
  221. X                        refresh();
  222. X                        (void)sleep(2);
  223. X                        srand((unsigned)time((long *)0));
  224. X                        p_num = i;
  225. X
  226. X        /**************************************************************/
  227. X        /*philosopher (child) thinks, becomes hungry, eats, thinks ...*/
  228. X        /**************************************************************/
  229. X
  230. X                        while(TRUE)
  231. X                        {
  232. X                                thinking(p_num);
  233. X                                hungry(p_num);
  234. X                                eating(p_num);
  235. X                        }
  236. X                }
  237. X        }
  238. X        /****************************/
  239. X        /*parent waits for interrupt*/
  240. X        /****************************/
  241. X        (void)signal(SIGHUP,die);
  242. X        (void)signal(SIGINT,die);
  243. X        (void)signal(SIGQUIT,die);
  244. X        while(TRUE)
  245. X             ;
  246. X}
  247. X
  248. X
  249. X/**********************************************************************/
  250. X/**FUNCTION:  clean_die()                                            **/
  251. X/**                                                                  **/
  252. X/**DESCRIPTION:  This function calls cleanup (ends curses) and exits.**/
  253. X/** It only is called by the children.                               **/
  254. X/**                                                                  **/
  255. X/**GLOBAL VARIABLES:  none              @                            **/
  256. X/**                                                                  **/
  257. X/**GLOBAL CONSTANTS:  none                                           **/
  258. X/**                                                                  **/
  259. X/**CALLS:  cleanup()                                                 **/
  260. X/**                                                                  **/
  261. X/**RETURNS: none                                                     **/
  262. X/**********************************************************************/ 
  263. Xvoid clean_die()
  264. X{
  265. X     cleanup();
  266. X     exit(0);
  267. X}
  268. X
  269. X
  270. X/**********************************************************************/
  271. X/**FUNCTION:  die()                                                  **/
  272. X/**                                                                  **/
  273. X/**DESCRIPTION:  This function is called by the parent and sends its **/
  274. X/** children a signal through killit and then exits.                 **/
  275. X/**                                                                  **/
  276. X/**GLOBAL VARIABLES:  semid, pid_array                               **/
  277. X/**                                                                  **/
  278. X/**GLOBAL CONSTANTS:  none                                           **/
  279. X/**                                                                  **/
  280. X/**CALLS:  killit()                                                  **/
  281. X/**                                                                  **/
  282. X/**RETURNS: none                                                     **/
  283. X/**********************************************************************/ 
  284. Xvoid die()
  285. X{
  286. X        killit(semid,pid_array);
  287. X        exit(0);
  288. X}
  289. X
  290. X
  291. X/**********************************************************************/
  292. X/**FUNCTION:  sleeper()                                              **/
  293. X/**                                                                  **/
  294. X/**DESCRIPTION:  This function randomly sleeps from 0 to             **/
  295. X/** (SLEEP_TIME-1) seconds.                                          **/
  296. X/**                                                                  **/
  297. X/**GLOBAL VARIABLES:  none                                           **/
  298. X/**                                                                  **/
  299. X/**GLOBAL CONSTANTS:  SLEEP_TIME                                     **/
  300. X/**                                                                  **/
  301. X/**CALLS:  none                                                      **/
  302. X/**                                                                  **/
  303. X/**RETURNS: none                                                     **/
  304. X/**********************************************************************/ 
  305. Xvoid sleeper()
  306. X{
  307. X        (void)sleep(rand() % SLEEP_TIME);
  308. X}
  309. X
  310. X
  311. X/**********************************************************************/
  312. X/**FUNCTION:  hungry()                                               **/
  313. X/**                                                                  **/
  314. X/**DESCRIPTION:   This function is representative of a philosopher   **/
  315. X/** being hungry.                                                    **/
  316. X/**                                                                  **/
  317. X/**GLOBAL VARIABLES:  none                                           **/
  318. X/**                                                                  **/
  319. X/**GLOBAL CONSTANTS:  HUNGRY                                         **/
  320. X/**                                                                  **/
  321. X/**CALLS:  printit()                                                 **/
  322. X/**                                                                  **/
  323. X/**RETURNS: none                                                     **/
  324. X/**********************************************************************/ 
  325. Xvoid hungry(p_num)
  326. X        int p_num;
  327. X{
  328. X        printit(p_num,HUNGRY);
  329. X}
  330. X
  331. X
  332. X/**********************************************************************/
  333. X/**FUNCTION:   thinking()                                            **/ 
  334. X/**                                                                  **/
  335. X/**DESCRIPTION:   This function is representative of a philosopher   **/
  336. X/** thinking for a random amount of time.                            **/
  337. X/**                                                                  **/
  338. X/**GLOBAL VARIABLES:  none                                           **/
  339. X/**                                                                  **/
  340. X/**GLOBAL CONSTANTS:  THINKING                                       **/
  341. X/**                                                                  **/
  342. X/**CALLS:  printit(), sleeper(),                                     **/
  343. X/**                                                                  **/
  344. X/**RETURNS: none                                                     **/
  345. X/**********************************************************************/ 
  346. Xvoid thinking(p_num)
  347. X        int p_num;
  348. X{
  349. X        printit(p_num,THINKING);
  350. X        sleeper();
  351. X}
  352. X
  353. X
  354. X/**********************************************************************/
  355. X/**FUNCTION:  eating()                                               **/ 
  356. X/**                                                                  **/
  357. X/**DESCRIPTION:   This function is representative of a philosopher   **/
  358. X/** eating for a random amount of time.                              **/
  359. X/**                                                                  **/
  360. X/**GLOBAL VARIABLES:  none                                           **/
  361. X/**                                                                  **/
  362. X/**GLOBAL CONSTANTS:  NUM_CHILDREN, EATING, HAS_ONE                  **/
  363. X/**                                                                  **/
  364. X/**CALLS:  printit(), P_semaphore(), V_semaphore(), sleeper(),       **/
  365. X/**                                                                  **/
  366. X/**RETURNS: none                                                     **/
  367. X/**********************************************************************/ 
  368. Xvoid eating(p_num)
  369. X        int p_num;
  370. X{
  371. X        int n = NUM_CHILDREN;
  372. X
  373. X        if (!(p_num % 2))
  374. X
  375. X        /************************************************/
  376. X        /*even philosopher--choose right chopstick first*/
  377. X        /* to prevent deadlock                          */
  378. X        /************************************************/
  379. X
  380. X        {
  381. X
  382. X        /******************************/
  383. X        /*P(right chopstick) operation*/
  384. X        /******************************/
  385. X
  386. X                if (!P_semaphore(p_num-1,TRUE))
  387. X                {
  388. X                     exit(0);
  389. X                }
  390. X                printit(p_num,HAS_ONE);
  391. X
  392. X        /*****************************/
  393. X        /*P(left chopstick) operation*/
  394. X        /*****************************/
  395. X
  396. X                if (!P_semaphore(p_num%n,TRUE))
  397. X                {
  398. X                     (void)V_semaphore(p_num-1);
  399. X                     exit(0);
  400. X                }
  401. X        
  402. X        /***************************************/
  403. X        /*philosopher's critical section begins*/
  404. X        /***************************************/
  405. X
  406. X                printit(p_num,EATING);
  407. X                sleeper();
  408. X
  409. X        /*************************************/
  410. X        /*Philosopher's critical section ends*/
  411. X        /*************************************/
  412. X
  413. X
  414. X        /******************************/
  415. X        /*V(right chopstick) operation*/
  416. X        /******************************/
  417. X
  418. X                if(!V_semaphore(p_num-1))
  419. X                {
  420. X                     (void)kill(getppid(),SIGHUP);
  421. X                     exit(0);
  422. X                }
  423. X
  424. X        /*****************************/
  425. X        /*V(left chopstick operation)*/
  426. X        /*****************************/
  427. X
  428. X                if(!V_semaphore(p_num%n))
  429. X                {
  430. X                     (void)kill(getppid(),SIGHUP);
  431. X                     exit(0);
  432. X                }
  433. X        }
  434. X        else
  435. X
  436. X        /**********************************************/
  437. X        /*odd philosopher--choose left chopstick first*/
  438. X        /* to prevent deadlock                        */
  439. X        /**********************************************/
  440. X
  441. X        {
  442. X
  443. X        /*****************************/
  444. X        /*P(left chopstick operation)*/
  445. X        /*****************************/
  446. X
  447. X                if (!P_semaphore(p_num%n,TRUE))
  448. X                {
  449. X                     exit(0);
  450. X                }
  451. X                printit(p_num,HAS_ONE);
  452. X
  453. X        /*****************************/
  454. X        /*P(right chopstick operation*/
  455. X        /*****************************/
  456. X
  457. X                if (!P_semaphore(p_num-1,TRUE))
  458. X                {
  459. X                     (void)V_semaphore(p_num%n);
  460. X                     exit(0);
  461. X                }
  462. X
  463. X        /***************************************/
  464. X        /*philosopher's critical section begins*/
  465. X        /***************************************/
  466. X
  467. X                printit(p_num,EATING);
  468. X                sleeper();
  469. X
  470. X        /*************************************/
  471. X        /*philosopher's critical section ends*/
  472. X        /*************************************/
  473. X
  474. X
  475. X        /*****************************/
  476. X        /*V(left chopstick) operation*/
  477. X        /*****************************/
  478. X
  479. X                if(!V_semaphore(p_num%n))
  480. X                {
  481. X                     (void)kill(getppid(),SIGHUP);
  482. X                     exit(0);
  483. X                }
  484. X
  485. X        /*****************************/
  486. X        /*V(right chopstick) operation*/
  487. X        /*****************************/
  488. X
  489. X                if(!V_semaphore(p_num-1))
  490. X                {
  491. X                     (void)kill(getppid(),SIGHUP);
  492. X                     exit(0);
  493. X                }
  494. X        }
  495. X}
  496. X
  497. X
  498. X/**********************************************************************/
  499. X/**FUNCTION:   killit()                                              **/ 
  500. X/**                                                                  **/
  501. X/**DESCRIPTION:   This function is used by the parent to kill its    **/
  502. X/** children and remove the semaphore set.                           **/
  503. X/**                                                                  **/
  504. X/**GLOBAL VARIABLES:  none                                           **/
  505. X/**                                                                  **/
  506. X/**GLOBAL CONSTANTS:  NUM_CHILDREN                                   **/
  507. X/**                                                                  **/
  508. X/**CALLS:  none                                                      **/
  509. X/**                                                                  **/
  510. X/**RETURNS: none                                                     **/
  511. X/**********************************************************************/ 
  512. Xvoid killit(semid,array_ptr)
  513. X        int semid, *array_ptr;
  514. X{
  515. X        int i;
  516. X
  517. X        for (i=0; i<NUM_CHILDREN; i++)
  518. X                (void)kill(array_ptr[i],SIGHUP);
  519. X        (void)semctl(semid,0,IPC_RMID,0);
  520. X}
  521. X
  522. X
  523. X/**********************************************************************/
  524. X/**FUNCTION:   cleanup()                                             **/ 
  525. X/**                                                                  **/
  526. X/**DESCRIPTION:   This function cleans up curses for the children.   **/
  527. X/**                                                                  **/
  528. X/**GLOBAL VARIABLES:  none                                           **/
  529. X/**                                                                  **/
  530. X/**GLOBAL CONSTANTS:  none                                           **/
  531. X/**                                                                  **/
  532. X/**CALLS:  none                                                      **/
  533. X/**                                                                  **/
  534. X/**RETURNS: none                                                     **/
  535. X/**********************************************************************/ 
  536. Xvoid cleanup()
  537. X{
  538. X           endwin();
  539. X}
  540. X
  541. X
  542. X/**********************************************************************/
  543. X/**FUNCTION:   printit()                                             **/ 
  544. X/**                                                                  **/
  545. X/**DESCRIPTION:  This function print the childrens' actions.         **/
  546. X/**                                                                  **/
  547. X/**GLOBAL VARIABLES:  none                                           **/
  548. X/**                                                                  **/
  549. X/**GLOBAL CONSTANTS:  EATING, THINKING, HAS_ONE, HUNGRY              **/
  550. X/**                                                                  **/
  551. X/**CALLS:  none                                                      **/
  552. X/**                                                                  **/
  553. X/**RETURNS: none                                                     **/
  554. X/**********************************************************************/ 
  555. Xvoid printit(p_num,action)
  556. X        int p_num, action;
  557. X{
  558. X        int x, y;
  559. X        char string[128];
  560. X
  561. X        switch(action)
  562. X        {
  563. X                 case EATING : (void)sprintf(string,"Philosopher %d is eating...",p_num);
  564. X                          break;
  565. X                 case THINKING : (void)sprintf(string,"Philosopher %d is thinking...",p_num);
  566. X                          break;
  567. X                 case HAS_ONE : if(!(p_num % 2))
  568. X                               (void)sprintf(string,"Philosopher %d is hungry & has right chopstick...",p_num);
  569. X                          else
  570. X                               (void)sprintf(string,"Philosopher %d is hungry & has left chopstick...",p_num);
  571. X                          break;
  572. X                 case HUNGRY : (void)sprintf(string,"Philosopher %d is hungry...",p_num);
  573. X                          break;
  574. X                default : return;
  575. X        }
  576. X        switch(p_num)
  577. X        {
  578. X                 case 1:  y = 2;
  579. X              x = 6;
  580. X                          break;
  581. X                 case 2 : y = 3;
  582. X                          x = COLS - strlen(string) - 6;
  583. X                          break;
  584. X                 case 3 : y = LINES/2;
  585. X                          x = COLS - strlen(string) - 2;
  586. X                          break;
  587. X                 case 4 : y = LINES - 2;
  588. X                          x = COLS/2 - strlen(string)/2;
  589. X                          break;
  590. X                 case 5 : y = LINES/2 - 1;
  591. X                          x = 2;
  592. X                          break;
  593. X                default : return;
  594. X        }
  595. X        move(0,0);
  596. X        refresh();
  597. X        move(y,0);
  598. X        clrtoeol();
  599. X        mvaddstr(y,x,string);
  600. X        refresh();
  601. X}
  602. X
  603. X
  604. X/*************************************************************************/
  605. X/**FUNCTION: V_semaphore()                                              **/ 
  606. X/**                                                                     **/
  607. X/**DESCRIPTION:   This function releases the named semaphore in the set.**/
  608. X/**   It is called after a process leaves its critical section which is **/
  609. X/**   associated with 'sem_num'.                                        **/
  610. X/**                                                                     **/
  611. X/**GLOBAL VARIABLES:  semid                                             **/
  612. X/**                                                                     **/
  613. X/**GLOBAL CONSTANTS:  NUM_CHILDREN                                      **/
  614. X/**                                                                     **/
  615. X/**CALLS:  cleanup()                                                    **/
  616. X/**                                                                     **/
  617. X/**RETURNS:  TRUE on success, otherwise FALSE.                          **/
  618. X/*************************************************************************/ 
  619. Xbool V_semaphore(sem_num)
  620. X     int sem_num;
  621. X{
  622. X     int retrn;
  623. X     struct sembuf sembuf[NUM_CHILDREN], *sops;
  624. X     unsigned nsops = 1;
  625. X
  626. X     sops = sembuf;
  627. X     sops->sem_num = sem_num;
  628. X     sops->sem_op = 1;
  629. X     sops->sem_flg = 0;
  630. X     if((retrn = semop(semid, sops, nsops)) == -1)
  631. X     {
  632. X         cleanup();
  633. X         perror("error with semop(semid,sops,nsops) in V_semaphore()");
  634. X         return(FALSE);
  635. X     }
  636. X     return(TRUE);
  637. X}
  638. X
  639. X
  640. X/*************************************************************************/
  641. X/**FUNCTION: P_semaphore()                                              **/ 
  642. X/**                                                                     **/
  643. X/**DESCRIPTION:   This function waits on the named semaphore in the set.**/
  644. X/**   It either blocks or not depending on 'block'.  It is called       **/
  645. X/**   before a process enters its critical section which is associated  **/
  646. X/**   with 'sem_num'.                                                   **/
  647. X/**                                                                     **/
  648. X/**GLOBAL VARIABLES:  semid                                             **/
  649. X/**                                                                     **/
  650. X/**GLOBAL CONSTANTS:  NUM_CHILDREN                                      **/
  651. X/**                                                                     **/
  652. X/**CALLS:   cleanup()                                                   **/
  653. X/**                                                                     **/
  654. X/**RETURNS:  TRUE on success, FALSE otherwise--if block; TRUE if got    **/
  655. X/** semaphore, FALSE if not or error--if !block.                        **/
  656. X/*************************************************************************/ 
  657. Xbool P_semaphore(sem_num,block)
  658. X     int sem_num;
  659. X     bool block;
  660. X{
  661. X     int retrn, flags = IPC_NOWAIT;
  662. X     struct sembuf sembuf[NUM_CHILDREN], *sops;
  663. X     unsigned nsops = 1;
  664. X     extern int errno;
  665. X
  666. X     sops = sembuf;
  667. X     if(block)
  668. X          flags = 0;
  669. X     else
  670. X          errno = 0;
  671. X     sops->sem_num = sem_num;
  672. X     sops->sem_op = -1;
  673. X     sops->sem_flg = flags;
  674. X     if((retrn = semop(semid, sops, nsops)) == -1)
  675. X     {
  676. X         if(errno == EAGAIN)  /* !block && didn't get semaphore */
  677. X              return(FALSE);
  678. X         cleanup();
  679. X         perror("error with semop(semid,sops,nsops) in P_semaphore()");
  680. X         return(FALSE);
  681. X     }
  682. X     return(TRUE);
  683. X}
  684. X
  685. X
  686. ________This_Is_The_END________
  687. if test `wc -l < phil.c` -ne 645; then
  688.   echo 'shar: phil.c was damaged during transit (should have been 645 bytes)'
  689. fi
  690. fi                ; : end of overwriting check
  691. exit 0
  692.  
  693.  
  694.