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 
41 wakeup_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 
63 int 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 
73 typedef struct {
74  sem_t *sem;
75  time_t abs_timeout;
76 } timeout_sem_data_t;
77 
78 static 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 
96 int 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 
122 int 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
int sem_wait(sem_t *sem)
Wait for semaphore (blocking)
time_t get_system_up_time(void)
retrieve the current system time
atomic_t sem_t
the semaphore data-type
Definition: semaphore.h:46
Interface: reduced UNIX standard library.
int sem_timedwait(sem_t *sem, const time_t abs_timeout)
Wait for semaphore (blocking with timeout).
unsigned long wakeup_t
wakeup data area type
Definition: tm.h:57
Interface: POSIX 1003.1b semaphores for task synchronization.
__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\ ")
unsigned long time_t
time type
Definition: time.h:50
int sem_trywait(sem_t *sem)
Try a wait for semaphore (non-blocking)
wakeup_t wait_event(wakeup_t(*wakeup)(wakeup_t), wakeup_t data)

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

Generated on Sun Jun 29 2014 23:26:59 for brickOS Kernel Developer by doxygen 1.8.7