]> git.pond.sub.org Git - empserver/blob - src/lib/lwp/sem.c
40c1a5595455caa35482bfb950f0641225e5c3d7
[empserver] / src / lib / lwp / sem.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1994-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *  Copyright (C) 1991-3 Stephen Crane
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  *  ---
22  *
23  *  See files README, COPYING and CREDITS in the root of the source
24  *  tree for related information and legal notices.  It is expected
25  *  that future projects/authors will amend these files as needed.
26  *
27  *  ---
28  *
29  *  lwpSem.c: lwpSemaphore manipulation
30  * 
31  *  Known contributors to this file:
32  *
33  */
34
35 #include <config.h>
36
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "lwp.h"
41 #include "lwpint.h"
42
43 /*
44  * create a lwpSemaphore.
45  */
46 struct lwpSem *
47 lwpCreateSem(char *name, int count)
48 {
49     struct lwpSem *new;
50
51     if (!(new = malloc(sizeof(struct lwpSem))))
52         return 0;
53     new->name = strdup(name);
54     new->count = count;
55     new->q.head = new->q.tail = 0;
56     return new;
57 }
58
59 /*
60  * signal a lwpSemaphore.  We only yield here if
61  * the blocked process has a higher priority than ours'.
62  */
63 void
64 lwpSignal(struct lwpSem *s)
65 {
66     lwpStatus(LwpCurrent, "done with semaphore %s", s->name);
67     if (s->count++ < 0) {
68         struct lwpProc *p = lwpGetFirst(&s->q);
69         lwpStatus(LwpCurrent, "activating first waiter");
70         lwpReady(p);
71         if (LwpCurrent->pri < p->pri) {
72             lwpStatus(p, "priority is higher");
73             lwpYield();
74         }
75     }
76 }
77
78 /*
79  * wait on a lwpSemaphore
80  */
81 void
82 lwpWait(struct lwpSem *s)
83 {
84     lwpStatus(LwpCurrent, "checking semaphore %s", s->name);
85     if (--s->count < 0) {
86         lwpStatus(LwpCurrent, "blocking");
87         lwpAddTail(&s->q, LwpCurrent);
88         lwpReschedule();
89     }
90 }