version 1.2, 2002/07/24 07:46:36 |
version 1.3, 2002/07/24 08:00:20 |
|
|
* |
* |
*/ |
*/ |
# ifdef THREADS |
# ifdef THREADS |
|
void GC_noop1 GC_PROTO((word)); |
# ifdef PCR_OBSOLETE /* Faster, but broken with multiple lwp's */ |
# ifdef PCR_OBSOLETE /* Faster, but broken with multiple lwp's */ |
# include "th/PCR_Th.h" |
# include "th/PCR_Th.h" |
# include "th/PCR_ThCrSec.h" |
# include "th/PCR_ThCrSec.h" |
|
|
# define LOCK() RT0u__inCritical++ |
# define LOCK() RT0u__inCritical++ |
# define UNLOCK() RT0u__inCritical-- |
# define UNLOCK() RT0u__inCritical-- |
# endif |
# endif |
# ifdef SOLARIS_THREADS |
# ifdef GC_SOLARIS_THREADS |
# include <thread.h> |
# include <thread.h> |
# include <signal.h> |
# include <signal.h> |
extern mutex_t GC_allocate_ml; |
extern mutex_t GC_allocate_ml; |
|
|
# if defined(POWERPC) |
# if defined(POWERPC) |
inline static int GC_test_and_set(volatile unsigned int *addr) { |
inline static int GC_test_and_set(volatile unsigned int *addr) { |
int oldval; |
int oldval; |
int temp = 1; // locked value |
int temp = 1; /* locked value */ |
|
|
__asm__ __volatile__( |
__asm__ __volatile__( |
"1:\tlwarx %0,0,%3\n" // load and reserve |
"1:\tlwarx %0,0,%3\n" /* load and reserve */ |
"\tcmpwi %0, 0\n" // if load is |
"\tcmpwi %0, 0\n" /* if load is */ |
"\tbne 2f\n" // non-zero, return already set |
"\tbne 2f\n" /* non-zero, return already set */ |
"\tstwcx. %2,0,%1\n" // else store conditional |
"\tstwcx. %2,0,%1\n" /* else store conditional */ |
"\tbne- 1b\n" // retry if lost reservation |
"\tbne- 1b\n" /* retry if lost reservation */ |
"2:\t\n" // oldval is zero if we set |
"2:\t\n" /* oldval is zero if we set */ |
: "=&r"(oldval), "=p"(addr) |
: "=&r"(oldval), "=p"(addr) |
: "r"(temp), "1"(addr) |
: "r"(temp), "1"(addr) |
: "memory"); |
: "memory"); |
|
|
} |
} |
# define GC_TEST_AND_SET_DEFINED |
# define GC_TEST_AND_SET_DEFINED |
inline static void GC_clear(volatile unsigned int *addr) { |
inline static void GC_clear(volatile unsigned int *addr) { |
__asm__ __volatile__("eieio" ::: "memory"); |
__asm__ __volatile__("eieio" : : : "memory"); |
*(addr) = 0; |
*(addr) = 0; |
} |
} |
# define GC_CLEAR_DEFINED |
# define GC_CLEAR_DEFINED |
|
|
# define GC_TEST_AND_SET_DEFINED |
# define GC_TEST_AND_SET_DEFINED |
# endif |
# endif |
# ifdef MIPS |
# ifdef MIPS |
# if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \ |
# ifdef LINUX |
|
# include <sys/tas.h> |
|
# define GC_test_and_set(addr) _test_and_set((int *) addr,1) |
|
# define GC_TEST_AND_SET_DEFINED |
|
# elif __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \ |
|| !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700 |
|| !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700 |
# define GC_test_and_set(addr, v) test_and_set(addr,v) |
# ifdef __GNUC__ |
|
# define GC_test_and_set(addr) _test_and_set(addr,1) |
|
# else |
|
# define GC_test_and_set(addr) test_and_set(addr,1) |
|
# endif |
# else |
# else |
# define GC_test_and_set(addr, v) __test_and_set(addr,v) |
# define GC_test_and_set(addr) __test_and_set(addr,1) |
# define GC_clear(addr) __lock_release(addr); |
# define GC_clear(addr) __lock_release(addr); |
# define GC_CLEAR_DEFINED |
# define GC_CLEAR_DEFINED |
# endif |
# endif |
|
|
/* "set" means 0 and "clear" means 1 here. */ |
/* "set" means 0 and "clear" means 1 here. */ |
# define GC_test_and_set(addr) !GC_test_and_clear(addr); |
# define GC_test_and_set(addr) !GC_test_and_clear(addr); |
# define GC_TEST_AND_SET_DEFINED |
# define GC_TEST_AND_SET_DEFINED |
# define GC_clear(addr) GC_noop1(addr); *(volatile unsigned int *)addr = 1; |
# define GC_clear(addr) GC_noop1((word)(addr)); *(volatile unsigned int *)addr = 1; |
/* The above needs a memory barrier! */ |
/* The above needs a memory barrier! */ |
# define GC_CLEAR_DEFINED |
# define GC_CLEAR_DEFINED |
# endif |
# endif |
|
|
# define USE_PTHREAD_LOCKS |
# define USE_PTHREAD_LOCKS |
# endif |
# endif |
|
|
# if defined(LINUX_THREADS) || defined(OSF1_THREADS) \ |
# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ |
|| defined(HPUX_THREADS) |
&& !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) |
# define NO_THREAD (pthread_t)(-1) |
# define NO_THREAD (pthread_t)(-1) |
# include <pthread.h> |
# include <pthread.h> |
# if defined(PARALLEL_MARK) |
# if defined(PARALLEL_MARK) |
|
|
# ifdef GC_ASSERTIONS |
# ifdef GC_ASSERTIONS |
extern pthread_t GC_mark_lock_holder; |
extern pthread_t GC_mark_lock_holder; |
# endif |
# endif |
# endif /* LINUX_THREADS || OSF1_THREADS || HPUX_THREADS */ |
# endif /* GC_PTHREADS with linux_threads.c implementation */ |
# if defined(IRIX_THREADS) |
# if defined(GC_IRIX_THREADS) |
# include <pthread.h> |
# include <pthread.h> |
/* This probably should never be included, but I can't test */ |
/* This probably should never be included, but I can't test */ |
/* on Irix anymore. */ |
/* on Irix anymore. */ |
|
|
# define NO_THREAD (pthread_t)(-1) |
# define NO_THREAD (pthread_t)(-1) |
# define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD |
# define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD |
# define I_HOLD_LOCK() (pthread_equal(GC_lock_holder, pthread_self())) |
# define I_HOLD_LOCK() (pthread_equal(GC_lock_holder, pthread_self())) |
# define LOCK() { if (GC_test_and_set(&GC_allocate_lock, 1)) GC_lock(); } |
# define LOCK() { if (GC_test_and_set(&GC_allocate_lock)) GC_lock(); } |
# define UNLOCK() GC_clear(&GC_allocate_lock); |
# define UNLOCK() GC_clear(&GC_allocate_lock); |
extern VOLATILE GC_bool GC_collecting; |
extern VOLATILE GC_bool GC_collecting; |
# define ENTER_GC() \ |
# define ENTER_GC() \ |
|
|
GC_collecting = 1; \ |
GC_collecting = 1; \ |
} |
} |
# define EXIT_GC() GC_collecting = 0; |
# define EXIT_GC() GC_collecting = 0; |
# endif /* IRIX_THREADS */ |
# endif /* GC_IRIX_THREADS */ |
# ifdef WIN32_THREADS |
# if defined(GC_WIN32_THREADS) |
# include <windows.h> |
# if defined(GC_PTHREADS) |
GC_API CRITICAL_SECTION GC_allocate_ml; |
# include <pthread.h> |
# define LOCK() EnterCriticalSection(&GC_allocate_ml); |
extern pthread_mutex_t GC_allocate_ml; |
# define UNLOCK() LeaveCriticalSection(&GC_allocate_ml); |
# define LOCK() pthread_mutex_lock(&GC_allocate_ml) |
|
# define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml) |
|
# else |
|
# include <windows.h> |
|
GC_API CRITICAL_SECTION GC_allocate_ml; |
|
# define LOCK() EnterCriticalSection(&GC_allocate_ml); |
|
# define UNLOCK() LeaveCriticalSection(&GC_allocate_ml); |
|
# endif |
# endif |
# endif |
# ifndef SET_LOCK_HOLDER |
# ifndef SET_LOCK_HOLDER |
# define SET_LOCK_HOLDER() |
# define SET_LOCK_HOLDER() |