Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

kernel/semaphore.c

Go to the documentation of this file.
00001 
00006 /*
00007  *  The contents of this file are subject to the Mozilla Public License
00008  *  Version 1.0 (the "License"); you may not use this file except in
00009  *  compliance with the License. You may obtain a copy of the License at
00010  *  http://www.mozilla.org/MPL/
00011  *
00012  *  Software distributed under the License is distributed on an "AS IS"
00013  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00014  *  License for the specific language governing rights and limitations
00015  *  under the License.
00016  *
00017  *  The Original Code is legOS code, released October 17, 1999.
00018  *
00019  *  The Initial Developer of the Original Code is Markus L. Noga.
00020  *  Portions created by Markus L. Noga are Copyright (C) 1999
00021  *  Markus L. Noga. All Rights Reserved.
00022  *
00023  *  Contributor(s): Markus L. Noga <markus@noga.de>
00024  */
00025 
00026 #include <semaphore.h>
00027 
00028 #ifdef CONF_SEMAPHORES
00029 
00030 #include <unistd.h>
00031 
00033 //
00034 // Functions
00035 //
00037 
00039 
00041 wakeup_t sem_event_wait(wakeup_t data) {
00042         sem_t *sem=(sem_t*) ((unsigned)data);
00043         
00044         // we're called by the scheduler, therefore in an IRQ handler,
00045         // so no worrying about IRQs.
00046         //
00047         if(*sem) {
00048                 (*sem)--;
00049                 return 1;                       // sem!=0 -> wakeup
00050         }
00051         return 0;
00052 }
00053 
00055 
00063 int sem_wait(sem_t * sem) {
00064         // check if semaphore is available, if not, go to sleep
00065         
00066         if(sem_trywait(sem))
00067                 if (wait_event(sem_event_wait,(unsigned long) ((unsigned)sem)) == 0)
00068                         return -1;
00069         
00070         return 0;
00071 }
00072 
00073 typedef struct {
00074         sem_t  *sem;
00075         time_t abs_timeout;
00076 } timeout_sem_data_t;
00077 
00078 static wakeup_t sem_event_timeout_wait(wakeup_t data) {
00079         timeout_sem_data_t *tsem = (timeout_sem_data_t*) ((unsigned)data);
00080         
00081         // we're called by the scheduler, therefore in an IRQ handler,
00082         // so no worrying about IRQs.
00083         //
00084         if (*tsem->sem) {
00085                 (*tsem->sem)--;
00086                 return 1;                       // sem!=0 -> wakeup
00087         }
00088         
00089         if (tsem->abs_timeout <= get_system_up_time()) {
00090                 return 2;                       // timeout reached -> wakeup
00091         }
00092 
00093         return 0;
00094 }
00095 
00096 int sem_timedwait(sem_t *sem,
00097                   const time_t abs_timeout) {
00098         timeout_sem_data_t data;
00099         data.sem = sem;
00100         data.abs_timeout = abs_timeout;
00101         
00102         if (sem_trywait(sem)) {
00103                 if (wait_event(sem_event_timeout_wait, 
00104                                (wakeup_t) ((unsigned) &data)) != 1) {
00105                         return -1; // timeout reached.
00106                 }
00107         }
00108         return 0;
00109 }
00110 
00112 
00122 int sem_trywait(sem_t * sem);
00123 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00124 __asm__("\n\
00125 .text\n\
00126 .align 1\n\
00127 .globl _sem_trywait\n\
00128        _sem_trywait:\n\
00129         stc ccr,r1h                             ; save flags    \n\
00130         orc #0x80,ccr                           ; block all but NMI\n\
00131         mov.b @r0,r1l\n\
00132         beq sem_fail                            ; !=0 -> decrease, return 0\n\
00133         dec r1l\n\
00134         mov.b r1l,@r0\n\
00135         sub.w r0,r0                             ; return 0\n\
00136         bra sem_ok\n\
00137 \n\
00138  sem_fail:\n\
00139         mov #0xffff,r0                          ; else return 0xffff\n\
00140 \n\
00141  sem_ok:\n\
00142         ldc r1h,ccr                             ; restore flags\n\
00143         rts\n\
00144         ");
00145 #endif // DOXYGEN_SHOULD_SKIP_THIS
00146         
00147 #endif // CONF_SEMAPHORES

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

Generated on Mon Feb 16 21:02:10 2004 for brickOS Kernel Developer by doxygen 1.3.5