From 0d83083f943f949cd92e8bc4de1ed5a793df9b83 Mon Sep 17 00:00:00 2001
From: rpj <rpj>
Date: Tue, 29 Jun 2004 07:28:39 +0000
Subject: Borland toolchain compatibilty

---
 Bmakefile                          | 250 +++++++++++++++++++++++++++++++++++++
 CONTRIBUTORS                       |   5 +-
 ChangeLog                          |   7 ++
 README.Borland                     |  46 +++++++
 ptw32_InterlockedCompareExchange.c |  21 +++-
 5 files changed, 326 insertions(+), 3 deletions(-)
 create mode 100644 Bmakefile
 create mode 100644 README.Borland

diff --git a/Bmakefile b/Bmakefile
new file mode 100644
index 0000000..efd4e66
--- /dev/null
+++ b/Bmakefile
@@ -0,0 +1,250 @@
+# This makefile is compatible with BCB make.  Use "make -fBMakefile" to compile.
+# 
+# The variables $DLLDEST and $LIBDEST hold the destination directories for the
+# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
+
+DEVROOT=H:\libraries\pthreads-win32\pthreads
+
+DLLDEST=$(DEVROOT)\DLL
+LIBDEST=$(DEVROOT)\DLL
+
+DLLS	= pthreadBC.dll
+
+OPTIM	= /O2
+
+# most of the below flags are to provide compatibility with the MSC-orientated source:
+# borland uses EDEADLOCK, timeb, and ftime instead of EDEADLK, _timeb, and _ftime.
+# borland doesn't define ENOSYS in errno.h, so we define an arbitrary value for it here (we don't use ENOSYS in our client apps; if someone wants this, we could add a seperate case to the config & need_errno header files for it).
+
+CFLAGS	= /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H=1 /4 /tWM \
+	/DEDEADLK=EDEADLOCK /D_timeb=timeb /D_ftime=ftime \
+	/DENOSYS=140
+
+#C cleanup code
+BCFLAGS	= /D__CLEANUP_C $(CFLAGS)
+
+# Agregate modules for inlinability
+DLL_OBJS	= \
+		attr.obj \
+		barrier.obj \
+		cancel.obj \
+		cleanup.obj \
+		condvar.obj \
+		create.obj \
+		dll.obj \
+		errno.obj \
+		exit.obj \
+		fork.obj \
+		global.obj \
+		misc.obj \
+		mutex.obj \
+		nonportable.obj \
+		private.obj \
+		rwlock.obj \
+		sched.obj \
+		semaphore.obj \
+		signal.obj \
+		spin.obj \
+		sync.obj \
+		tsd.obj
+
+INCL	= config.h implement.h semaphore.h pthread.h need_errno.h
+
+ATTR_SRCS	= \
+		pthread_attr_init.c \
+		pthread_attr_destroy.c \
+		pthread_attr_getdetachstate.c \
+		pthread_attr_setdetachstate.c \
+		pthread_attr_getstackaddr.c \
+		pthread_attr_setstackaddr.c \
+		pthread_attr_getstacksize.c \
+		pthread_attr_setstacksize.c \
+		pthread_attr_getscope.c \
+		pthread_attr_setscope.c
+
+BARRIER_SRCS = \
+		pthread_barrier_init.c \
+		pthread_barrier_destroy.c \
+		pthread_barrier_wait.c \
+		pthread_barrierattr_init.c \
+		pthread_barrierattr_destroy.c \
+		pthread_barrierattr_setpshared.c \
+		pthread_barrierattr_getpshared.c
+
+CANCEL_SRCS	= \
+		pthread_setcancelstate.c \
+		pthread_setcanceltype.c \
+		pthread_testcancel.c \
+		pthread_cancel.c 
+
+CONDVAR_SRCS	= \
+		ptw32_cond_check_need_init.c \
+		pthread_condattr_destroy.c \
+		pthread_condattr_getpshared.c \
+		pthread_condattr_init.c \
+		pthread_condattr_setpshared.c \
+		pthread_cond_destroy.c \
+		pthread_cond_init.c \
+		pthread_cond_signal.c \
+		pthread_cond_wait.c
+
+EXIT_SRCS	= \
+		pthread_exit.c
+
+MISC_SRCS	= \
+		pthread_equal.c \
+		pthread_getconcurrency.c \
+		pthread_once.c \
+		pthread_self.c \
+		pthread_setconcurrency.c \
+		ptw32_calloc.c \
+		ptw32_new.c \
+		w32_CancelableWait.c
+
+MUTEX_SRCS	= \
+		ptw32_mutex_check_need_init.c \
+		pthread_mutex_init.c \
+		pthread_mutex_destroy.c \
+		pthread_mutexattr_init.c \
+		pthread_mutexattr_destroy.c \
+		pthread_mutexattr_getpshared.c \
+		pthread_mutexattr_setpshared.c \
+		pthread_mutexattr_settype.c \
+		pthread_mutexattr_gettype.c \
+		pthread_mutex_lock.c \
+		pthread_mutex_timedlock.c \
+		pthread_mutex_unlock.c \
+		pthread_mutex_trylock.c
+
+NONPORTABLE_SRCS = \
+		pthread_mutexattr_setkind_np.c \
+		pthread_mutexattr_getkind_np.c \
+		pthread_getw32threadhandle_np.c \
+		pthread_delay_np.c \
+		pthread_num_processors_np.c \
+		pthread_win32_attach_detach_np.c \
+		pthread_timechange_handler_np.c 
+
+PRIVATE_SRCS	= \
+		ptw32_is_attr.c \
+		ptw32_processInitialize.c \
+		ptw32_processTerminate.c \
+		ptw32_threadStart.c \
+		ptw32_threadDestroy.c \
+		ptw32_tkAssocCreate.c \
+		ptw32_tkAssocDestroy.c \
+		ptw32_callUserDestroyRoutines.c \
+		ptw32_timespec.c \
+		ptw32_throw.c \
+		ptw32_InterlockedCompareExchange.c \
+		ptw32_getprocessors.c
+
+RWLOCK_SRCS	= \
+		ptw32_rwlock_check_need_init.c \
+		ptw32_rwlock_cancelwrwait.c \
+		pthread_rwlock_init.c \
+		pthread_rwlock_destroy.c \
+		pthread_rwlockattr_init.c \
+		pthread_rwlockattr_destroy.c \
+		pthread_rwlockattr_getpshared.c \
+		pthread_rwlockattr_setpshared.c \
+		pthread_rwlock_rdlock.c \
+		pthread_rwlock_timedrdlock.c \
+		pthread_rwlock_wrlock.c \
+		pthread_rwlock_timedwrlock.c \
+		pthread_rwlock_unlock.c \
+		pthread_rwlock_tryrdlock.c \
+		pthread_rwlock_trywrlock.c
+
+SCHED_SRCS	= \
+		pthread_attr_setschedpolicy.c \
+		pthread_attr_getschedpolicy.c \
+		pthread_attr_setschedparam.c \
+		pthread_attr_getschedparam.c \
+		pthread_attr_setinheritsched.c \
+		pthread_attr_getinheritsched.c \
+		pthread_setschedparam.c \
+		pthread_getschedparam.c \
+		sched_get_priority_max.c \
+		sched_get_priority_min.c \
+		sched_setscheduler.c \
+		sched_getscheduler.c \
+		sched_yield.c
+
+SEMAPHORE_SRCS = \
+		sem_init.c \
+		sem_destroy.c \
+		sem_trywait.c \
+		sem_timedwait.c \
+		sem_wait.c \
+		sem_post.c \
+		sem_post_multiple.c \
+		sem_getvalue.c \
+		sem_open.c \
+		sem_close.c \
+		sem_unlink.c \
+		ptw32_increase_semaphore.c \
+		ptw32_decrease_semaphore.c
+
+SPIN_SRCS	= \
+		ptw32_spinlock_check_need_init.c \
+		pthread_spin_init.c \
+		pthread_spin_destroy.c \
+		pthread_spin_lock.c \
+		pthread_spin_unlock.c \
+		pthread_spin_trylock.c
+
+SYNC_SRCS	= \
+		pthread_detach.c \
+		pthread_join.c
+
+TSD_SRCS	= \
+		pthread_key_create.c \
+		pthread_key_delete.c \
+		pthread_setspecific.c \
+		pthread_getspecific.c
+
+
+all: clean $(DLLS)
+
+realclean: clean
+	if exist *.dll del *.dll
+	if exist *.lib del *.lib
+	if exist *.stamp del *.stamp
+
+clean:
+	if exist *.obj del *.obj
+	if exist *.ilk del *.ilk
+	if exist *.pdb del *.pdb
+	if exist *.exp del *.exp
+	if exist *.o del *.o
+	if exist *.i del *.i
+
+
+install: $(DLLS)
+	copy pthread*.dll $(DLLDEST)
+	copy pthread*.lib $(LIBDEST)
+
+$(DLLS): $(DLL_OBJS)
+	ilink32 /Tpd /Gi $(DLL_OBJS), \
+		$@, ,\
+		import32.lib cw32mt.lib c0d32x.obj
+
+.c.obj:
+	bcc32 $(OPTIM) $(BCFLAGS) -c $<
+
+attr.obj:	attr.c $(ATTR_SRCS) $(INCL)
+barrier.obj:	barrier.c $(BARRIER_SRCS) $(INCL)
+cancel.obj:	cancel.c $(CANCEL_SRCS) $(INCL)
+condvar.obj:	condvar.c $(CONDVAR_SRCS) $(INCL)
+exit.obj:	exit.c $(EXIT_SRCS) $(INCL)
+misc.obj:	misc.c $(MISC_SRCS) $(INCL)
+mutex.obj:	mutex.c $(MUTEX_SRCS) $(INCL)
+nonportable.obj:	nonportable.c $(NONPORTABLE_SRCS) $(INCL)
+private.obj:	private.c $(PRIVATE_SRCS) $(INCL)
+rwlock.obj:	rwlock.c $(RWLOCK_SRCS) $(INCL)
+sched.obj:	sched.c $(SCHED_SRCS) $(INCL)
+semaphore.obj:	semaphore.c $(SEMAPHORE_SRCS) $(INCL)
+spin.obj:	spin.c $(SPIN_SRCS) $(INCL)
+sync.obj:	sync.c $(SYNC_SRCS) $(INCL)
+tsd.obj:	tsd.c $(TSD_SRCS) $(INCL)
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 752d57a..de417df 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -108,6 +108,9 @@ Piet van Bruggen	pietvb at newbridges dot nl
 					Bug fix.
 Makoto Kato		raven at oldskool dot jp
 					AMD64 port.
-Panagiotis E. Hadjidoukas	peh at hpclab dot ceid dotupatras dot gr
+Panagiotis E. Hadjidoukas	peh at hpclab dot ceid dot upatras dot gr
 					Contributed the QueueUserAPCEx package which
 					makes preemptive async cancelation possible.
+
+Will Bryant			will dot bryant at ecosm dot com
+					Borland compiler patch and makefile.
diff --git a/ChangeLog b/ChangeLog
index 4131f64..e0dbb2f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-06-29  Will Bryant  <will.bryant at ecosm.com>
+
+	* README.Borland: New; description of Borland changes.
+	* Bmakefile: New makefile for the Borland make utility.
+	* ptw32_InterlockedCompareExchange.c:
+	Add Borland compatible asm code.
+
 2004-06-26  Jason Bard  <BardJA at Npt.NUWC.Navy.Mil>
 
 	* pthread.h (HAVE_STRUCT_TIMESPEC): If undefined, define it
diff --git a/README.Borland b/README.Borland
new file mode 100644
index 0000000..5aca71c
--- /dev/null
+++ b/README.Borland
@@ -0,0 +1,46 @@
+In ptw32_InterlockedCompareExchange.c, I've added a section for
+Borland's compiler; it's identical to that for the MS compiler except
+that it uses /* ... */ comments instead of ; comments.
+
+The other file is a makefile suitable for use with Borland's compiler
+(run "make -fBmakefile" in the directory).  It builds a single version
+of the library, pthreadBC.dll and the corresponding pthreadBC.lib
+import library, which is comparable to the pthreadVC version; I can't
+personally see any demand for the versions that include structured or
+C++ exception cancellation handling so I haven't attempted to build
+those versions of the library.  (I imagine a static version might be
+of use to some, but we can't legally use that on my commercial
+projects so I can't try that out, unfortunately.)
+
+Borland C++ doesn't define the ENOSYS constant used by pthreads-win32;
+rather than make more extensive patches to the pthreads-win32 source I
+have a mostly-arbitrary constant for it in the makefile.  However this
+doesn't make it visible to the application using the library, so if
+anyone actually wants to use this constant in their apps (why?)
+someone might like to make a seperate NEED_BCC_something define to add
+this stuff.
+
+The makefile also #defines EDEADLK as EDEADLOCK, _timeb as timeb, and
+_ftime as ftime, to deal with the minor differences between the two
+RTLs' naming conventions, and sets the compiler flags as required to
+get a normal compile of the library.
+
+
+(While I'm on the subject, the reason Borland users should recompile
+the library, rather than using the impdef/implib technique suggested
+previously on the mailing list, is that a) the errno constants are
+different, so the results returned by the pthread_* functions can be
+meaningless, and b) the errno variable/pseudo-variable itself is
+different in the MS & BCC runtimes, so you can't access the
+pthreadVC's errno from a Borland C++-compiled host application
+correctly - I imagine there are other potential problems from the RTL
+mismatch too.)
+
+Best regards,
+Will
+
+-- 
+Will Bryant
+Systems Architect, eCOSM Limited
+Cell +64 21 655 443, office +64 3 365 4176
+http://www.ecosm.com/
diff --git a/ptw32_InterlockedCompareExchange.c b/ptw32_InterlockedCompareExchange.c
index 0980710..299fc36 100644
--- a/ptw32_InterlockedCompareExchange.c
+++ b/ptw32_InterlockedCompareExchange.c
@@ -85,15 +85,32 @@ ptw32_InterlockedCompareExchange (PTW32_INTERLOCKED_LPLONG location,
     POP          ecx
   }
 
+#elif defined(__BORLANDC__)
+
+  _asm {
+    PUSH	 ecx
+    PUSH	 edx
+    MOV 	 ecx,dword ptr [location]
+    MOV 	 edx,dword ptr [value]
+    MOV 	 eax,dword ptr [comparand]
+    LOCK CMPXCHG dword ptr [ecx],edx	    /* if (EAX == [ECX]) */
+                                            /*  [ECX] = EDX      */
+					    /* else              */
+					    /*  EAX = [ECX]      */
+    MOV 	 dword ptr [result], eax
+    POP 	 edx
+    POP 	 ecx
+  }
+
 #elif defined(__GNUC__)
 
   __asm__
     (
      "lock\n\t"
-     "cmpxchgl       %3,(%0)"    /* if (EAX == [location]), */
+     "cmpxchgl       %3,(%0)"    /* if (EAX == [location])  */
                                  /*   [location] = value    */
                                  /* else                    */
-                                 /*   EAX = [location]           */
+                                 /*   EAX = [location]      */
      :"=r" (location), "=a" (result)
      :"0"  (location), "q" (value), "a" (comparand)
      : "memory" );
-- 
cgit v1.2.3