]> git.pond.sub.org Git - empserver/blob - src/lib/lwp/sem.c
Import of Empire 4.2.12
[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 #include <stdlib.h>
24 #include <string.h>
25
26 #include "lwp.h"
27 #include "lwpint.h"
28 #include "prototypes.h"
29
30 #if defined(_EMPTH_LWP)
31
32 /* for systems without strdup  */
33 #ifdef NOSTRDUP
34 extern char *strdup();
35 #endif /* NOSTRDUP */
36
37 /*
38  * create a lwpSemaphore.
39  */
40 struct lwpSem *lwpCreateSem(name, count)
41         char    *name;
42         int     count;
43 {
44         struct lwpSem *new;
45
46         if (!(new = (struct lwpSem *)malloc(sizeof(struct lwpSem))))
47                 return (0);
48         new->name = strdup(name);
49         new->count = count;
50         new->q.head = new->q.tail = 0;
51         return (new);
52 }
53
54 /*
55  * signal a lwpSemaphore.  We only yield here if
56  * the blocked process has a higher priority than ours'.
57  */
58 void lwpSignal(s)
59         struct lwpSem *s;
60 {
61         extern struct lwpProc *LwpCurrent;
62
63         lwpStatus(LwpCurrent, "done with semaphore %s", s->name);
64         if (s->count++ < 0) {
65                 struct lwpProc *p = lwpGetFirst(&s->q);
66                 lwpStatus(LwpCurrent, "activating first waiter");
67                 lwpReady(p);
68                 if (LwpCurrent->pri < p->pri) {
69                         lwpStatus(p, "priority is higher");
70                         lwpYield();
71                 }
72         }
73 }
74
75 /*
76  * wait on a lwpSemaphore
77  */
78 void lwpWait(s)
79         struct lwpSem *s;
80 {
81         extern struct lwpProc *LwpCurrent;
82
83         lwpStatus(LwpCurrent, "checking semaphore %s", s->name);
84         if (--s->count < 0) {
85                 lwpStatus(LwpCurrent, "blocking");
86                 lwpAddTail(&s->q, LwpCurrent);
87                 lwpReschedule();
88         }
89 }
90 #endif