IBNOS
semaphore.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Michael Müller
3  * Copyright (c) 2014, Sebastian Lackner
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #include <process/semaphore.h>
29 #include <process/object.h>
30 #include <memory/allocator.h>
31 #include <util/list.h>
32 #include <util/util.h>
33 
39 static void __semaphoreDestroy(struct object *obj);
40 static void __semaphoreShutdown(struct object *obj, UNUSED uint32_t mode);
41 static int32_t __semaphoreGetStatus(struct object *obj, UNUSED uint32_t mode);
42 static struct linkedList *__semaphoreWait(struct object *obj, UNUSED uint32_t mode, uint32_t *result);
43 static void __semaphoreSignal(struct object *obj, UNUSED uint32_t result);
44 
45 static const struct objectFunctions semaphoreFunctions =
46 {
47  __semaphoreDestroy,
48  NULL, /* getMinHandle */
49  __semaphoreShutdown,
50  __semaphoreGetStatus,
51  __semaphoreWait,
52  __semaphoreSignal,
53  NULL, /* write */
54  NULL, /* read */
55  NULL, /* insert */
56  NULL, /* remove */
57 };
58 
68 struct semaphore *semaphoreCreate(uint32_t value)
69 {
70  struct semaphore *s;
71 
72  /* allocate some new memory */
73  if (!(s = heapAlloc(sizeof(*s))))
74  return NULL;
75 
76  /* initialize general object info */
77  __objectInit(&s->obj, &semaphoreFunctions);
78  ll_init(&s->waiters);
79  s->value = value;
80 
81  return s;
82 }
83 
89 static void __semaphoreDestroy(struct object *obj)
90 {
91  struct semaphore *s = objectContainer(obj, struct semaphore, &semaphoreFunctions);
92 
93  /* release other threads if the user destroys the object before they return */
94  queueWakeup(&s->waiters, true, -1);
95  assert(ll_empty(&s->waiters));
96 
97  /* release semaphore memory */
98  s->obj.functions = NULL;
99  heapFree(s);
100 }
101 
111 static void __semaphoreShutdown(struct object *obj, UNUSED uint32_t mode)
112 {
113  struct semaphore *s = objectContainer(obj, struct semaphore, &semaphoreFunctions);
114  queueWakeup(&s->waiters, true, -1);
115 }
116 
128 static int32_t __semaphoreGetStatus(struct object *obj, UNUSED uint32_t mode)
129 {
130  struct semaphore *s = objectContainer(obj, struct semaphore, &semaphoreFunctions);
131  return s->value;
132 }
133 
149 static struct linkedList *__semaphoreWait(struct object *obj, UNUSED uint32_t mode, uint32_t *result)
150 {
151  struct semaphore *s = objectContainer(obj, struct semaphore, &semaphoreFunctions);
152  if (s->value == 0) return &s->waiters;
153 
154  *result = --s->value;
155  return NULL;
156 }
157 
168 static void __semaphoreSignal(struct object *obj, UNUSED uint32_t result)
169 {
170  struct semaphore *s = objectContainer(obj, struct semaphore, &semaphoreFunctions);
171  if (ll_empty(&s->waiters))
172  s->value++;
173  else
174  {
175  assert(s->value == 0);
176  queueWakeup(&s->waiters, false, 0);
177  }
178 }
179 
const struct objectFunctions * functions
Definition: object.h:72
void * heapAlloc(uint32_t length)
Allocates a block of kernel memory.
Definition: allocator.c:363
#define assert(ex)
Definition: util.h:61
#define UNUSED
Definition: util.h:39
struct linkedList waiters
Definition: semaphore.h:44
void heapFree(void *addr)
Deallocates a block of kernel memory.
Definition: allocator.c:385
struct object obj
Definition: thread.h:49
struct semaphore * semaphoreCreate(uint32_t value)
Creates a new kernel semaphore object.
Definition: semaphore.c:68
struct object obj
Definition: semaphore.h:43
#define objectContainer(p, type, functions)
Definition: object.h:66
uint32_t value
Definition: semaphore.h:47
uint32_t value
Definition: paging.h:55
char mode[8]
Definition: filesystem.h:65