sem.c
Go to the documentation of this file.00001
00041 #include "sem.h"
00042 #include <kern/proc.h>
00043 #include <kern/proc_p.h>
00044 #include <kern/signal.h>
00045 #include <cfg/debug.h>
00046
00047 INLINE void sem_verify(struct Semaphore *s)
00048 {
00049 (void)s;
00050 ASSERT(s);
00051 LIST_ASSERT_VALID(&s->wait_queue);
00052 ASSERT(s->nest_count >= 0);
00053 ASSERT(s->nest_count < 128);
00054 }
00055
00056
00060 void sem_init(struct Semaphore *s)
00061 {
00062 LIST_INIT(&s->wait_queue);
00063 s->owner = NULL;
00064 s->nest_count = 0;
00065 }
00066
00067
00079 bool sem_attempt(struct Semaphore *s)
00080 {
00081 bool result = false;
00082
00083 proc_forbid();
00084 sem_verify(s);
00085 if ((!s->owner) || (s->owner == CurrentProcess))
00086 {
00087 s->owner = CurrentProcess;
00088 s->nest_count++;
00089 result = true;
00090 }
00091 proc_permit();
00092
00093 return result;
00094 }
00095
00096
00114 void sem_obtain(struct Semaphore *s)
00115 {
00116 proc_forbid();
00117 sem_verify(s);
00118
00119
00120 if (UNLIKELY(s->owner && (s->owner != CurrentProcess)))
00121 {
00122
00123 ADDTAIL(&s->wait_queue, (Node *)CurrentProcess);
00124
00125
00126
00127
00128
00129
00130 proc_permit();
00131 proc_schedule();
00132 }
00133 else
00134 {
00135 ASSERT(LIST_EMPTY(&s->wait_queue));
00136
00137
00138 s->owner = CurrentProcess;
00139 s->nest_count++;
00140 proc_permit();
00141 }
00142 }
00143
00144
00158 void sem_release(struct Semaphore *s)
00159 {
00160 proc_forbid();
00161 sem_verify(s);
00162
00163 ASSERT(s->owner == CurrentProcess);
00164
00165
00166
00167
00168
00169 if (--s->nest_count == 0)
00170 {
00171 Process *proc;
00172
00173
00174 s->owner = NULL;
00175
00176
00177 if (UNLIKELY((proc = (Process *)list_remHead(&s->wait_queue))))
00178 {
00179 s->nest_count = 1;
00180 s->owner = proc;
00181 SCHED_ENQUEUE(proc);
00182 }
00183 }
00184
00185 proc_permit();
00186 }