1 //////////////////////////////////////////////////////////////////////
2 //
3 // Pixie
4 //
5 // Copyright � 1999 - 2003, Okan Arikan
6 //
7 // Contact: okan@cs.utexas.edu
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 ///////////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////////
25 //
26 // File : os.h
27 // Classes : -
28 // Description : OS dependent functions
29 //
30 ////////////////////////////////////////////////////////////////////////
31 #ifndef OS_H
32 #define OS_H
33
34 #include "global.h"
35
36 #ifdef _WINDOWS // >>>>>>>>>>>>>>>>>>> Windoze
37 #define WIN32_LEAN_AND_MEAN
38 #include <windows.h>
39 #include <winsock.h>
40 #include <malloc.h>
41 #include <process.h>
42
43 class CRWLock {
44 HANDLE readerEvent;
45 HANDLE mutex;
46 HANDLE writerMutex;
47 LONG readCount;
48
49 friend void osCreateRWLock(CRWLock &);
50 friend void osDeleteRWLock(CRWLock &);
51 friend void osReadLock(CRWLock &);
52 friend void osReadUnlock(CRWLock &);
53 friend void osWriteLock(CRWLock &);
54 friend void osWriteUnlock(CRWLock &);
55 };
56
57 #define socklen_t int
58 #define LIB_EXPORT __declspec(dllexport)
59 #define LIB_IMPORT __declspec(dllimport)
60 #define popen _popen
61 #define pclose _pclose
62 #define j1 _j1
63 #define TThread HANDLE
64 #define TMutex CRITICAL_SECTION
65 #define TSemaphore HANDLE
66 #define TRWLock CRWLock
67 #define TFunPrefix DWORD WINAPI
68 #define TFunReturn return 0
69 typedef LPTHREAD_START_ROUTINE TFun;
70
71 #define OS_DIR_SEPERATOR '\\'
72 #define OS_DIR_SEPERATOR_STRING "\\"
73
74 #else // >>>>>>>>>>>>>>>>>>> Unix
75 #include <unistd.h>
76 #include <pthread.h>
77 #include <sys/socket.h>
78 #include <netinet/in.h>
79 #include <netinet/tcp.h>
80 #include <arpa/inet.h>
81 #include <netdb.h>
82 #include <ctype.h>
83 #include <signal.h>
84 #include <errno.h>
85
86 //#if defined(__APPLE__) || defined(__APPLE_CC__) // guard against __APPLE__ being undef from ftlk
87 #include <semaphore.h>
88 //#endif
89
90
91 #ifndef LIB_EXPORT
92 #define LIB_EXPORT extern
93 #endif
94 #define LIB_IMPORT extern
95 #define SOCKET int
96 #define closesocket close
97 #define INVALID_SOCKET -1
98 #define TThread pthread_t
99 #define TMutex pthread_mutex_t
100 #define TSemaphore sem_t
101 #define TRWLock pthread_rwlock_t
102 #define TFunPrefix void *
103 #define TFunReturn return NULL
104 typedef void *(*TFun)(void *);
105
106
107 #define OS_DIR_SEPERATOR '/'
108 #define OS_DIR_SEPERATOR_STRING "/"
109
110 #endif
111
112 // Some common headers
113 #include <stdio.h>
114 #include <stdlib.h>
115
116
117 // Because Microzort developers are monkeys, we need these
118 // for compatibility with the .NET 2005
119 #ifdef _WINDOWS // >>>>>>>>>>>>>>>>>>> Windoze
120
121 #ifndef strdup
122 #define strdup _strdup
123 #endif
124
125
126 #ifndef fileno
127 #define fileno _fileno
128 #endif
129
130 #endif // >>>>>>>>>>>>>>>>>>> Windoze
131
132
133 // Maximum length of a path
134 const int OS_MAX_PATH_LENGTH = 512;
135
136 // Init/shutdown
137 void osInit();
138 void osShutdown();
139
140 // Module I/O
141 void *osLoadModule(const char *);
142 const char *osModuleError();
143 void osUnloadModule(void *);
144 void *osResolve(void *,const char *);
145
146 // Get an environment variable (return NULL if non existent)
147 char *osEnvironment(const char *);
148
149 // File io
150 int osFileExists(const char *);
151 void osFixSlashes(char *);
152 void osTempdir(char *result, size_t resultsize);
153 void osTempname(const char *,const char *,char*);
154
155 // Directory IO
156 void osCreateDir(const char *);
157 void osDeleteDir(const char *);
158 void osDeleteFile(const char *);
159
160 // Iterate thru files in a directory
161 void osEnumerate(const char *,int (*callback)(const char *,void *),void *);
162
163 // Time functions
164 float osTime();
165 float osCPUTime();
166
167 // Sync. functions
168 TThread osCreateThread(TFun,void *);
169 int osWaitThread(TThread);
170 void osCreateMutex(TMutex &);
171 void osDeleteMutex(TMutex &);
172 void osCreateSemaphore(TMutex &,int);
173 void osDeleteSemaphore(TMutex &);
174
175 // Misc functions
176 void osProcessEscapes(char *str);
177 int osAvailableCPUs();
178
179 ///////////////////////////////////////////////////////////////////////
180 // Function : osLock
181 // Description : Lock a mutex
182 // Return Value :
183 // Comments :
osLock(TMutex & mutex)184 inline void osLock(TMutex &mutex) {
185 #ifdef _WINDOWS
186 EnterCriticalSection(&mutex);
187 #else
188 pthread_mutex_lock(&mutex);
189 #endif
190 }
191
192 ///////////////////////////////////////////////////////////////////////
193 // Function : osUnlock
194 // Description : Unlock a mutex
195 // Return Value :
196 // Comments :
osUnlock(TMutex & mutex)197 inline void osUnlock(TMutex &mutex) {
198 #ifdef _WINDOWS
199 LeaveCriticalSection(&mutex);
200 #else
201 pthread_mutex_unlock(&mutex);
202 #endif
203 }
204
205
206 ///////////////////////////////////////////////////////////////////////
207 // Function : osUp
208 // Description : Increment a semaphore
209 // Return Value :
210 // Comments :
osUp(TSemaphore & sem)211 inline void osUp(TSemaphore &sem) {
212 #ifdef _WINDOWS
213 ReleaseSemaphore(sem,1,NULL);
214 #else
215 sem_post(&sem);
216 #endif
217 }
218
219 ///////////////////////////////////////////////////////////////////////
220 // Function : osDown
221 // Description : Decrement a semaphore
222 // Return Value :
223 // Comments :
osDown(TSemaphore & sem)224 inline void osDown(TSemaphore &sem) {
225 #ifdef _WINDOWS
226 WaitForSingleObject(sem,INFINITE);
227 #else
228 sem_wait(&sem);
229 #endif
230 }
231
232 ///////////////////////////////////////////////////////////////////////
233 // Function : osCreateRWLock
234 // Description : create a read-write lock
235 // Return Value :
236 // Comments :
osCreateRWLock(TRWLock & l)237 inline void osCreateRWLock(TRWLock &l) {
238 #ifdef _WINDOWS
239 l.readerEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
240 l.mutex = CreateEvent(NULL,FALSE,TRUE,NULL);
241 l.writerMutex = CreateMutex(NULL,FALSE,NULL);
242 l.readCount = -1;
243 #else
244 pthread_rwlock_init(&l,NULL);
245 #endif
246 }
247
248 ///////////////////////////////////////////////////////////////////////
249 // Function : osDeleteRWLock
250 // Description : destroy a read-write lock
251 // Return Value :
252 // Comments :
osDeleteRWLock(TRWLock & l)253 inline void osDeleteRWLock(TRWLock &l) {
254 #ifdef _WINDOWS
255 CloseHandle(l.readerEvent);
256 CloseHandle(l.mutex);
257 CloseHandle(l.writerMutex);
258 #else
259 pthread_rwlock_destroy(&l);
260 #endif
261 }
262
263 ///////////////////////////////////////////////////////////////////////
264 // Function : osReadLock
265 // Description : lock for reading
266 // Return Value :
267 // Comments :
osReadLock(TRWLock & l)268 inline void osReadLock(TRWLock &l) {
269 #ifdef _WINDOWS
270 // If we're first reader, claim mutex for all readers
271 if (InterlockedIncrement(&l.readCount) == 0) {
272 WaitForSingleObject(l.mutex, INFINITE);
273 }
274 // Signal that there are readers
275 WaitForSingleObject(l.readerEvent, INFINITE);
276 #else
277 pthread_rwlock_rdlock(&l);
278 #endif
279 }
280
281 ///////////////////////////////////////////////////////////////////////
282 // Function : osReadUnlock
283 // Description : unlock after reading
284 // Return Value :
285 // Comments :
osReadUnlock(TRWLock & l)286 inline void osReadUnlock(TRWLock &l) {
287 #ifdef _WINDOWS
288 // If we're last reader, signal that there are no more
289 if (InterlockedDecrement(&l.readCount) < 0) {
290 ResetEvent(l.readerEvent);
291 // And release global mutex for a writer
292 ReleaseMutex(l.mutex);
293 }
294 #else
295 pthread_rwlock_unlock(&l);
296 #endif
297 }
298
299 ///////////////////////////////////////////////////////////////////////
300 // Function : osWriteLock
301 // Description : lock for writing
302 // Return Value :
303 // Comments :
osWriteLock(TRWLock & l)304 inline void osWriteLock(TRWLock &l) {
305 #ifdef _WINDOWS
306 // Ensure we are the only writr
307 WaitForSingleObject(l.writerMutex, INFINITE);
308 // Claim the global mutex
309 WaitForSingleObject(l.mutex, INFINITE);
310 #else
311 pthread_rwlock_wrlock(&l);
312 #endif
313 }
314
315 ///////////////////////////////////////////////////////////////////////
316 // Function : osWriteUnlock
317 // Description : unlock after writing
318 // Return Value :
319 // Comments :
osWriteUnlock(TRWLock & l)320 inline void osWriteUnlock(TRWLock &l) {
321 #ifdef _WINDOWS
322 // Signal that that there are no more writers
323 SetEvent(l.mutex);
324 // And release writer mutex for a reader
325 ReleaseMutex(l.writerMutex);
326 #else
327 pthread_rwlock_unlock(&l);
328 #endif
329 }
330
331
332 // Misc. file extensions
333 #ifdef _WINDOWS
334 const char osModuleExtension[] = "dll";
335 #else // Windoze
336 #ifdef __APPLE_CC__
337 //const char osModuleExtension[] = "dylib";
338
339 // loadable libs on darwin are supposed to be .bundle
340 // but automake/libtool chooses .so and it can't be
341 // changed. Xcode can be
342 const char osModuleExtension[] = "so";
343 #else // OSX
344 const char osModuleExtension[] = "so";
345 #endif // OSX
346 #endif // Windoze
347
348 #endif
349
350