1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/*
3 * The contents of this file are subject to the Mozilla Public
4 * License Version 1.1 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of
6 * the License at http://www.mozilla.org/MPL/
7 *
8 * Software distributed under the License is distributed on an "AS
9 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10 * implied. See the License for the specific language governing
11 * rights and limitations under the License.
12 *
13 * The Original Code is the Netscape Portable Runtime (NSPR).
14 *
15 * The Initial Developer of the Original Code is Netscape
16 * Communications Corporation.  Portions created by Netscape are
17 * Copyright (C) 1998-2000 Netscape Communications Corporation.  All
18 * Rights Reserved.
19 *
20 * Contributor(s):
21 *
22 * Alternatively, the contents of this file may be used under the
23 * terms of the GNU General Public License Version 2 or later (the
24 * "GPL"), in which case the provisions of the GPL are applicable
25 * instead of those above.  If you wish to allow use of your
26 * version of this file only under the terms of the GPL and not to
27 * allow others to use your version of this file under the MPL,
28 * indicate your decision by deleting the provisions above and
29 * replace them with the notice and other provisions required by
30 * the GPL.  If you do not delete the provisions above, a recipient
31 * may use your version of this file under either the MPL or the
32 * GPL.
33 */
34
35#ifndef nspr_os2_defs_h___
36#define nspr_os2_defs_h___
37
38#define INCL_DOS
39#define INCL_DOSPROCESS
40#define INCL_DOSERRORS
41#define INCL_WIN
42#define INCL_WPS
43#include <os2.h>
44#include <sys/select.h>
45
46#include "prio.h"
47
48#include <errno.h>
49
50#ifdef XP_OS2_VACPP
51/* TODO RAMSEMs need to be written for GCC/EMX */
52#define USE_RAMSEM
53#endif
54
55#ifdef USE_RAMSEM
56#pragma pack(4)
57
58#pragma pack(2)
59typedef struct _RAMSEM
60{
61   ULONG   ulTIDPID;
62   ULONG   hevSem;
63   ULONG   cLocks;
64   USHORT  cWaiting;
65   USHORT  cPosts;
66} RAMSEM, *PRAMSEM;
67
68typedef struct _CRITICAL_SECTION
69{
70    ULONG ulReserved[4]; /* Same size as RAMSEM */
71} CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
72#pragma pack(4)
73
74APIRET _Optlink SemRequest486(PRAMSEM, ULONG);
75APIRET _Optlink SemReleasex86(PRAMSEM, ULONG);
76#endif
77
78/*
79 * Internal configuration macros
80 */
81
82#define PR_LINKER_ARCH      "os2"
83#define _PR_SI_SYSNAME        "OS2"
84#define _PR_SI_ARCHITECTURE   "x86"    /* XXXMB hardcode for now */
85
86#define HAVE_DLL
87#define _PR_GLOBAL_THREADS_ONLY
88#undef  HAVE_THREAD_AFFINITY
89#define _PR_HAVE_THREADSAFE_GETHOST
90#define _PR_HAVE_ATOMIC_OPS
91
92#define HANDLE unsigned long
93#define HINSTANCE HMODULE
94
95/* --- Common User-Thread/Native-Thread Definitions --------------------- */
96
97/* --- Globals --- */
98extern struct PRLock                      *_pr_schedLock;
99
100/* --- Typedefs --- */
101typedef void (*FiberFunc)(void *);
102
103#define PR_NUM_GCREGS           8
104typedef PRInt32	                PR_CONTEXT_TYPE[PR_NUM_GCREGS];
105#define GC_VMBASE               0x40000000
106#define GC_VMLIMIT              0x00FFFFFF
107typedef int (*FARPROC)();
108
109#define _MD_MAGIC_THREAD	0x22222222
110#define _MD_MAGIC_THREADSTACK	0x33333333
111#define _MD_MAGIC_SEGMENT	0x44444444
112#define _MD_MAGIC_DIR		0x55555555
113#define _MD_MAGIC_CV        0x66666666
114
115struct _MDSemaphore {
116   HEV sem;
117};
118
119struct _MDCPU {
120    int              unused;
121};
122
123struct _MDThread {
124    HEV              blocked_sema;      /* Threads block on this when waiting
125                                         * for IO or CondVar.
126                                         */
127    PRBool           inCVWaitQueue;     /* PR_TRUE if the thread is in the
128                                         * wait queue of some cond var.
129                                         * PR_FALSE otherwise.  */
130    TID              handle;            /* OS/2 thread handle */
131    void            *sp;                /* only valid when suspended */
132    PRUint32         magic;             /* for debugging */
133    PR_CONTEXT_TYPE  gcContext;         /* Thread context for GC */
134    struct PRThread *prev, *next;       /* used by the cvar wait queue to
135                                         * chain the PRThread structures
136                                         * together */
137};
138
139struct _MDThreadStack {
140    PRUint32           magic;          /* for debugging */
141};
142
143struct _MDSegment {
144    PRUint32           magic;          /* for debugging */
145};
146
147#undef PROFILE_LOCKS
148
149struct _MDDir {
150    HDIR           d_hdl;
151    FILEFINDBUF3  d_entry;
152    PRBool           firstEntry;     /* Is this the entry returned
153                                      * by FindFirstFile()? */
154    PRUint32         magic;          /* for debugging */
155};
156
157struct _MDCVar {
158    PRUint32 magic;
159    struct PRThread *waitHead, *waitTail;  /* the wait queue: a doubly-
160                                            * linked list of threads
161                                            * waiting on this condition
162                                            * variable */
163    PRIntn nwait;                          /* number of threads in the
164                                            * wait queue */
165};
166
167#define _MD_CV_NOTIFIED_LENGTH 6
168typedef struct _MDNotified _MDNotified;
169struct _MDNotified {
170    PRIntn length;                     /* # of used entries in this
171                                        * structure */
172    struct {
173        struct _MDCVar *cv;            /* the condition variable notified */
174        PRIntn times;                  /* and the number of times notified */
175        struct PRThread *notifyHead;   /* list of threads to wake up */
176    } cv[_MD_CV_NOTIFIED_LENGTH];
177    _MDNotified *link;                 /* link to another of these, or NULL */
178};
179
180struct _MDLock {
181#ifdef USE_RAMSEM
182    CRITICAL_SECTION mutex;            /* this is recursive on NT */
183#else
184    HMTX mutex;                        /* this is recursive on NT */
185#endif
186
187    /*
188     * When notifying cvars, there is no point in actually
189     * waking up the threads waiting on the cvars until we've
190     * released the lock.  So, we temporarily record the cvars.
191     * When doing an unlock, we'll then wake up the waiting threads.
192     */
193    struct _MDNotified notified;     /* array of conditions notified */
194#ifdef PROFILE_LOCKS
195    PRInt32 hitcount;
196    PRInt32 misscount;
197#endif
198};
199
200struct _MDFileDesc {
201    PRInt32 osfd;    /* The osfd can come from one of three spaces:
202                      * - For stdin, stdout, and stderr, we are using
203                      *   the libc file handle (0, 1, 2), which is an int.
204                      * - For files and pipes, we are using OS/2 handles,
205                      *   which is a void*.
206                      * - For sockets, we are using int
207                      */
208};
209
210struct _MDProcess {
211   PID pid;
212};
213
214/* --- Misc stuff --- */
215#define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
216
217/* --- IO stuff --- */
218
219#define _MD_OPEN                      (_PR_MD_OPEN)
220#define _MD_OPEN_FILE                 (_PR_MD_OPEN)
221#define _MD_READ                      (_PR_MD_READ)
222#define _MD_WRITE                     (_PR_MD_WRITE)
223#define _MD_WRITEV                    (_PR_MD_WRITEV)
224#define _MD_LSEEK                     (_PR_MD_LSEEK)
225#define _MD_LSEEK64                   (_PR_MD_LSEEK64)
226extern PRInt32 _MD_CloseFile(PRInt32 osfd);
227#define _MD_CLOSE_FILE                _MD_CloseFile
228#define _MD_GETFILEINFO               (_PR_MD_GETFILEINFO)
229#define _MD_GETFILEINFO64             (_PR_MD_GETFILEINFO64)
230#define _MD_GETOPENFILEINFO           (_PR_MD_GETOPENFILEINFO)
231#define _MD_GETOPENFILEINFO64         (_PR_MD_GETOPENFILEINFO64)
232#define _MD_STAT                      (_PR_MD_STAT)
233#define _MD_RENAME                    (_PR_MD_RENAME)
234#define _MD_ACCESS                    (_PR_MD_ACCESS)
235#define _MD_DELETE                    (_PR_MD_DELETE)
236#define _MD_MKDIR                     (_PR_MD_MKDIR)
237#define _MD_MAKE_DIR                  (_PR_MD_MKDIR)
238#define _MD_RMDIR                     (_PR_MD_RMDIR)
239#define _MD_LOCKFILE                  (_PR_MD_LOCKFILE)
240#define _MD_TLOCKFILE                 (_PR_MD_TLOCKFILE)
241#define _MD_UNLOCKFILE                (_PR_MD_UNLOCKFILE)
242
243/* --- Socket IO stuff --- */
244
245#define TCPV40HDRS
246#define BSD_SELECT
247
248/* The ones that don't map directly may need to be re-visited... */
249#ifdef XP_OS2_VACPP
250#define EPIPE                     EBADF
251#define EIO                       ECONNREFUSED
252#endif
253#define _MD_EACCES                EACCES
254#define _MD_EADDRINUSE            EADDRINUSE
255#define _MD_EADDRNOTAVAIL         EADDRNOTAVAIL
256#define _MD_EAFNOSUPPORT          EAFNOSUPPORT
257#define _MD_EAGAIN                EWOULDBLOCK
258#define _MD_EALREADY              EALREADY
259#define _MD_EBADF                 EBADF
260#define _MD_ECONNREFUSED          ECONNREFUSED
261#define _MD_ECONNRESET            ECONNRESET
262#define _MD_EFAULT                SOCEFAULT
263#define _MD_EINPROGRESS           EINPROGRESS
264#define _MD_EINTR                 EINTR
265#define _MD_EINVAL                EINVAL
266#define _MD_EISCONN               EISCONN
267#define _MD_ENETUNREACH           ENETUNREACH
268#define _MD_ENOENT                ENOENT
269#define _MD_ENOTCONN              ENOTCONN
270#define _MD_ENOTSOCK              ENOTSOCK
271#define _MD_EOPNOTSUPP            EOPNOTSUPP
272#define _MD_EWOULDBLOCK           EWOULDBLOCK
273#define _MD_GET_SOCKET_ERROR()    sock_errno()
274#ifndef INADDR_LOOPBACK /* For some reason this is not defined in OS2 tcpip */
275/*  #define INADDR_LOOPBACK         INADDR_ANY */
276#endif
277
278#define _MD_INIT_FILEDESC(fd)
279extern void _MD_MakeNonblock(PRFileDesc *f);
280#define _MD_MAKE_NONBLOCK             _MD_MakeNonblock
281#define _MD_INIT_FD_INHERITABLE       (_PR_MD_INIT_FD_INHERITABLE)
282#define _MD_QUERY_FD_INHERITABLE      (_PR_MD_QUERY_FD_INHERITABLE)
283#define _MD_SHUTDOWN                  (_PR_MD_SHUTDOWN)
284#define _MD_LISTEN                    _PR_MD_LISTEN
285extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
286#define _MD_CLOSE_SOCKET              _MD_CloseSocket
287#define _MD_SENDTO                    (_PR_MD_SENDTO)
288#define _MD_RECVFROM                  (_PR_MD_RECVFROM)
289#define _MD_SOCKETPAIR                (_PR_MD_SOCKETPAIR)
290#define _MD_GETSOCKNAME               (_PR_MD_GETSOCKNAME)
291#define _MD_GETPEERNAME               (_PR_MD_GETPEERNAME)
292#define _MD_GETSOCKOPT                (_PR_MD_GETSOCKOPT)
293#define _MD_SETSOCKOPT                (_PR_MD_SETSOCKOPT)
294
295#define _MD_FSYNC                     _PR_MD_FSYNC
296#define _MD_SET_FD_INHERITABLE        (_PR_MD_SET_FD_INHERITABLE)
297
298#ifdef _PR_HAVE_ATOMIC_OPS
299#define _MD_INIT_ATOMIC()
300#define _MD_ATOMIC_INCREMENT          _PR_MD_ATOMIC_INCREMENT
301#define _MD_ATOMIC_ADD                _PR_MD_ATOMIC_ADD
302#define _MD_ATOMIC_DECREMENT          _PR_MD_ATOMIC_DECREMENT
303#define _MD_ATOMIC_SET                _PR_MD_ATOMIC_SET
304#endif
305
306#define _MD_INIT_IO                   (_PR_MD_INIT_IO)
307#define _MD_PR_POLL                   (_PR_MD_PR_POLL)
308
309#define _MD_SOCKET                    (_PR_MD_SOCKET)
310extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd);
311#define _MD_SOCKETAVAILABLE           _MD_SocketAvailable
312#define _MD_PIPEAVAILABLE             _MD_SocketAvailable
313#define _MD_CONNECT                   (_PR_MD_CONNECT)
314extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
315        PRIntervalTime timeout);
316#define _MD_ACCEPT                    _MD_Accept
317#define _MD_BIND                      (_PR_MD_BIND)
318#define _MD_RECV                      (_PR_MD_RECV)
319#define _MD_SEND                      (_PR_MD_SEND)
320
321/* --- Scheduler stuff --- */
322/* #define _MD_PAUSE_CPU                 _PR_MD_PAUSE_CPU */
323#define _MD_PAUSE_CPU
324
325/* --- DIR stuff --- */
326#define PR_DIRECTORY_SEPARATOR        '\\'
327#define PR_DIRECTORY_SEPARATOR_STR    "\\"
328#define PR_PATH_SEPARATOR		';'
329#define PR_PATH_SEPARATOR_STR		";"
330#define _MD_ERRNO()                   errno
331#define _MD_OPEN_DIR                  (_PR_MD_OPEN_DIR)
332#define _MD_CLOSE_DIR                 (_PR_MD_CLOSE_DIR)
333#define _MD_READ_DIR                  (_PR_MD_READ_DIR)
334
335/* --- Segment stuff --- */
336#define _MD_INIT_SEGS()
337#define _MD_ALLOC_SEGMENT(seg, size, vaddr)   0
338#define _MD_FREE_SEGMENT(seg)
339
340/* --- Environment Stuff --- */
341#define _MD_GET_ENV                 (_PR_MD_GET_ENV)
342#define _MD_PUT_ENV                 (_PR_MD_PUT_ENV)
343
344/* --- Threading Stuff --- */
345#define _MD_DEFAULT_STACK_SIZE      65536L
346#define _MD_INIT_THREAD             (_PR_MD_INIT_THREAD)
347#define _MD_INIT_ATTACHED_THREAD    (_PR_MD_INIT_THREAD)
348#define _MD_CREATE_THREAD           (_PR_MD_CREATE_THREAD)
349#define _MD_YIELD                   (_PR_MD_YIELD)
350#define _MD_SET_PRIORITY            (_PR_MD_SET_PRIORITY)
351#define _MD_CLEAN_THREAD            (_PR_MD_CLEAN_THREAD)
352#define _MD_SETTHREADAFFINITYMASK   (_PR_MD_SETTHREADAFFINITYMASK)
353#define _MD_GETTHREADAFFINITYMASK   (_PR_MD_GETTHREADAFFINITYMASK)
354#define _MD_EXIT_THREAD             (_PR_MD_EXIT_THREAD)
355#define _MD_SUSPEND_THREAD          (_PR_MD_SUSPEND_THREAD)
356#define _MD_RESUME_THREAD           (_PR_MD_RESUME_THREAD)
357#define _MD_SUSPEND_CPU             (_PR_MD_SUSPEND_CPU)
358#define _MD_RESUME_CPU              (_PR_MD_RESUME_CPU)
359#define _MD_WAKEUP_CPUS             (_PR_MD_WAKEUP_CPUS)
360#define _MD_BEGIN_SUSPEND_ALL()
361#define _MD_BEGIN_RESUME_ALL()
362#define _MD_END_SUSPEND_ALL()
363#define _MD_END_RESUME_ALL()
364
365/* --- Lock stuff --- */
366#define _PR_LOCK                      _MD_LOCK
367#define _PR_UNLOCK					  _MD_UNLOCK
368
369#ifdef USE_RAMSEM
370#define _MD_NEW_LOCK                  (_PR_MD_NEW_LOCK)
371#define _MD_FREE_LOCK(lock)           (DosCloseEventSem(((PRAMSEM)(&((lock)->mutex)))->hevSem))
372#define _MD_LOCK(lock)                (SemRequest486(&((lock)->mutex), -1))
373#define _MD_TEST_AND_LOCK(lock)       (SemRequest486(&((lock)->mutex), -1),0)
374#define _MD_UNLOCK(lock)              \
375    PR_BEGIN_MACRO \
376    if (0 != (lock)->notified.length) { \
377        md_UnlockAndPostNotifies((lock), NULL, NULL); \
378    } else { \
379        SemReleasex86( &(lock)->mutex, 0 ); \
380    } \
381    PR_END_MACRO
382#else
383#define _MD_NEW_LOCK                  (_PR_MD_NEW_LOCK)
384#define _MD_FREE_LOCK(lock)           (DosCloseMutexSem((lock)->mutex))
385#define _MD_LOCK(lock)                (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT))
386#define _MD_TEST_AND_LOCK(lock)       (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT),0)
387#define _MD_UNLOCK(lock)              \
388    PR_BEGIN_MACRO \
389    if (0 != (lock)->notified.length) { \
390        md_UnlockAndPostNotifies((lock), NULL, NULL); \
391    } else { \
392        DosReleaseMutexSem((lock)->mutex); \
393    } \
394    PR_END_MACRO
395#endif
396
397/* --- lock and cv waiting --- */
398#define _MD_WAIT                      (_PR_MD_WAIT)
399#define _MD_WAKEUP_WAITER             (_PR_MD_WAKEUP_WAITER)
400
401/* --- CVar ------------------- */
402#define _MD_WAIT_CV					  (_PR_MD_WAIT_CV)
403#define _MD_NEW_CV					  (_PR_MD_NEW_CV)
404#define _MD_FREE_CV					  (_PR_MD_FREE_CV)
405#define _MD_NOTIFY_CV				  (_PR_MD_NOTIFY_CV	)
406#define _MD_NOTIFYALL_CV			  (_PR_MD_NOTIFYALL_CV)
407
408   /* XXXMB- the IOQ stuff is certainly not working correctly yet. */
409/* extern  struct _MDLock              _pr_ioq_lock; */
410#define _MD_IOQ_LOCK()
411#define _MD_IOQ_UNLOCK()
412
413
414/* --- Initialization stuff --- */
415#define _MD_START_INTERRUPTS()
416#define _MD_STOP_INTERRUPTS()
417#define _MD_DISABLE_CLOCK_INTERRUPTS()
418#define _MD_ENABLE_CLOCK_INTERRUPTS()
419#define _MD_BLOCK_CLOCK_INTERRUPTS()
420#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
421#define _MD_EARLY_INIT                (_PR_MD_EARLY_INIT)
422#define _MD_FINAL_INIT()
423#define _MD_INIT_CPUS()
424#define _MD_INIT_RUNNING_CPU(cpu)
425
426struct PRProcess;
427struct PRProcessAttr;
428
429#define _MD_CREATE_PROCESS _PR_CreateOS2Process
430extern struct PRProcess * _PR_CreateOS2Process(
431    const char *path,
432    char *const *argv,
433    char *const *envp,
434    const struct PRProcessAttr *attr
435);
436
437#define _MD_DETACH_PROCESS _PR_DetachOS2Process
438extern PRStatus _PR_DetachOS2Process(struct PRProcess *process);
439
440/* --- Wait for a child process to terminate --- */
441#define _MD_WAIT_PROCESS _PR_WaitOS2Process
442extern PRStatus _PR_WaitOS2Process(struct PRProcess *process,
443    PRInt32 *exitCode);
444
445#define _MD_KILL_PROCESS _PR_KillOS2Process
446extern PRStatus _PR_KillOS2Process(struct PRProcess *process);
447
448#define _MD_CLEANUP_BEFORE_EXIT()
449#define _MD_EXIT                          (_PR_MD_EXIT)
450#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
451    PR_BEGIN_MACRO \
452    *status = PR_TRUE; \
453    PR_END_MACRO
454#define _MD_SWITCH_CONTEXT
455#define _MD_RESTORE_CONTEXT
456
457/* --- Intervals --- */
458#define _MD_INTERVAL_INIT                 (_PR_MD_INTERVAL_INIT)
459#define _MD_GET_INTERVAL                  (_PR_MD_GET_INTERVAL)
460#define _MD_INTERVAL_PER_SEC              (_PR_MD_INTERVAL_PER_SEC)
461#define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
462#define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
463
464/* --- Native-Thread Specific Definitions ------------------------------- */
465
466typedef struct __NSPR_TLS
467{
468    struct PRThread  *_pr_thread_last_run;
469    struct PRThread  *_pr_currentThread;
470    struct _PRCPU    *_pr_currentCPU;
471} _NSPR_TLS;
472
473extern _NSPR_TLS*  pThreadLocalStorage;
474NSPR_API(void) _PR_MD_ENSURE_TLS(void);
475
476#define _MD_GET_ATTACHED_THREAD() pThreadLocalStorage->_pr_currentThread
477extern struct PRThread * _MD_CURRENT_THREAD(void);
478#define _MD_SET_CURRENT_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentThread = (_thread)
479
480#define _MD_LAST_THREAD() pThreadLocalStorage->_pr_thread_last_run
481#define _MD_SET_LAST_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_thread_last_run = (_thread)
482
483#define _MD_CURRENT_CPU() pThreadLocalStorage->_pr_currentCPU
484#define _MD_SET_CURRENT_CPU(_cpu) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentCPU = (_cpu)
485
486/* lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val)) */
487/* lth. #define _MD_GET_INTSOFF() _pr_ints_off */
488/* lth. #define _MD_INCREMENT_INTSOFF() (_pr_ints_off++) */
489/* lth. #define _MD_DECREMENT_INTSOFF() (_pr_ints_off--) */
490
491/* --- Scheduler stuff --- */
492#define LOCK_SCHEDULER()                 0
493#define UNLOCK_SCHEDULER()               0
494#define _PR_LockSched()                	 0
495#define _PR_UnlockSched()                0
496
497/* --- Initialization stuff --- */
498#define _MD_INIT_LOCKS()
499
500/* --- Stack stuff --- */
501#define _MD_INIT_STACK(stack, redzone)
502#define _MD_CLEAR_STACK(stack)
503
504/* --- Memory-mapped files stuff --- not implemented on OS/2 */
505
506struct _MDFileMap {
507    PRInt8 unused;
508};
509
510extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
511#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
512
513extern PRInt32 _MD_GetMemMapAlignment(void);
514#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
515
516extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
517        PRUint32 len);
518#define _MD_MEM_MAP _MD_MemMap
519
520extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
521#define _MD_MEM_UNMAP _MD_MemUnmap
522
523extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
524#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
525
526/* Some stuff for setting up thread contexts */
527typedef ULONG DWORD, *PDWORD;
528
529/* The following definitions and two structures are new in OS/2 Warp 4.0.
530 */
531#ifndef CONTEXT_CONTROL
532#define CONTEXT_CONTROL        0x00000001
533#define CONTEXT_INTEGER        0x00000002
534#define CONTEXT_SEGMENTS       0x00000004
535#define CONTEXT_FLOATING_POINT 0x00000008
536#define CONTEXT_FULL           0x0000000F
537
538#pragma pack(2)
539typedef struct _FPREG {
540    ULONG      losig;    /*  Low 32-bits of the significand. */
541    ULONG      hisig;    /*  High 32-bits of the significand. */
542    USHORT     signexp;  /*  Sign and exponent. */
543} FPREG;
544typedef struct _CONTEXTRECORD {
545    ULONG     ContextFlags;
546    ULONG     ctx_env[7];
547    FPREG     ctx_stack[8];
548    ULONG     ctx_SegGs;     /*  GS register. */
549    ULONG     ctx_SegFs;     /*  FS register. */
550    ULONG     ctx_SegEs;     /*  ES register. */
551    ULONG     ctx_SegDs;     /*  DS register. */
552    ULONG     ctx_RegEdi;    /*  EDI register. */
553    ULONG     ctx_RegEsi;    /*  ESI register. */
554    ULONG     ctx_RegEax;    /*  EAX register. */
555    ULONG     ctx_RegEbx;    /*  EBX register. */
556    ULONG     ctx_RegEcx;    /*  ECX register. */
557    ULONG     ctx_RegEdx;    /*  EDX register. */
558    ULONG     ctx_RegEbp;    /*  EBP register. */
559    ULONG     ctx_RegEip;    /*  EIP register. */
560    ULONG     ctx_SegCs;     /*  CS register. */
561    ULONG     ctx_EFlags;    /*  EFLAGS register. */
562    ULONG     ctx_RegEsp;    /*  ESP register. */
563    ULONG     ctx_SegSs;     /*  SS register. */
564} CONTEXTRECORD, *PCONTEXTRECORD;
565#pragma pack()
566#endif
567
568extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
569unsigned long _System _DLL_InitTerm( unsigned long mod_handle, unsigned long flag);
570
571/*
572#define _pr_tid            (((PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)))->tib2_ultid)
573#define _pr_current_Thread (_system_tls[_pr_tid-1].__pr_current_thread)
574*/
575
576/* Some simple mappings of Windows API's to OS/2 API's to make our lives a
577 * little bit easier.  Only add one here if it is a DIRECT mapping.  We are
578 * not emulating anything.  Just mapping.
579 */
580#define FreeLibrary(x) DosFreeModule((HMODULE)x)
581#define OutputDebugString(x)
582
583extern int _MD_os2_get_nonblocking_connect_error(int osfd);
584
585#endif /* nspr_os2_defs_h___ */
586