00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "src/common/shared.hpp"
00018 #include "src/memory/memset.hpp"
00019 #include "src/memory/heap.hpp"
00020 #include "src/memory/align.hpp"
00021 #include "src/memory/heap.hpp"
00022 #include "src/thread/thread.hpp"
00023 #include "src/thread/scheduler.hpp"
00024 #include "src/ipc/lock.hpp"
00025 #include "src/ipc/sem.hpp"
00026
00027
00028
00029
00030
00031
00032 int sem_init(sem_t *sem, unsigned int value, const char *name)
00033 { _Pf("sem_init");
00034 memset(sem,0,sizeof(struct sem_t));
00035 sem->wait_queue.init(name, &Memory::Heap::heap0);
00036 sem->lock_sem.init((char*)name);
00037 sem->name=name;
00038 sem->val= value;
00039 sem->flags=SF_OPEN;
00040
00041 preturn(ESUCCESS);
00042 }
00043
00044
00045 int sem_destroy(sem_t *sem)
00046 { _Pf("sem_destroy");
00047 if ((sem->flags&SF_OPEN)==0)
00048 preturn(EFAIL);
00049 sem->wait_queue.done();
00050 memset(sem,0,sizeof(struct sem_t));
00051 preturn(ESUCCESS);
00052 }
00053
00054
00055 int sem_getvalue(sem_t *sem, int *sval)
00056 { _Pf("sem_getvalue");
00057 if ((sem->flags&SF_OPEN)==0)
00058 preturn(EFAIL);
00059
00060 sem->lock_sem.lock();
00061 *sval= sem->val;
00062 sem->lock_sem.ulock();
00063 preturn(ESUCCESS);
00064 }
00065
00066
00067 int sem_wait(sem_t *sem)
00068 { _Pf("sem_wait");
00069 if ((sem->flags&SF_OPEN)==0)
00070 preturn(EFAIL);
00071
00072 int r;
00073 sem->lock_sem.lock();
00074 uint32 fl;
00075 asm volatile("pushf\npopl %0\ncli":"=g"(fl));
00076 r= --sem->val;
00077 if (r<0)
00078 sem->wait_queue.ptr((void*)current_thread,NULL);
00079 sem->lock_sem.ulock();
00080
00081 if (r<0) {
00082 if (Thread::Scheduler::multitasking_running)
00083 Thread::sem_sleep(sem, 0); else
00084 sysfail("semaphore locked with multithreading off");
00085 }
00086
00087 asm volatile("pushl %0\npopf"::"g"(fl));
00088
00089 preturn(ESUCCESS);
00090 }
00091
00092
00093 int sem_trywait(sem_t *sem)
00094 { _Pf("sem_trywait");
00095 if ((sem->flags&SF_OPEN)==0)
00096 preturn(EFAIL);
00097
00098 int r;
00099 sem->lock_sem.lock();
00100 r= sem->val;
00101 if (r>0) sem->val--;
00102
00103 sem->lock_sem.ulock();
00104 if (r>0)
00105 preturn(ESUCCESS);
00106
00107 preturn(EFAIL);
00108 }
00109
00110
00111 int sem_post(sem_t *sem)
00112 { _Pf("sem_post");
00113 if ((sem->flags&SF_OPEN)==0)
00114 preturn(EFAIL);
00115 int r;
00116 sem->lock_sem.lock();
00117 r= ++sem->val;
00118 if (r<=0) {
00119 Thread::sem_awake(bli_dt(sem->wait_queue.head,struct Thread::thread_t*));
00120 sem->wait_queue.del(sem->wait_queue.head);
00121 }
00122 sem->lock_sem.ulock();
00123 preturn(ESUCCESS);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136