Add assertions to ensure ADD_CALL_CHAIN is called holding the lock
authorIvan Maidanski <ivmai@mail.ru>
Thu, 15 Mar 2018 20:16:36 +0000 (23:16 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 15 Mar 2018 20:16:36 +0000 (23:16 +0300)
(code refactoring)

* alloc.c (GC_collect_a_little_inner, GC_allocobj): Add assertion that
the allocation lock is held.
* dbg_mlc.c (GC_store_debug_info_inner): Likewise.
* dbg_mlc.c [DBG_HDRS_ALL] (GC_debug_generic_malloc_inner,
GC_debug_generic_malloc_inner_ignore_off_page): Likewise.
* finalize.c [!GC_TOGGLE_REFS_NOT_NEEDED] (ensure_toggleref_capacity):
Likewise.
* specific.c [USE_CUSTOM_SPECIFIC] (GC_key_create_inner): Likewise.
* alloc.c (GC_allocobj): Remove comment (about the lock).
* dbg_mlc.c [DBG_HDRS_ALL] (GC_debug_generic_malloc_inner): Likewise.

alloc.c
dbg_mlc.c
finalize.c
specific.c

diff --git a/alloc.c b/alloc.c
index abdfebe..1d4c90c 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -577,7 +577,9 @@ GC_INNER void GC_collect_a_little_inner(int n)
 {
     IF_CANCEL(int cancel_state;)
 
+    GC_ASSERT(I_HOLD_LOCK());
     if (GC_dont_gc) return;
+
     DISABLE_CANCEL(cancel_state);
     if (GC_incremental && GC_collection_in_progress()) {
         int i;
@@ -1460,7 +1462,6 @@ GC_INNER GC_bool GC_collect_or_expand(word needed_blocks,
  * Make sure the object free list for size gran (in granules) is not empty.
  * Return a pointer to the first object on the free list.
  * The object MUST BE REMOVED FROM THE FREE LIST BY THE CALLER.
- * Assumes we hold the allocator lock.
  */
 GC_INNER ptr_t GC_allocobj(size_t gran, int kind)
 {
@@ -1468,6 +1469,7 @@ GC_INNER ptr_t GC_allocobj(size_t gran, int kind)
     GC_bool tried_minor = FALSE;
     GC_bool retry = FALSE;
 
+    GC_ASSERT(I_HOLD_LOCK());
     if (gran == 0) return(0);
 
     while (*flh == 0) {
index f087ab4..554692b 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -277,6 +277,7 @@ GC_INNER void *GC_store_debug_info_inner(void *p, word sz GC_ATTR_UNUSED,
 {
     word * result = (word *)((oh *)p + 1);
 
+    GC_ASSERT(I_HOLD_LOCK());
     GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
     GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK((ptr_t)p, sz)));
 #   ifdef KEEP_BACK_PTRS
@@ -577,13 +578,13 @@ STATIC void * GC_debug_generic_malloc(size_t lb, int knd, GC_EXTRA_PARAMS)
   /* An allocation function for internal use.  Normally internally      */
   /* allocated objects do not have debug information.  But in this      */
   /* case, we need to make sure that all objects have debug headers.    */
-  /* We assume we already hold the GC lock.                             */
   GC_INNER void * GC_debug_generic_malloc_inner(size_t lb, int k)
   {
-    void * result = GC_generic_malloc_inner(
-                                SIZET_SAT_ADD(lb, DEBUG_BYTES), k);
+    void * result;
 
-    if (result == 0) {
+    GC_ASSERT(I_HOLD_LOCK());
+    result = GC_generic_malloc_inner(SIZET_SAT_ADD(lb, DEBUG_BYTES), k);
+    if (NULL == result) {
         GC_err_printf("GC internal allocation (%lu bytes) returning NULL\n",
                        (unsigned long) lb);
         return(0);
@@ -598,10 +599,12 @@ STATIC void * GC_debug_generic_malloc(size_t lb, int knd, GC_EXTRA_PARAMS)
   GC_INNER void * GC_debug_generic_malloc_inner_ignore_off_page(size_t lb,
                                                                 int k)
   {
-    void * result = GC_generic_malloc_inner_ignore_off_page(
-                                SIZET_SAT_ADD(lb, DEBUG_BYTES), k);
+    void * result;
 
-    if (result == 0) {
+    GC_ASSERT(I_HOLD_LOCK());
+    result = GC_generic_malloc_inner_ignore_off_page(
+                                SIZET_SAT_ADD(lb, DEBUG_BYTES), k);
+    if (NULL == result) {
         GC_err_printf("GC internal allocation (%lu bytes) returning NULL\n",
                        (unsigned long) lb);
         return(0);
index 10d9b9e..d6d2f6e 100644 (file)
@@ -400,6 +400,7 @@ GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
   static GC_bool ensure_toggleref_capacity(int capacity_inc)
   {
     GC_ASSERT(capacity_inc >= 0);
+    GC_ASSERT(I_HOLD_LOCK());
     if (NULL == GC_toggleref_arr) {
       GC_toggleref_array_capacity = 32; /* initial capacity */
       GC_toggleref_arr = (GCToggleRef *)GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE(
index eca2d93..0ded036 100644 (file)
@@ -27,11 +27,13 @@ GC_INNER int GC_key_create_inner(tsd ** key_ptr)
 {
     int i;
     int ret;
-    tsd * result = (tsd *)MALLOC_CLEAR(sizeof(tsd));
+    tsd * result;
 
+    GC_ASSERT(I_HOLD_LOCK());
     /* A quick alignment check, since we need atomic stores */
     GC_ASSERT((word)(&invalid_tse.next) % sizeof(tse *) == 0);
-    if (0 == result) return ENOMEM;
+    result = (tsd *)MALLOC_CLEAR(sizeof(tsd));
+    if (NULL == result) return ENOMEM;
     ret = pthread_mutex_init(&result->lock, NULL);
     if (ret != 0) return ret;
     for (i = 0; i < TS_CACHE_SIZE; ++i) {