head 1.24; access; symbols PTH_2_0_7:1.23 PTH_2_0_6:1.22 PTH_2_0_5:1.22 PTH_2_0_4:1.22 PTH_2_0_3:1.21 PTH_2_0_2:1.21 PTH_2_0_1:1.21 PTH_2_0_0:1.20 PTH_2_0b2:1.19 PTH_2_0b1:1.19 PTH_2_0b0:1.19 PTH_1_4:1.18.0.2 PTH_1_4_1:1.18 PTH_1_4_0:1.17 PTH_1_3_7:1.16 PTH_1_4a3:1.16 PTH_1_3_6:1.16 PTH_1_4a2:1.16 PTH_1_3_5:1.16 PTH_1_4a1:1.16 PTH_1_3_4:1.16 PTH_1_3:1.16.0.2 PTH_1_3_3:1.16 PTH_1_3_2:1.15 PTH_1_3_1:1.15 PTH_1_3_0:1.15 PTH_1_3b3:1.15 PTH_1_2_3:1.8.2.2 PTH_1_3b2:1.15 PTH_1_3b1:1.15 PTH_1_3a5:1.15 PTH_1_3a4:1.12 PTH_1_3a3:1.12 PTH_1_2_2:1.8.2.1 PTH_1_3a2:1.12 PTH_1_2_1:1.8.2.1 PTH_1_3a1:1.10 PTH_1_2:1.8.0.2 PTH_1_2_0:1.8 PTH_1_2b8:1.7 PTH_1_2b7:1.7 PTH_1_1_6:1.6 PTH_1_2b6:1.7 PTH_1_2b5:1.7 PTH_1_2b4:1.7 PTH_1_2b3:1.7 PTH_1_2b2:1.6 PTH_1_2b1:1.6 PTH_1_1_5:1.6 PTH_1_1:1.6.0.2 PTH_1_1_4:1.6 PTH_1_1_3:1.6; locks; strict; comment @ * @; 1.24 date 2007.01.01.18.23.53; author rse; state Exp; branches; next 1.23; commitid 9DhdiirNzQPBIP0s; 1.23 date 2006.06.08.17.54.54; author rse; state Exp; branches; next 1.22; commitid x8N3mLVdQgkbdeAr; 1.22 date 2004.12.31.19.34.45; author rse; state Exp; branches; next 1.21; 1.21 date 2004.07.13.10.50.49; author rse; state Exp; branches; next 1.20; 1.20 date 2003.01.01.15.49.12; author rse; state Exp; branches; next 1.19; 1.19 date 2002.10.15.20.34.23; author rse; state Exp; branches; next 1.18; 1.18 date 2002.01.27.11.03.41; author rse; state Exp; branches; next 1.17; 1.17 date 2001.03.24.14.51.05; author rse; state Exp; branches; next 1.16; 1.16 date 2000.03.09.12.11.51; author rse; state Exp; branches; next 1.15; 1.15 date 2000.01.09.16.32.45; author rse; state Exp; branches; next 1.14; 1.14 date 2000.01.09.16.31.45; author rse; state Exp; branches; next 1.13; 1.13 date 2000.01.09.16.06.13; author rse; state Exp; branches; next 1.12; 1.12 date 99.12.30.21.59.02; author rse; state Exp; branches; next 1.11; 1.11 date 99.11.09.08.11.32; author rse; state Exp; branches; next 1.10; 1.10 date 99.11.01.19.03.49; author rse; state Exp; branches; next 1.9; 1.9 date 99.11.01.10.27.21; author rse; state Exp; branches; next 1.8; 1.8 date 99.10.31.11.46.14; author rse; state Exp; branches 1.8.2.1; next 1.7; 1.7 date 99.09.17.08.01.56; author rse; state Exp; branches; next 1.6; 1.6 date 99.08.27.08.56.22; author rse; state Exp; branches; next 1.5; 1.5 date 99.08.27.08.50.44; author rse; state Exp; branches; next 1.4; 1.4 date 99.08.27.06.18.06; author rse; state Exp; branches; next 1.3; 1.3 date 99.08.27.06.15.15; author rse; state Exp; branches; next 1.2; 1.2 date 99.08.26.17.30.03; author rse; state Exp; branches; next 1.1; 1.1 date 99.08.26.16.29.14; author rse; state Exp; branches; next ; 1.8.2.1 date 99.11.01.10.25.03; author rse; state Exp; branches; next 1.8.2.2; 1.8.2.2 date 2000.02.04.22.07.18; author rse; state Exp; branches; next ; desc @@ 1.24 log @Adjusted all copyright messages for new year 2007. @ text @/* ** GNU Pth - The GNU Portable Threads ** Copyright (c) 1999-2007 Ralf S. Engelschall ** ** This file is part of GNU Pth, a non-preemptive thread scheduling ** library which can be found at http://www.gnu.org/software/pth/. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public ** License as published by the Free Software Foundation; either ** version 2.1 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with this library; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ** USA, or contact Ralf S. Engelschall . ** ** test_philo.c: Pth test application showing the 5 philosopher problem */ /* ``It's not enough to be a great programmer; you have to find a great problem.'' -- Charles Simonyi */ /* * Reference: E.W. Dijkstra, * ``Hierarchical Ordering of Sequential Processes'', * Acta Informatica 1, 1971, 115-138. */ #include #include #include #include #include #include "pth.h" #include "test_common.h" #define PHILNUM 5 typedef enum { thinking, hungry, eating } philstat; static const char *philstatstr[3] = { "thinking", "hungry ", "EATING " }; typedef struct tablestruct { pth_t tid[PHILNUM]; int self[PHILNUM]; pth_mutex_t mutex; pth_cond_t condition[PHILNUM]; philstat status[PHILNUM]; } table; static table *tab; static void printstate(void) { int i; for (i = 0; i < PHILNUM; i++) printf("| %s ", philstatstr[(int)(tab->status)[i]]); printf("|\n"); return; } static int test(unsigned int i) { if ( ((tab->status)[i] == hungry) && ((tab->status)[(i + 1) % PHILNUM] != eating) && ((tab->status)[(i - 1 + PHILNUM) % PHILNUM] != eating)) { (tab->status)[i] = eating; pth_cond_notify(&((tab->condition)[i]), FALSE); return TRUE; } return FALSE; } static void pickup(unsigned int k) { pth_mutex_acquire(&(tab->mutex), FALSE, NULL); (tab->status)[k] = hungry; printstate(); if (!test(k)) pth_cond_await(&((tab->condition)[k]), &(tab->mutex), NULL); printstate(); pth_mutex_release(&(tab->mutex)); return; } static void putdown(unsigned int k) { pth_mutex_acquire(&(tab->mutex), FALSE, NULL); (tab->status)[k] = thinking; printstate(); test((k + 1) % PHILNUM); test((k - 1 + PHILNUM) % PHILNUM); pth_mutex_release(&(tab->mutex)); return; } static void *philosopher(void *_who) { unsigned int *who = (unsigned int *)_who; /* For simplicity, all philosophers eat for the same amount of time and think for a time that is simply related to their position at the table. The parameter who identifies the philosopher: 0,1,2,.. */ for (;;) { pth_sleep((*who) + 1); pickup((*who)); pth_sleep(1); putdown((*who)); } return NULL; } int main(int argc, char *argv[]) { int i; sigset_t ss; int sig; pth_event_t ev; /* initialize Pth library */ pth_init(); /* display test program header */ printf("This is TEST_PHILO, a Pth test showing the Five Dining Philosophers\n"); printf("\n"); printf("This is a demonstration showing the famous concurrency problem of the\n"); printf("Five Dining Philosophers as analysed 1965 by E.W.Dijkstra:\n"); printf("\n"); printf("Five philosophers are sitting around a round table, each with a bowl of\n"); printf("Chinese food in front of him. Between periods of talking they may start\n"); printf("eating whenever they want to, with their bowls being filled frequently.\n"); printf("But there are only five chopsticks available, one each to the left of\n"); printf("each bowl - and for eating Chinese food one needs two chopsticks. When\n"); printf("a philosopher wants to start eating, he must pick up the chopstick to\n"); printf("the left of his bowl and the chopstick to the right of his bowl. He\n"); printf("may find, however, that either one (or even both) of the chopsticks is\n"); printf("unavailable as it is being used by another philosopher sitting on his\n"); printf("right or left, so he has to wait.\n"); printf("\n"); printf("This situation shows classical contention under concurrency (the\n"); printf("philosophers want to grab the chopsticks) and the possibility of a\n"); printf("deadlock (all philosophers wait that the chopstick to their left becomes\n"); printf("available).\n"); printf("\n"); printf("The demonstration runs max. 60 seconds. To stop before, press CTRL-C.\n"); printf("\n"); printf("+----P1----+----P2----+----P3----+----P4----+----P5----+\n"); /* initialize the control table */ tab = (table *)malloc(sizeof(table)); if (!pth_mutex_init(&(tab->mutex))) { perror("pth_mutex_init"); exit(1); } for (i = 0; i < PHILNUM; i++) { (tab->self)[i] = i; (tab->status)[i] = thinking; if (!pth_cond_init(&((tab->condition)[i]))) { perror("pth_cond_init"); exit(1); } } /* spawn the philosopher threads */ for (i = 0; i < PHILNUM; i++) { if (((tab->tid)[i] = pth_spawn(PTH_ATTR_DEFAULT, philosopher, &((tab->self)[i]))) == NULL) { perror("pth_spawn"); exit(1); } } /* wait until 60 seconds have elapsed or CTRL-C was pressed */ sigemptyset(&ss); sigaddset(&ss, SIGINT); ev = pth_event(PTH_EVENT_TIME, pth_timeout(60,0)); pth_sigwait_ev(&ss, &sig, ev); pth_event_free(ev, PTH_FREE_ALL); /* cancel and join the philosopher threads */ for (i = 0; i < PHILNUM; i++) pth_cancel((tab->tid)[i]); while (pth_join(NULL, NULL)); /* finish display */ printf("+----------+----------+----------+----------+----------+\n"); /* free the control table */ free(tab); /* shutdown Pth library */ pth_kill(); return 0; } @ 1.23 log @Adjusted all copyright messages for new year 2006 @ text @d3 1 a3 1 ** Copyright (c) 1999-2006 Ralf S. Engelschall @ 1.22 log @Adjusted all copyright messages for new year 2005. @ text @d3 1 a3 1 ** Copyright (c) 1999-2005 Ralf S. Engelschall @ 1.21 log @Adjusted all copyright messages for new year 2004. @ text @d3 1 a3 1 ** Copyright (c) 1999-2004 Ralf S. Engelschall @ 1.20 log @Adjusted all copyright messages for new year 2003. @ text @d3 1 a3 1 ** Copyright (c) 1999-2003 Ralf S. Engelschall @ 1.19 log @remove trailing whitespaces @ text @d3 1 a3 1 ** Copyright (c) 1999-2002 Ralf S. Engelschall @ 1.18 log @bump copyright year @ text @d184 1 a184 1 pth_spawn(PTH_ATTR_DEFAULT, philosopher, @ 1.17 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2001 Ralf S. Engelschall @ 1.16 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2000 Ralf S. Engelschall @ 1.15 log @*** empty log message *** @ text @d53 1 a53 1 static char *philstatstr[3] = { d79 1 a79 1 static int test(int i) d91 1 a91 1 static void pickup(int k) d103 1 a103 1 static void putdown(int k) d116 1 a116 1 int *who = (int *)_who; @ 1.14 log @*** empty log message *** @ text @a41 1 #include "dmalloc.h" @ 1.13 log @*** empty log message *** @ text @d42 1 d184 3 a186 2 if (((tab->tid)[i] = pth_spawn(PTH_ATTR_DEFAULT, philosopher, &((tab->self)[i]))) == NULL) { d199 1 a199 1 /* cancel the philosopher threads */ d202 1 d206 3 a208 1 fflush(stdout); @ 1.12 log @*** empty log message *** @ text @d30 3 a32 2 * E.W. Dijkstra, ``Hierarchical Ordering of Sequential Processes.'', * Acta Informatica 1, 1971, 115-138. @ 1.11 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999 Ralf S. Engelschall @ 1.10 log @*** empty log message *** @ text @d25 1 a25 1 /* ``It's not enough to be a great programmer; d31 1 a31 1 * Acta Informatica 1, 1971, 115-138. d182 1 a182 1 if (((tab->tid)[i] = pth_spawn(PTH_ATTR_DEFAULT, @ 1.9 log @*** empty log message *** @ text @d25 3 @ 1.8 log @*** empty log message *** @ text @d2 1 a2 2 ** test_philo.c -- Pth test application showing the 5 philosopher problem ** d22 2 @ 1.8.2.1 log @*** empty log message *** @ text @d2 2 a3 1 ** GNU Pth - The GNU Portable Threads a22 2 ** ** test_philo.c: Pth test application showing the 5 philosopher problem @ 1.8.2.2 log @*** empty log message *** @ text @d193 1 a193 1 /* cancel and join the philosopher threads */ a195 1 while (pth_join(NULL, NULL)); d199 1 a199 3 /* free the control table */ free(tab); @ 1.7 log @*** empty log message *** @ text @d12 1 a12 1 ** version 2 of the License, or (at your option) any later version. @ 1.6 log @*** empty log message *** @ text @d10 1 a10 1 ** modify it under the terms of the GNU Library General Public d17 1 a17 1 ** Library General Public License for more details. d19 1 a19 1 ** You should have received a copy of the GNU Library General Public @ 1.5 log @*** empty log message *** @ text @d132 1 d135 1 d185 1 d192 1 d196 1 d199 2 @ 1.4 log @*** empty log message *** @ text @d25 5 d33 1 d51 1 a51 1 "eating " d55 2 a56 2 pth_t t[PHILNUM]; int self[PHILNUM]; d58 2 a59 2 pth_cond_t condition[PHILNUM]; philstat status[PHILNUM]; a65 1 static char stat[] = "THE"; d128 3 d136 20 a155 6 printf("This is an implementation of Dijkstra's classic problem of the\n"); printf("Five Dining Philosophers. There are five philosophers sitting around\n"); printf("a table. There are five forks on the table, one between each pair of\n"); printf("philosophers. A philosopher can either talk, think or eat. But no more\n"); printf("than two philosopher can eat at the same time, because every philosopher\n"); printf("needs two forks for eating.\n"); d159 1 d173 2 d176 2 a177 1 if (((tab->t)[i] = pth_spawn(PTH_ATTR_DEFAULT, philosopher, &((tab->self)[i]))) == NULL) { d183 5 a187 1 pth_sleep(10); d190 1 a190 1 pth_cancel((tab->t)[i]); d192 2 @ 1.3 log @*** empty log message *** @ text @d36 4 a39 4 typedef enum { thinking, hungry, eating d71 1 a71 1 if ( ((tab->status)[i] == hungry) d120 1 a120 1 int main(int argc, char *argv[]) @ 1.2 log @*** empty log message *** @ text @d120 1 a120 1 static void tableinit(void) d124 13 a155 2 return; } d157 4 a160 3 int main(int argc, char *argv[]) { pth_init(); d162 1 a162 10 printf("This is TEST_PHILO, a Pth test showing the Five Dining Philosophers\n"); printf("\n"); printf("This is an implementation of Dijkstra's classic problem of the\n"); printf("Five Dining Philosophers. There are five philosophers sitting around\n"); printf("a table. There are five forks on the table, one between each pair of\n"); printf("philosophers. A philosopher can either talk, think or eat. But no more\n"); printf("than two philosopher can eat at the same time, because every philosopher\n"); printf("needs two forks for eating.\n"); printf("\n"); printf("+----P1----+----P2----+----P3----+----P4----+----P5----+\n"); a163 2 tableinit(); pth_sleep(60); @ 1.1 log @*** empty log message *** @ text @d42 6 d64 2 a65 2 printf("%c", stat[(int)(tab->status)[i]]); printf("\n"); d149 2 a150 1 printf("This is TEST_PHILO, Dijkstra's Five Dining Philosophers.\n"); d152 9 @