]> git.pond.sub.org Git - empserver/blob - src/lib/lwp/sem.c
5ae076d32ab4aceb73eb9a22faa4e807e9015b84
[empserver] / src / lib / lwp / sem.c
1 /*
2  * lwpSem.c -- lwpSemaphore manipulation.
3  * Copyright (C) 1991-3 Stephen Crane.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  * 
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  * 
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the Free
17  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  * author: Stephen Crane, (jsc@doc.ic.ac.uk), Department of Computing,
20  * Imperial College of Science, Technology and Medicine, 180 Queen's
21  * Gate, London SW7 2BZ, England.
22  */
23
24 #include <config.h>
25
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "lwp.h"
30 #include "lwpint.h"
31
32 /*
33  * create a lwpSemaphore.
34  */
35 struct lwpSem *
36 lwpCreateSem(char *name, int count)
37 {
38     struct lwpSem *new;
39
40     if (!(new = malloc(sizeof(struct lwpSem))))
41         return 0;
42     new->name = strdup(name);
43     new->count = count;
44     new->q.head = new->q.tail = 0;
45     return new;
46 }
47
48 /*
49  * signal a lwpSemaphore.  We only yield here if
50  * the blocked process has a higher priority than ours'.
51  */
52 void
53 lwpSignal(struct lwpSem *s)
54 {
55     lwpStatus(LwpCurrent, "done with semaphore %s", s->name);
56     if (s->count++ < 0) {
57         struct lwpProc *p = lwpGetFirst(&s->q);
58         lwpStatus(LwpCurrent, "activating first waiter");
59         lwpReady(p);
60         if (LwpCurrent->pri < p->pri) {
61             lwpStatus(p, "priority is higher");
62             lwpYield();
63         }
64     }
65 }
66
67 /*
68  * wait on a lwpSemaphore
69  */
70 void
71 lwpWait(struct lwpSem *s)
72 {
73     lwpStatus(LwpCurrent, "checking semaphore %s", s->name);
74     if (--s->count < 0) {
75         lwpStatus(LwpCurrent, "blocking");
76         lwpAddTail(&s->q, LwpCurrent);
77         lwpReschedule();
78     }
79 }