Index: trunk/src/odincrt/critsect.cpp
===================================================================
--- trunk/src/odincrt/critsect.cpp	(revision 8201)
+++ trunk/src/odincrt/critsect.cpp	(revision 8201)
@@ -0,0 +1,192 @@
+/* $Id: critsect.cpp,v 1.1 2002-04-07 14:35:24 sandervl Exp $ */
+/*
+ * Critical sections
+ * 
+ * Copyright 2002 Sander van Leeuwen (sandervl@xs4all.nl) 
+ * OS/2 port
+ *
+ * Based on Wine code
+ *
+ * Copyright 1998 Alexandre Julliard (991031 Port)
+ *
+ *
+ */
+#define INCL_DOSPROCESS
+#define INCL_DOSERRORS
+#define INCL_DOSSEMAPHORES
+#include <os2wrap.h>
+#include <win32type.h>
+#include <win32api.h>
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <odincrt.h>
+
+#ifdef DEBUG
+#define DebugInt3()	_interrupt(3)
+#else
+#define DebugInt3()
+#endif
+
+#define MAKE_THREADID(processid, threadid) 	((processid << 16) | threadid)
+
+//******************************************************************************
+//******************************************************************************
+inline ULONG GetCurrentThreadId()
+{
+    PTIB   ptib;
+    PPIB   ppib;
+    APIRET rc;
+ 
+    rc = DosGetInfoBlocks(&ptib, &ppib);
+    if(rc == NO_ERROR) {
+        return MAKE_THREADID(ppib->pib_ulpid, ptib->tib_ptib2->tib2_ultid);
+    }
+    DebugInt3();
+    return 0;
+}
+//******************************************************************************
+//******************************************************************************
+inline ULONG GetCurrentProcessId()
+{
+    PTIB   ptib;
+    PPIB   ppib;
+    APIRET rc;
+ 
+    rc = DosGetInfoBlocks(&ptib, &ppib);
+    if(rc == NO_ERROR) {
+        return ppib->pib_ulpid;
+    }
+    DebugInt3();
+    return 0;
+}
+
+/***********************************************************************
+ *           DosInitializeCriticalSection
+ */
+VOID WIN32API DosInitializeCriticalSection(CRITICAL_SECTION_OS2 *crit, PSZ pszSemName)
+{
+    APIRET rc;
+
+    crit->LockCount      = -1;
+    crit->RecursionCount = 0;
+    crit->OwningThread   = 0;
+
+    rc = DosCreateMutexSem(pszSemName, &crit->hmtxLock, DC_SEM_SHARED, FALSE);
+    if(rc != NO_ERROR) {
+        DebugInt3();
+        crit->hmtxLock = 0;
+    }
+    crit->Reserved       = GetCurrentProcessId();
+}
+
+
+/***********************************************************************
+ *           DosAccessCriticalSection
+ */
+VOID WIN32API DosAccessCriticalSection(CRITICAL_SECTION_OS2 *, PSZ pszSemName)
+{
+    HMTX   hmtxLock = 0;
+    APIRET rc;
+
+    if(pszSemName == NULL) {
+        DebugInt3();
+        return;
+    }
+
+    rc = DosOpenMutexSem(pszSemName, &hmtxLock);
+    if(rc != NO_ERROR) {
+        DebugInt3();
+    }
+}
+/***********************************************************************
+ *           DosDeleteCriticalSection
+ */
+void WIN32API DosDeleteCriticalSection( CRITICAL_SECTION_OS2 *crit )
+{
+    if (crit->hmtxLock)
+    {
+        if (crit->RecursionCount)  /* Should not happen */
+        {
+           DebugInt3();
+        }
+        crit->LockCount      = -1;
+        crit->RecursionCount = 0;
+        crit->OwningThread   = 0;
+        DosCloseMutexSem(crit->hmtxLock);
+        crit->hmtxLock       = 0;
+        crit->Reserved       = (DWORD)-1;
+    }
+}
+
+
+/***********************************************************************
+ *           DosEnterCriticalSection
+ */
+void WIN32API DosEnterCriticalSection( CRITICAL_SECTION_OS2 *crit )
+{
+    DWORD res;
+
+    if (!crit->hmtxLock)
+    {
+    	DosInitializeCriticalSection(crit, NULL);
+    }
+    if (DosInterlockedIncrement( &crit->LockCount ))
+    {
+        if (crit->OwningThread == GetCurrentThreadId())
+        {
+            crit->RecursionCount++;
+            return;
+        }
+
+        /* Now wait for it */
+        APIRET rc = DosRequestMutexSem(crit->hmtxLock, SEM_INDEFINITE_WAIT);
+    }
+    crit->OwningThread   = GetCurrentThreadId();
+    crit->RecursionCount = 1;
+}
+
+
+/***********************************************************************
+ *           DosTryEnterCriticalSection
+ */
+BOOL WIN32API DosTryEnterCriticalSection( CRITICAL_SECTION_OS2 *crit )
+{
+    if (DosInterlockedIncrement( &crit->LockCount ))
+    {
+        if (crit->OwningThread == GetCurrentThreadId())
+        {
+            crit->RecursionCount++;
+            return TRUE;
+        }
+        /* FIXME: this doesn't work */
+        DosInterlockedDecrement( &crit->LockCount );
+        return FALSE;
+    }
+    crit->OwningThread   = GetCurrentThreadId();
+    crit->RecursionCount = 1;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           DosLeaveCriticalSection
+ */
+void WIN32API DosLeaveCriticalSection( CRITICAL_SECTION_OS2 *crit )
+{
+    if (crit->OwningThread != GetCurrentThreadId()) return;
+       
+    if (--crit->RecursionCount)
+    {
+        DosInterlockedDecrement( &crit->LockCount );
+        return;
+    }
+    crit->OwningThread = 0;
+    if (DosInterlockedDecrement( &crit->LockCount ) >= 0)
+    {
+        /* Someone is waiting */
+        DosReleaseMutexSem(crit->hmtxLock);
+    }
+}
+
Index: trunk/src/odincrt/interlock.asm
===================================================================
--- trunk/src/odincrt/interlock.asm	(revision 8201)
+++ trunk/src/odincrt/interlock.asm	(revision 8201)
@@ -0,0 +1,127 @@
+; $Id: interlock.asm,v 1.1 2002-04-07 14:35:24 sandervl Exp $
+
+;/*
+; * Interlocked apis
+; *
+; * Copyright 1999 Sander van Leeuwen
+; * Copyright 1999 Patrick Haller
+; *
+; * Based on WINE code: win32\thread.c (990815)
+; *
+; * Copyright 1995 Martin von Loewis
+; * Copyright 1997 Onno Hovers
+; *
+; * Project Odin Software License can be found in LICENSE.TXT
+; *
+; */
+.586P
+               NAME    interlocked
+
+CODE32         SEGMENT DWORD PUBLIC USE32 'CODE'
+
+       public  _DosInterlockedIncrement@4
+
+;*           InterlockedIncrement			[KERNEL32]	*
+;*									*
+;* InterlockedIncrement adds 1 to a long variable and returns		*
+;*  -  a negative number if the result < 0				*
+;*  -  zero if the result == 0						*
+;*  -  a positive number if the result > 0				*
+;*									*
+;* The returned number need not be equal to the result!!!!		*
+
+_DosInterlockedIncrement@4 proc near
+        ;we are allowed to trash edx
+	mov	edx, dword ptr [esp+4] ; LPLONG lpAddend
+        mov     eax, 1
+	lock 	xadd dword ptr [edx], eax 
+        inc     eax
+      	ret     4
+_DosInterlockedIncrement@4 endp
+
+       public  _DosInterlockedDecrement@4
+
+;*           InterlockedDecrement			[KERNEL32]	*
+;*									*
+;* InterlockedIncrement adds 1 to a long variable and returns		*
+;*  -  a negative number if the result < 0				*
+;*  -  zero if the result == 0						*
+;*  -  a positive number if the result > 0				*
+;*									*
+;* The returned number need not be equal to the result!!!!		*
+
+_DosInterlockedDecrement@4 proc near
+        ;we are allowed to trash edx
+	mov	edx, dword ptr [esp+4] ; LPLONG lpAddend
+        mov     eax, -1
+	lock 	xadd dword ptr [edx], eax
+        dec     eax
+        ret     4
+_DosInterlockedDecrement@4 endp
+
+
+       public  _DosInterlockedExchange@8
+; *           InterlockedExchange				[KERNEL32.???]
+; *
+; * Atomically exchanges a pair of values.
+; *
+; * RETURNS
+; *	Prior value of value pointed to by Target
+
+_DosInterlockedExchange@8 proc near
+	push	edx			
+	mov	eax, [esp+12]        	; LONG value
+        mov     edx,[esp+8]           	; LPLONG target
+  	lock 	xchg eax, dword ptr [edx]
+	pop	edx
+       	ret 	8
+_DosInterlockedExchange@8 endp
+
+
+
+		public _DosInterlockedCompareExchange@12
+;/************************************************************************
+; *           InterlockedCompareExchange		[KERNEL32.879]
+; *
+; * Atomically compares Destination and Comperand, and if found equal exchanges
+; * the value of Destination with Exchange
+; *
+; */
+_DosInterlockedCompareExchange@12 proc near
+	push	ebp
+	mov	ebp, esp
+	push	edx
+	push	ebx
+
+	mov	ebx, dword ptr [ebp+8]  ;PVOID *Destination, /* Address of 32-bit value to exchange */
+	mov	eax, [ebp+16]		;PVOID Comperand      /* value to compare, 32 bits */
+	mov	edx, [ebp+12]   	;PVOID Exchange,      /* change value, 32 bits */
+	lock	cmpxchg dword ptr [ebx],edx
+
+	pop	ebx
+	pop	edx
+	pop	ebp
+	ret	12
+_DosInterlockedCompareExchange@12 endp
+
+		public _DosInterlockedExchangeAdd@8
+; *           InterlockedExchangeAdd			[KERNEL32.880]
+; *
+; * Atomically adds Increment to Addend and returns the previous value of
+; * Addend
+; *
+; * RETURNS
+; *	Prior value of value pointed to by cwAddendTarget
+; */
+_DosInterlockedExchangeAdd@8 proc near
+	push	edx
+	mov	eax, dword ptr [esp+12] ;LONG Increment /* Value to add */
+	mov	edx, dword ptr [esp+8]	;PLONG Addend, /* Address of 32-bit value to exchange */
+	lock	xadd dword ptr [edx], eax
+	pop	edx
+	ret 	8
+_DosInterlockedExchangeAdd@8 endp
+
+CODE32          ENDS
+
+                END
Index: trunk/src/odincrt/makefile
===================================================================
--- trunk/src/odincrt/makefile	(revision 8198)
+++ trunk/src/odincrt/makefile	(revision 8201)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.25 2001-11-22 10:41:43 phaller Exp $
+# $Id: makefile,v 1.26 2002-04-07 14:35:24 sandervl Exp $
 
 #
@@ -66,5 +66,7 @@
 $(OBJDIR)\malloc.obj \
 $(OBJDIR)\string.obj \
-$(OBJDIR)\file.obj
+$(OBJDIR)\file.obj \
+$(OBJDIR)\critsect.obj \
+$(OBJDIR)\interlock.obj \
 !else
 !ifdef NMAKE
Index: trunk/src/odincrt/odin36.def
===================================================================
--- trunk/src/odincrt/odin36.def	(revision 8198)
+++ trunk/src/odincrt/odin36.def	(revision 8201)
@@ -1,3 +1,3 @@
-; $Id: odin36.def,v 1.4 2001-07-20 15:40:29 sandervl Exp $
+; $Id: odin36.def,v 1.5 2002-04-07 14:35:25 sandervl Exp $
 ; Odin VAC++ 3.6.5 shared multithreaded runtime
 LIBRARY ODINCRT INITINSTANCE TERMINSTANCE
@@ -976,2 +976,13 @@
     __divi64                                           @1031 NONAME
     __divu64                                           @1032 NONAME
+
+    _DosDeleteCriticalSection@4                        @1200 NONAME
+    _DosEnterCriticalSection@4                         @1201 NONAME
+    _DosInitializeCriticalSection@8                    @1202 NONAME
+    _DosAccessCriticalSection@8                        @1203 NONAME
+    _DosLeaveCriticalSection@4                         @1204 NONAME
+    _DosInterlockedCompareExchange@12                  @1205 NONAME
+    _DosInterlockedDecrement@4                         @1206 NONAME
+    _DosInterlockedExchange@8                          @1207 NONAME
+    _DosInterlockedExchangeAdd@8                       @1208 NONAME
+    _DosInterlockedIncrement@4                         @1209 NONAME
Index: trunk/src/odincrt/odin36d.def
===================================================================
--- trunk/src/odincrt/odin36d.def	(revision 8198)
+++ trunk/src/odincrt/odin36d.def	(revision 8201)
@@ -1,3 +1,3 @@
-; $Id: odin36d.def,v 1.4 2001-07-20 15:40:30 sandervl Exp $
+; $Id: odin36d.def,v 1.5 2002-04-07 14:35:25 sandervl Exp $
 ; Odin VAC++ 3.6.5 shared multithreaded runtime
 LIBRARY ODINCRTD INITINSTANCE TERMINSTANCE
@@ -984,2 +984,13 @@
     __divi64                                           @1031 NONAME
     __divu64                                           @1032 NONAME
+
+    _DosDeleteCriticalSection@4                        @1200 NONAME
+    _DosEnterCriticalSection@4                         @1201 NONAME
+    _DosInitializeCriticalSection@8                    @1202 NONAME
+    _DosAccessCriticalSection@8                        @1203 NONAME
+    _DosLeaveCriticalSection@4                         @1204 NONAME
+    _DosInterlockedCompareExchange@12                  @1205 NONAME
+    _DosInterlockedDecrement@4                         @1206 NONAME
+    _DosInterlockedExchange@8                          @1207 NONAME
+    _DosInterlockedExchangeAdd@8                       @1208 NONAME
+    _DosInterlockedIncrement@4                         @1209 NONAME
Index: trunk/src/odincrt/odincrt.def
===================================================================
--- trunk/src/odincrt/odincrt.def	(revision 8198)
+++ trunk/src/odincrt/odincrt.def	(revision 8201)
@@ -1,3 +1,3 @@
-; $Id: odincrt.def,v 1.24 2001-07-20 15:40:30 sandervl Exp $
+; $Id: odincrt.def,v 1.25 2002-04-07 14:35:25 sandervl Exp $
 ; Odin VAC++ 3.08 shared multithreaded runtime
 LIBRARY ODINCRT INITINSTANCE TERMINSTANCE
@@ -954,2 +954,13 @@
     __divi64                                           @1031 NONAME
     __divu64                                           @1032 NONAME
+
+    _DosDeleteCriticalSection@4                        @1200 NONAME
+    _DosEnterCriticalSection@4                         @1201 NONAME
+    _DosInitializeCriticalSection@8                    @1202 NONAME
+    _DosAccessCriticalSection@8                        @1203 NONAME
+    _DosLeaveCriticalSection@4                         @1204 NONAME
+    _DosInterlockedCompareExchange@12                  @1205 NONAME
+    _DosInterlockedDecrement@4                         @1206 NONAME
+    _DosInterlockedExchange@8                          @1207 NONAME
+    _DosInterlockedExchangeAdd@8                       @1208 NONAME
+    _DosInterlockedIncrement@4                         @1209 NONAME
Index: trunk/src/odincrt/odincrtd.def
===================================================================
--- trunk/src/odincrt/odincrtd.def	(revision 8198)
+++ trunk/src/odincrt/odincrtd.def	(revision 8201)
@@ -1,3 +1,3 @@
-; $Id: odincrtd.def,v 1.5 2001-12-13 15:32:17 sandervl Exp $
+; $Id: odincrtd.def,v 1.6 2002-04-07 14:35:26 sandervl Exp $
 ; Odin VAC++ 3.08 shared multithreaded runtime
 LIBRARY ODINCRTD INITINSTANCE TERMINSTANCE
@@ -956,2 +956,13 @@
 
     getcrtstat                                         @1033 NONAME
+
+    _DosDeleteCriticalSection@4                        @1200 NONAME
+    _DosEnterCriticalSection@4                         @1201 NONAME
+    _DosInitializeCriticalSection@8                    @1202 NONAME
+    _DosAccessCriticalSection@8                        @1203 NONAME
+    _DosLeaveCriticalSection@4                         @1204 NONAME
+    _DosInterlockedCompareExchange@12                  @1205 NONAME
+    _DosInterlockedDecrement@4                         @1206 NONAME
+    _DosInterlockedExchange@8                          @1207 NONAME
+    _DosInterlockedExchangeAdd@8                       @1208 NONAME
+    _DosInterlockedIncrement@4                         @1209 NONAME
Index: trunk/src/odincrt/odincrtp.def
===================================================================
--- trunk/src/odincrt/odincrtp.def	(revision 8198)
+++ trunk/src/odincrt/odincrtp.def	(revision 8201)
@@ -1,3 +1,3 @@
-; $Id: odincrtp.def,v 1.2 2001-12-19 09:37:24 phaller Exp $
+; $Id: odincrtp.def,v 1.3 2002-04-07 14:35:26 sandervl Exp $
 ; Odin VAC++ 3.08 shared multithreaded runtime
 LIBRARY ODINCRTP INITINSTANCE TERMINSTANCE
@@ -977,2 +977,13 @@
     ProfilerWrite                                    @1103 NONAME
     ProfilerTerminate                                @1104 NONAME
+
+    _DosDeleteCriticalSection@4                        @1200 NONAME
+    _DosEnterCriticalSection@4                         @1201 NONAME
+    _DosInitializeCriticalSection@8                    @1202 NONAME
+    _DosAccessCriticalSection@8                        @1203 NONAME
+    _DosLeaveCriticalSection@4                         @1204 NONAME
+    _DosInterlockedCompareExchange@12                  @1205 NONAME
+    _DosInterlockedDecrement@4                         @1206 NONAME
+    _DosInterlockedExchange@8                          @1207 NONAME
+    _DosInterlockedExchangeAdd@8                       @1208 NONAME
+    _DosInterlockedIncrement@4                         @1209 NONAME
