comparison src/thread/amigaos/SDL_syssem.c @ 21:75a95f82bc1f

Updated the Amiga OS port of SDL (thanks Gabriele)
author Sam Lantinga <slouken@lokigames.com>
date Thu, 10 May 2001 20:13:29 +0000
parents 74212992fb08
children e8157fcb3114
comparison
equal deleted inserted replaced
20:3dc008dc229d 21:75a95f82bc1f
23 #ifdef SAVE_RCSID 23 #ifdef SAVE_RCSID
24 static char rcsid = 24 static char rcsid =
25 "@(#) $Id$"; 25 "@(#) $Id$";
26 #endif 26 #endif
27 27
28 /* An native implementation of semaphores on AmigaOS */ 28 /* An implementation of semaphores using mutexes and condition variables */
29 29
30 #include "SDL_error.h" 30 #include "SDL_error.h"
31 #include "SDL_thread.h" 31 #include "SDL_thread.h"
32 #include "SDL_systhread_c.h" 32 #include "SDL_systhread_c.h"
33 33
34 34
35 struct SDL_semaphore 35 struct SDL_semaphore
36 { 36 {
37 struct SignalSemaphore Sem; 37 struct SignalSemaphore Sem;
38 Uint32 count;
39 Uint32 waiters_count;
40 SDL_mutex *count_lock;
41 SDL_cond *count_nonzero;
38 }; 42 };
39 43
40 #undef D(x) 44 #undef D
41 45
42 #define D(x) 46 #define D(x)
43 47
44 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) 48 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
45 { 49 {
46 SDL_sem *sem; 50 SDL_sem *sem;
47 51
48 sem = (SDL_sem *)malloc(sizeof(*sem)); 52 sem = (SDL_sem *)malloc(sizeof(*sem));
53
49 if ( ! sem ) { 54 if ( ! sem ) {
50 SDL_OutOfMemory(); 55 SDL_OutOfMemory();
51 return(0); 56 return(0);
52 } 57 }
53 memset(sem, 0, sizeof(*sem));
54 58
55 D(bug("Creating semaphore %lx...\n",sem)); 59 D(bug("Creating semaphore %lx...\n",sem));
56 60
61 memset(sem,0,sizeof(*sem));
62
57 InitSemaphore(&sem->Sem); 63 InitSemaphore(&sem->Sem);
58 #if 1 // Allow multiple obtainings of the semaphore 64
59 while ( initial_value-- ) {
60 ReleaseSemaphore(&sem->Sem);
61 }
62 #endif
63 return(sem); 65 return(sem);
64 } 66 }
65 67
66 void SDL_DestroySemaphore(SDL_sem *sem) 68 void SDL_DestroySemaphore(SDL_sem *sem)
67 { 69 {
73 } 75 }
74 } 76 }
75 77
76 int SDL_SemTryWait(SDL_sem *sem) 78 int SDL_SemTryWait(SDL_sem *sem)
77 { 79 {
78 int retval;
79
80 if ( ! sem ) { 80 if ( ! sem ) {
81 SDL_SetError("Passed a NULL semaphore"); 81 SDL_SetError("Passed a NULL semaphore");
82 return -1; 82 return -1;
83 } 83 }
84 84
85 D(bug("TryWait semaphore...%lx\n",sem)); 85 D(bug("TryWait semaphore...%lx\n",sem));
86 86
87 retval = SDL_MUTEX_TIMEDOUT; 87 ObtainSemaphore(&sem->Sem);
88 if ( AttemptSemaphore(&sem->Sem) ) { 88 // ReleaseSemaphore(&sem->Sem);
89 retval = 0; 89
90 } 90 return 1;
91 return retval;
92 } 91 }
93 92
94 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) 93 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
95 { 94 {
96 int retval; 95 int retval;
96
97 97
98 if ( ! sem ) { 98 if ( ! sem ) {
99 SDL_SetError("Passed a NULL semaphore"); 99 SDL_SetError("Passed a NULL semaphore");
100 return -1; 100 return -1;
101 } 101 }
102 102
103 D(bug("WaitTimeout (%ld) semaphore...%lx\n",timeout,sem)); 103 D(bug("WaitTimeout (%ld) semaphore...%lx\n",timeout,sem));
104 104
105 #if 1 // We need to keep trying the semaphore until the timeout expires 105 /* A timeout of 0 is an easy case */
106 retval = SDL_MUTEX_TIMEDOUT; 106 if ( timeout == 0 ) {
107 then = SDL_GetTicks(); 107 return SDL_SemTryWait(sem);
108 do { 108 }
109 if ( AttemptSemaphore(&sem->Sem) ) { 109 /*
110 retval = 0; 110 SDL_LockMutex(sem->count_lock);
111 } 111 ++sem->waiters_count;
112 now = SDL_GetTicks(); 112 retval = 0;
113 } while ( (retval == SDL_MUTEX_TIMEDOUT) && ((now-then) < timeout) ); 113 while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
114 #else 114 retval = SDL_CondWaitTimeout(sem->count_nonzero,
115 sem->count_lock, timeout);
116 }
117 --sem->waiters_count;
118 --sem->count;
119 SDL_UnlockMutex(sem->count_lock);
120 */
115 if(!(retval=AttemptSemaphore(&sem->Sem))) 121 if(!(retval=AttemptSemaphore(&sem->Sem)))
116 { 122 {
117 SDL_Delay(timeout); 123 SDL_Delay(timeout);
118 retval=AttemptSemaphore(&sem->Sem); 124 retval=AttemptSemaphore(&sem->Sem);
119 } 125 }
121 if(retval==TRUE) 127 if(retval==TRUE)
122 { 128 {
123 // ReleaseSemaphore(&sem->Sem); 129 // ReleaseSemaphore(&sem->Sem);
124 retval=1; 130 retval=1;
125 } 131 }
126 #endif 132
127 return retval; 133 return retval;
128 } 134 }
129 135
130 int SDL_SemWait(SDL_sem *sem) 136 int SDL_SemWait(SDL_sem *sem)
131 { 137 {
132 if ( ! sem ) {
133 SDL_SetError("Passed a NULL semaphore");
134 return -1;
135 }
136 #if 1 // This should be an infinite wait - FIXME, what is the return value?
137 ObtainSemaphore(&sem->Sem); 138 ObtainSemaphore(&sem->Sem);
138 return 0; 139 return 0;
139 #else 140 // return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
140 return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
141 #endif
142 } 141 }
143 142
144 Uint32 SDL_SemValue(SDL_sem *sem) 143 Uint32 SDL_SemValue(SDL_sem *sem)
145 { 144 {
146 Uint32 value; 145 Uint32 value;
147 146
148 value = 0; 147 value = 0;
149 if ( sem ) { 148 if ( sem ) {
150 value = sem->Sem.ss_NestCount; 149 value = sem->Sem.ss_NestCount;
150 // SDL_UnlockMutex(sem->count_lock);
151 } 151 }
152 return value; 152 return value;
153 } 153 }
154 154
155 int SDL_SemPost(SDL_sem *sem) 155 int SDL_SemPost(SDL_sem *sem)
159 return -1; 159 return -1;
160 } 160 }
161 D(bug("SemPost semaphore...%lx\n",sem)); 161 D(bug("SemPost semaphore...%lx\n",sem));
162 162
163 ReleaseSemaphore(&sem->Sem); 163 ReleaseSemaphore(&sem->Sem);
164 #if 0
165 SDL_LockMutex(sem->count_lock);
166 if ( sem->waiters_count > 0 ) {
167 SDL_CondSignal(sem->count_nonzero);
168 }
169 ++sem->count;
170 SDL_UnlockMutex(sem->count_lock);
171 #endif
164 return 0; 172 return 0;
165 } 173 }
166 174