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