+2008-02-08 Hans Boehm <Hans.Boehm@hp.com>
+
+ * misc.c (GC_init_inner): Assert !GC_need_to_lock only when
+ defined. (GC_call_with_stack_base): Add GC_API.
+ * os_dep.c (GC_get_stack_base): Add GC_API.
+ * win32_threads.c: (GC_register_my_thread, GC_unregister_my_thread):
+ Add GC_API.
+ * include/gc.h: Add GC_API annotations.
+ * include/private/gc_locks.h: Define UNCOND_LOCK etc. also for
+ PCR.
+ * include/private/gc_pmark.h: Fix comments.
+
2008-02-06 Hans Boehm <Hans.Boehm@hp.com> (mostly from Henning Makholm)
* include/private/gc_priv.h, mark_rts.c, typd_mlc.c:
/* somewhere in the GC_call_with_stack_base frame. This often can */
/* be used to provide a sufficiently accurate stack base. And we */
/* implement it everywhere. */
-void * GC_call_with_stack_base(GC_stack_base_func fn, void *arg);
+GC_API void * GC_call_with_stack_base(GC_stack_base_func fn, void *arg);
/* Register the current thread, with the indicated stack base, as */
/* a new thread whose stack(s) should be traced by the GC. If a */
#define GC_DUPLICATE 1 /* Was already registered. */
#define GC_NO_THREADS 2 /* No thread support in GC. */
#define GC_UNIMPLEMENTED 3 /* Not yet implemented on this platform. */
-int GC_register_my_thread(struct GC_stack_base *);
+GC_API int GC_register_my_thread(struct GC_stack_base *);
/* Unregister the current thread. The thread may no longer allocate */
/* garbage collected memory or manipulate pointers to the */
/* pointer to the garbage-collected heap to another thread, it must */
/* do this before calling GC_unregister_my_thread, most probably */
/* by saving it in a global data structure. */
-int GC_unregister_my_thread(void);
+GC_API int GC_unregister_my_thread(void);
/* Attempt to fill in the GC_stack_base structure with the stack base */
/* for this thread. This appears to be required to implement anything */
/* threads are not automatically registered with the collector. */
/* It is also unfortunately hard to implement well on many platforms. */
/* Returns GC_SUCCESS or GC_UNIMPLEMENTED. */
-int GC_get_stack_base(struct GC_stack_base *);
+GC_API int GC_get_stack_base(struct GC_stack_base *);
/* The following routines are primarily intended for use with a */
/* preprocessor which inserts calls to check C pointer arithmetic. */
extern PCR_Th_ML GC_allocate_ml;
# define DCL_LOCK_STATE \
PCR_ERes GC_fastLockRes; PCR_sigset_t GC_old_sig_mask
-# define LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml)
-# define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml)
+# define UNCOND_LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml)
+# define UNCOND_UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml)
# endif
# if !defined(AO_HAVE_test_and_set_acquire) && defined(GC_PTHREADS)
#define GC_MARK_STACK_DISCARDS (INITIAL_MARK_STACK_SIZE/8)
typedef struct GC_ms_entry {
- ptr_t mse_start; /* First word of object */
+ ptr_t mse_start; /* First word of object, word aligned */
GC_word mse_descr; /* Descriptor; low order two bits are tags, */
- /* identifying the upper 30 bits as one of the */
- /* following: */
+ /* as described in gc_mark.h. */
} mse;
extern size_t GC_mark_stack_size;
/* And the initialization code needs to run before */
/* then. Thus we really don't hold any locks, and can */
/* in fact safely initialize them here. */
- GC_ASSERT(!GC_need_to_lock);
+# ifdef THREADS
+ GC_ASSERT(!GC_need_to_lock);
+# endif
# if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
if (!GC_is_initialized) {
BOOL (WINAPI *pfn) (LPCRITICAL_SECTION, DWORD) = NULL;
return result;
}
-void * GC_call_with_stack_base(GC_stack_base_func fn, void *arg)
+GC_API void * GC_call_with_stack_base(GC_stack_base_func fn, void *arg)
{
int dummy;
struct GC_stack_base base;
return(buf.RegionSize);
}
-int GC_get_stack_base(struct GC_stack_base *sb)
+GC_API int GC_get_stack_base(struct GC_stack_base *sb)
{
int dummy;
ptr_t sp = (ptr_t)(&dummy);
}
}
-int GC_register_my_thread(struct GC_stack_base *sb) {
+GC_API int GC_register_my_thread(struct GC_stack_base *sb) {
DWORD t = GetCurrentThreadId();
if (0 == GC_lookup_thread(t)) {
}
}
-int GC_unregister_my_thread(void)
+GC_API int GC_unregister_my_thread(void)
{
DWORD t = GetCurrentThreadId();