home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume2 / phil < prev    next >
Internet Message Format  |  1991-08-07  |  30KB

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