semaphore.c
Go to the documentation of this file.
1
6/*
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.0 (the "License"); you may not use this file except in
9 * compliance with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS"
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
14 * License for the specific language governing rights and limitations
15 * under the License.
16 *
17 * The Original Code is legOS code, released October 17, 1999.
18 *
19 * The Initial Developer of the Original Code is Markus L. Noga.
20 * Portions created by Markus L. Noga are Copyright (C) 1999
21 * Markus L. Noga. All Rights Reserved.
22 *
23 * Contributor(s): Markus L. Noga <markus@noga.de>
24 */
25
26#include <semaphore.h>
27
28#ifdef CONF_SEMAPHORES
29
30#include <unistd.h>
31
33//
34// Functions
35//
37
39
41wakeup_t sem_event_wait(wakeup_t data) {
42 sem_t *sem=(sem_t*) ((unsigned)data);
43
44 // we're called by the scheduler, therefore in an IRQ handler,
45 // so no worrying about IRQs.
46 //
47 if(*sem) {
48 (*sem)--;
49 return 1; // sem!=0 -> wakeup
50 }
51 return 0;
52}
53
55
63int sem_wait(sem_t * sem) {
64 // check if semaphore is available, if not, go to sleep
65
66 if(sem_trywait(sem))
67 if (wait_event(sem_event_wait,(unsigned long) ((unsigned)sem)) == 0)
68 return -1;
69
70 return 0;
71}
72
73typedef struct {
74 sem_t *sem;
75 time_t abs_timeout;
76} timeout_sem_data_t;
77
78static wakeup_t sem_event_timeout_wait(wakeup_t data) {
79 timeout_sem_data_t *tsem = (timeout_sem_data_t*) ((unsigned)data);
80
81 // we're called by the scheduler, therefore in an IRQ handler,
82 // so no worrying about IRQs.
83 //
84 if (*tsem->sem) {
85 (*tsem->sem)--;
86 return 1; // sem!=0 -> wakeup
87 }
88
89 if (tsem->abs_timeout <= get_system_up_time()) {
90 return 2; // timeout reached -> wakeup
91 }
92
93 return 0;
94}
95
96int sem_timedwait(sem_t *sem,
97 const time_t abs_timeout) {
98 timeout_sem_data_t data;
99 data.sem = sem;
100 data.abs_timeout = abs_timeout;
101
102 if (sem_trywait(sem)) {
103 if (wait_event(sem_event_timeout_wait,
104 (wakeup_t) ((unsigned) &data)) != 1) {
105 return -1; // timeout reached.
106 }
107 }
108 return 0;
109}
110
112
122int sem_trywait(sem_t * sem);
123#ifndef DOXYGEN_SHOULD_SKIP_THIS
124__asm__("\n\
125.text\n\
126.align 1\n\
127.globl _sem_trywait\n\
128 _sem_trywait:\n\
129 stc ccr,r1h ; save flags \n\
130 orc #0x80,ccr ; block all but NMI\n\
131 mov.b @r0,r1l\n\
132 beq sem_fail ; !=0 -> decrease, return 0\n\
133 dec r1l\n\
134 mov.b r1l,@r0\n\
135 sub.w r0,r0 ; return 0\n\
136 bra sem_ok\n\
137\n\
138 sem_fail:\n\
139 mov #0xffff,r0 ; else return 0xffff\n\
140\n\
141 sem_ok:\n\
142 ldc r1h,ccr ; restore flags\n\
143 rts\n\
144 ");
145#endif // DOXYGEN_SHOULD_SKIP_THIS
146
147#endif // CONF_SEMAPHORES
__asm__("\n\ .text\n\ .globl _atomic_inc\n\ _atomic_inc:\n\ stc ccr, r1h ; save flags\n\ orc #0x80, ccr ; disable all but NMI\n\ mov.b @r0, r1l\n\ inc r1l\n\ mov.b r1l, @r0\n\ ldc r1h, ccr ; restore flags\n\ rts\n\ ")
Interface: POSIX 1003.1b semaphores for task synchronization.
int sem_timedwait(sem_t *sem, const time_t abs_timeout)
Wait for semaphore (blocking with timeout).
int sem_trywait(sem_t *sem)
Try a wait for semaphore (non-blocking)
int sem_wait(sem_t *sem)
Wait for semaphore (blocking)
atomic_t sem_t
the semaphore data-type
Definition: semaphore.h:46
time_t get_system_up_time(void)
retrieve the current system time
unsigned long time_t
time type
Definition: time.h:50
unsigned long wakeup_t
wakeup data area type
Definition: tm.h:57
Interface: reduced UNIX standard library.
wakeup_t wait_event(wakeup_t(*wakeup)(wakeup_t), wakeup_t data)
Definition: unistd.h:112

brickOS is released under the Mozilla Public License.
Original code copyright 1998-2005 by the authors.

Generated for brickOS Kernel Developer by doxygen 1.9.4