summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2011-09-07 15:35:22 +0200
committerIvan Maidanski <ivmai@mail.ru>2011-09-12 12:26:01 +0200
commit92198c76397bf78c59cd170315ad2c857c5be584 (patch)
tree310a6a30abcb40be4e52504c930ec3015b5382f3 /misc.c
parented9b8b97e2d72aa28b85999c7e57172e130fbc22 (diff)
HOTFIX: Remove locking in API GC_get_bytes_since_gc and friends.
Add GC_get_heap_usage_safe() to API as a thread-safe alternative to GC_get_bytes_since_gc and friends. Remove newly-added lock-free GC_get_heap_size_inner and GC_get_free_bytes_inner from API. * include/gc.h (GC_get_heap_size, GC_get_free_bytes, GC_get_unmapped_bytes, GC_get_bytes_since_gc, GC_get_total_bytes): Refine comment. * include/gc.h (GC_HAVE_GET_HEAP_USAGE_SAFE): New macro. * include/gc.h (GC_get_heap_usage_safe): New API function. * misc.c (GC_get_heap_usage_safe): Likewise. * include/gc_mark.h (GC_get_heap_size_inner, GC_get_free_bytes_inner): Remove API function. * misc.c (GC_get_heap_size_inner, GC_get_free_bytes_inner): Likewise. * misc.c (GC_get_heap_size): Add comment. * misc.c (GC_get_heap_size, GC_get_free_bytes, GC_get_unmapped_bytes, GC_get_bytes_since_gc, GC_get_total_bytes): Remove locking. * misc.c (GC_get_unmapped_bytes): Do not test USE_MUNMAP (not needed after locking removal). * misc.c (GC_get_bytes_since_gc, GC_get_total_bytes): Cast result to size_t.
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c77
1 files changed, 32 insertions, 45 deletions
diff --git a/misc.c b/misc.c
index 2ea209f..c164481 100644
--- a/misc.c
+++ b/misc.c
@@ -399,75 +399,62 @@ GC_API size_t GC_CALL GC_size(const void * p)
return hhdr -> hb_sz;
}
+
+/* These getters remain unsynchronized for compatibility (since some */
+/* clients could call some of them from a GC callback holding the */
+/* allocator lock). */
GC_API size_t GC_CALL GC_get_heap_size(void)
{
- size_t value;
- DCL_LOCK_STATE;
- LOCK();
/* ignore the memory space returned to OS (i.e. count only the */
/* space owned by the garbage collector) */
- value = (size_t)(GC_heapsize - GC_unmapped_bytes);
- UNLOCK();
- return value;
+ return (size_t)(GC_heapsize - GC_unmapped_bytes);
}
GC_API size_t GC_CALL GC_get_free_bytes(void)
{
- size_t value;
- DCL_LOCK_STATE;
- LOCK();
/* ignore the memory space returned to OS */
- value = (size_t)(GC_large_free_bytes - GC_unmapped_bytes);
- UNLOCK();
- return value;
-}
-
-/* The _inner versions assume the caller holds the allocation lock. */
-/* Declared in gc_mark.h (where other public "inner" functions reside). */
-GC_API size_t GC_CALL GC_get_heap_size_inner(void)
-{
- return (size_t)(GC_heapsize - GC_unmapped_bytes);
-}
-
-GC_API size_t GC_CALL GC_get_free_bytes_inner(void)
-{
return (size_t)(GC_large_free_bytes - GC_unmapped_bytes);
}
GC_API size_t GC_CALL GC_get_unmapped_bytes(void)
{
-# ifdef USE_MUNMAP
- size_t value;
- DCL_LOCK_STATE;
- LOCK();
- value = (size_t)GC_unmapped_bytes;
- UNLOCK();
- return value;
-# else
- return 0;
-# endif
+ return (size_t)GC_unmapped_bytes;
}
GC_API size_t GC_CALL GC_get_bytes_since_gc(void)
{
- size_t value;
- DCL_LOCK_STATE;
- LOCK();
- value = GC_bytes_allocd;
- UNLOCK();
- return value;
+ return (size_t)GC_bytes_allocd;
}
GC_API size_t GC_CALL GC_get_total_bytes(void)
{
- size_t value;
- DCL_LOCK_STATE;
- LOCK();
- value = GC_bytes_allocd+GC_bytes_allocd_before_gc;
- UNLOCK();
- return value;
+ return (size_t)(GC_bytes_allocd + GC_bytes_allocd_before_gc);
}
+/* Return the heap usage information. This is a thread-safe (atomic) */
+/* alternative for the five above getters. NULL pointer is allowed for */
+/* any argument. Returned (filled in) values are of word type. */
+GC_API void GC_CALL GC_get_heap_usage_safe(GC_word *pheap_size,
+ GC_word *pfree_bytes, GC_word *punmapped_bytes,
+ GC_word *pbytes_since_gc, GC_word *ptotal_bytes)
+{
+ DCL_LOCK_STATE;
+
+ LOCK();
+ if (pheap_size != NULL)
+ *pheap_size = GC_heapsize - GC_unmapped_bytes;
+ if (pfree_bytes != NULL)
+ *pfree_bytes = GC_large_free_bytes - GC_unmapped_bytes;
+ if (punmapped_bytes != NULL)
+ *punmapped_bytes = GC_unmapped_bytes;
+ if (pbytes_since_gc != NULL)
+ *pbytes_since_gc = GC_bytes_allocd;
+ if (ptotal_bytes != NULL)
+ *ptotal_bytes = GC_bytes_allocd + GC_bytes_allocd_before_gc;
+ UNLOCK();
+}
+
+
#ifdef THREADS
GC_API int GC_CALL GC_get_suspend_signal(void)
{