Issue #282 (bdwgc).
Public GC_alloc_lock() and GC_alloc_unlock() are introduced to simplify
dealing with the GC lock compared to GC_call_with_alloc_lock().
* include/gc.h [GC_THREADS] (GC_alloc_lock, GC_alloc_unlock): Declare
new API function.
* include/gc.h [!GC_THREADS] (GC_alloc_lock, GC_alloc_unlock): Define
as a no-op macro.
* misc.c [THREADS] (GC_alloc_lock, GC_alloc_unlock): Define API
function.
* tests/test.c (reachable_objs_count_enumerator): Remove function.
* tests/test.c (check_heap_stats): Call GC_alloc_lock(); call
GC_enumerate_reachable_objects_inner() directly; call GC_alloc_unlock().
# define REVEAL_POINTER(p) GC_REVEAL_POINTER(p)
#endif
+/* The routines to acquire/release the allocator lock. */
+/* The lock is not reentrant. GC_alloc_unlock() should not be called */
+/* unless the lock is acquired by the current thread. */
+#ifdef GC_THREADS
+ GC_API void GC_CALL GC_alloc_lock(void);
+ GC_API void GC_CALL GC_alloc_unlock(void);
+#else
+ /* No need for real locking if the client is single-threaded. */
+# define GC_alloc_lock() (void)0
+# define GC_alloc_unlock() (void)0
+#endif /* !GC_THREADS */
+
typedef void * (GC_CALLBACK * GC_fn_type)(void * /* client_data */);
GC_API void * GC_CALL GC_call_with_alloc_lock(GC_fn_type /* fn */,
void * /* client_data */) GC_ATTR_NONNULL(1);
return GC_parallel;
}
+ GC_API void GC_CALL GC_alloc_lock(void)
+ {
+ DCL_LOCK_STATE;
+ LOCK();
+ }
+
+ GC_API void GC_CALL GC_alloc_unlock(void)
+ {
+ /* no DCL_LOCK_STATE */
+ UNLOCK();
+ }
+
GC_INNER GC_on_thread_event_proc GC_on_thread_event = 0;
GC_API void GC_CALL GC_set_on_thread_event(GC_on_thread_event_proc fn)
(*(unsigned *)pcounter)++;
}
-void * GC_CALLBACK reachable_objs_count_enumerator(void *pcounter)
-{
- GC_enumerate_reachable_objects_inner(reachable_objs_counter, pcounter);
- return NULL;
-}
-
#define NUMBER_ROUND_UP(v, bound) ((((v) + (bound) - 1) / (bound)) * (bound))
void check_heap_stats(void)
FAIL;
}
}
- (void)GC_call_with_alloc_lock(reachable_objs_count_enumerator,
- &obj_count);
+ GC_alloc_lock();
+ GC_enumerate_reachable_objects_inner(reachable_objs_counter, &obj_count);
+ GC_alloc_unlock();
GC_printf("Completed %u tests\n", n_tests);
GC_printf("Allocated %d collectable objects\n", (int)collectable_count);
GC_printf("Allocated %d uncollectable objects\n",