Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
99 | pmbaty | 1 | #include <stdlib.h> |
2 | #include <stdio.h> |
||
3 | #include <errno.h> |
||
4 | #include "sysport.h" |
||
5 | |||
6 | /**** CLOCK *************************************************************************/ |
||
7 | |||
8 | #if defined(USECLOCK) |
||
9 | |||
10 | #include <time.h> |
||
11 | extern myclock_t myclock(void) {return (myclock_t)clock();} |
||
12 | extern myclock_t ticks_per_sec (void) {return CLOCKS_PER_SEC;} |
||
13 | |||
14 | #elif defined(USEWINCLOCK) |
||
15 | |||
16 | #define WIN32_LEAN_AND_MEAN |
||
17 | #include <windows.h> |
||
18 | extern myclock_t myclock(void) {return (myclock_t)GetTickCount();} |
||
19 | extern myclock_t ticks_per_sec (void) {return 1000;} |
||
20 | |||
21 | |||
22 | #elif defined(USELINCLOCK) |
||
23 | |||
24 | #include <sys/time.h> |
||
25 | extern myclock_t myclock(void) |
||
26 | { |
||
27 | struct timeval tv; |
||
28 | gettimeofday(&tv, NULL); |
||
29 | return (myclock_t)tv.tv_sec * 1000 + (myclock_t)tv.tv_usec/1000; |
||
30 | } |
||
31 | extern myclock_t ticks_per_sec (void) {return 1000;} |
||
32 | |||
33 | #else |
||
34 | |||
35 | #error No Clock specified in compilation |
||
36 | |||
37 | #endif |
||
38 | |||
39 | /**** PATH NAMES *************************************************************************/ |
||
40 | |||
41 | #if defined(GCCLINUX) |
||
42 | extern int isfoldersep (int x) { return x == '/';} |
||
43 | #elif defined(MVSC) |
||
44 | extern int isfoldersep (int x) { return x == '\\' || x == ':';} |
||
45 | #else |
||
46 | extern int isfoldersep (int x) { return x == '/' || x == '\\' || x == ':';} |
||
47 | #endif |
||
48 | |||
49 | /**** Maximum Files Open *****************************************************************/ |
||
50 | |||
51 | #if defined(__MINGW32__) || defined(__MINGW64__) |
||
52 | extern int mysys_fopen_max (void) { return FOPEN_MAX;} |
||
53 | #elif defined(GCCLINUX) |
||
54 | #include <sys/resource.h> |
||
55 | #if 0 |
||
56 | struct rlimit { |
||
57 | rlim_t rlim_cur; /* Soft limit */ |
||
58 | rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */ |
||
59 | }; |
||
60 | #endif |
||
61 | extern int mysys_fopen_max (void) |
||
62 | { |
||
63 | int ok; |
||
64 | struct rlimit rl; |
||
65 | ok = 0 == getrlimit(RLIMIT_NOFILE, &rl); |
||
66 | if (ok) |
||
67 | return (int)rl.rlim_cur; |
||
68 | else |
||
69 | return FOPEN_MAX; |
||
70 | } |
||
71 | #elif defined(MVSC) |
||
72 | extern int mysys_fopen_max (void) { return FOPEN_MAX;} |
||
73 | #else |
||
74 | extern int mysys_fopen_max (void) { return FOPEN_MAX;} |
||
75 | #endif |
||
76 | |||
77 | |||
78 | #if defined(MULTI_THREADED_INTERFACE) |
||
79 | /**** THREADS ****************************************************************************/ |
||
80 | |||
81 | /* |
||
82 | | |
||
83 | | POSIX |
||
84 | | |
||
85 | \*-------------------------*/ |
||
86 | #if defined (POSIX_THREADS) |
||
87 | |||
88 | #include <pthread.h> |
||
89 | |||
90 | extern int /* boolean */ |
||
91 | mythread_create (/*@out@*/ mythread_t *thread, routine_t start_routine, void *arg, /*@out@*/ int *ret_error) |
||
92 | { |
||
93 | const pthread_attr_t *attr = NULL; /* default attributes */ |
||
94 | int ret; |
||
95 | ret = pthread_create (thread, attr, start_routine, arg); |
||
96 | *ret_error = ret; |
||
97 | return 0 == ret; |
||
98 | } |
||
99 | |||
100 | extern int /* boolean */ |
||
101 | mythread_join (mythread_t thread) |
||
102 | { |
||
103 | void *p; /* value return from pthread_exit, not used */ |
||
104 | int ret = pthread_join (thread, &p); |
||
105 | return 0 == ret; |
||
106 | } |
||
107 | |||
108 | extern void |
||
109 | mythread_exit (void) |
||
110 | { |
||
111 | pthread_exit (NULL); |
||
112 | } |
||
113 | |||
114 | |||
115 | extern const char * |
||
116 | mythread_create_error (int err) |
||
117 | { |
||
118 | const char *s; |
||
119 | switch (err) { |
||
120 | case 0 : s = "Success"; break; |
||
121 | case EAGAIN: s = "EAGAIN" ; break; |
||
122 | case EINVAL: s = "EINVAL" ; break; |
||
123 | case EPERM : s = "EPERM" ; break; |
||
124 | default : s = "Unknown error"; break; |
||
125 | } |
||
126 | return s; |
||
127 | } |
||
128 | |||
129 | extern void mythread_mutex_init (mythread_mutex_t *m) { pthread_mutex_init (m,NULL);} |
||
130 | extern void mythread_mutex_destroy (mythread_mutex_t *m) { pthread_mutex_destroy(m) ;} |
||
131 | extern void mythread_mutex_lock (mythread_mutex_t *m) { pthread_mutex_lock (m) ;} |
||
132 | extern void mythread_mutex_unlock (mythread_mutex_t *m) { pthread_mutex_unlock (m) ;} |
||
133 | |||
134 | #ifdef SPINLOCKS |
||
135 | extern void mythread_spinx_init (mythread_spinx_t *m) { pthread_spin_init (m,0);} /**/ |
||
136 | extern void mythread_spinx_destroy (mythread_spinx_t *m) { pthread_spin_destroy(m) ;} /**/ |
||
137 | extern void mythread_spinx_lock (mythread_spinx_t *m) { pthread_spin_lock (m) ;} /**/ |
||
138 | extern void mythread_spinx_unlock (mythread_spinx_t *m) { pthread_spin_unlock (m) ;} /**/ |
||
139 | #else |
||
140 | extern void mythread_spinx_init (mythread_spinx_t *m) { pthread_mutex_init (m,NULL);} /**/ |
||
141 | extern void mythread_spinx_destroy (mythread_spinx_t *m) { pthread_mutex_destroy(m) ;} /**/ |
||
142 | extern void mythread_spinx_lock (mythread_spinx_t *m) { pthread_mutex_lock (m) ;} /**/ |
||
143 | extern void mythread_spinx_unlock (mythread_spinx_t *m) { pthread_mutex_unlock (m) ;} /**/ |
||
144 | #endif |
||
145 | |||
146 | /* semaphores */ |
||
147 | extern int /* boolean */ |
||
148 | mysem_init (mysem_t *sem, unsigned int value) |
||
149 | { return -1 != sem_init (sem, 0 /*not shared with processes*/, value);} |
||
150 | |||
151 | extern int /* boolean */ |
||
152 | mysem_wait (mysem_t *sem) |
||
153 | { return 0 == sem_wait (sem);} |
||
154 | |||
155 | extern int /* boolean */ |
||
156 | mysem_post (mysem_t *sem) |
||
157 | { return 0 == sem_post (sem);} |
||
158 | |||
159 | extern int /* boolean */ |
||
160 | mysem_destroy (mysem_t *sem) |
||
161 | { return 0 == sem_destroy (sem);} |
||
162 | |||
163 | /* |
||
164 | | |
||
165 | | NT_THREADS |
||
166 | | |
||
167 | \*-------------------------*/ |
||
168 | #elif defined(NT_THREADS) |
||
169 | |||
170 | #define WIN32_LEAN_AND_MEAN |
||
171 | #include <windows.h> |
||
172 | #include <process.h> |
||
173 | |||
174 | extern int /* boolean */ |
||
175 | mythread_create (/*@out@*/ mythread_t *thread, routine_t start_routine, void *arg, /*@out@*/ int *ret_error) |
||
176 | { |
||
177 | static unsigned int thread_id; |
||
178 | mythread_t t; |
||
179 | int /* boolean */ is_ok; |
||
180 | |||
181 | t = (mythread_t) _beginthreadex (NULL, 0, start_routine, arg, 0, &thread_id ); |
||
182 | is_ok = (t != 0); |
||
183 | *thread = t; |
||
184 | *ret_error = is_ok? 0: errno; |
||
185 | return is_ok; |
||
186 | } |
||
187 | |||
188 | extern int /* boolean */ |
||
189 | mythread_join (mythread_t thread) |
||
190 | { |
||
191 | unsigned long int ret; |
||
192 | ret = WaitForSingleObject (thread, INFINITE); |
||
193 | CloseHandle(thread); |
||
194 | return ret != WAIT_FAILED; |
||
195 | } |
||
196 | |||
197 | extern void |
||
198 | mythread_exit (void) |
||
199 | { |
||
200 | return; |
||
201 | } |
||
202 | |||
203 | extern const char * |
||
204 | mythread_create_error (int err) |
||
205 | { |
||
206 | const char *s; |
||
207 | switch (err) { |
||
208 | case 0 : s = "Success"; break; |
||
209 | case EAGAIN: s = "EAGAIN" ; break; |
||
210 | case EINVAL: s = "EINVAL" ; break; |
||
211 | case EPERM : s = "EPERM" ; break; |
||
212 | default : s = "Unknown error"; break; |
||
213 | } |
||
214 | return s; |
||
215 | } |
||
216 | |||
217 | extern void mythread_mutex_init (mythread_mutex_t *m) { *m = CreateMutex(0, FALSE, 0) ;} |
||
218 | extern void mythread_mutex_destroy (mythread_mutex_t *m) { CloseHandle(*m) ;} |
||
219 | extern void mythread_mutex_lock (mythread_mutex_t *m) { WaitForSingleObject(*m, INFINITE) ;} |
||
220 | extern void mythread_mutex_unlock (mythread_mutex_t *m) { ReleaseMutex(*m) ;} |
||
221 | |||
222 | extern void mythread_spinx_init (mythread_spinx_t *m) { InitializeCriticalSection(m) ;} /**/ |
||
223 | extern void mythread_spinx_destroy (mythread_spinx_t *m) { DeleteCriticalSection(m) ;} /**/ |
||
224 | extern void mythread_spinx_lock (mythread_spinx_t *m) { EnterCriticalSection (m) ;} /**/ |
||
225 | extern void mythread_spinx_unlock (mythread_spinx_t *m) { LeaveCriticalSection (m) ;} /**/ |
||
226 | |||
227 | /* semaphores */ |
||
228 | extern int /* boolean */ |
||
229 | mysem_init (mysem_t *sem, unsigned int value) |
||
230 | { |
||
231 | mysem_t h = |
||
232 | CreateSemaphore( |
||
233 | NULL, /* cannot be inherited */ |
||
234 | value, /* Initial Count */ |
||
235 | 256, /* Maximum Count */ |
||
236 | NULL /* Name --> NULL, not shared among threads */ |
||
237 | ); |
||
238 | |||
239 | if (h != NULL) *sem = h; |
||
240 | |||
241 | return h != NULL; |
||
242 | } |
||
243 | |||
244 | extern int /* boolean */ |
||
245 | mysem_wait (mysem_t *sem) |
||
246 | { |
||
247 | HANDLE h = *sem; |
||
248 | return WAIT_FAILED != WaitForSingleObject (h, INFINITE); |
||
249 | } |
||
250 | |||
251 | extern int /* boolean */ |
||
252 | mysem_post (mysem_t *sem) |
||
253 | { |
||
254 | HANDLE h = *sem; |
||
255 | return 0 != ReleaseSemaphore(h, 1, NULL); |
||
256 | } |
||
257 | |||
258 | extern int /* boolean */ |
||
259 | mysem_destroy (mysem_t *sem) |
||
260 | { |
||
261 | return 0 != CloseHandle( *sem); |
||
262 | } |
||
263 | |||
264 | /**** THREADS ****************************************************************************/ |
||
265 | #else |
||
266 | #error Definition of threads not present |
||
267 | #endif |
||
268 | |||
269 | /* MULTI_THREADED_INTERFACE */ |
||
270 | #endif |
||
271 | |||
272 | |||
273 | |||
274 | |||
275 | |||
276 |