]> granicus.if.org Git - gc/commitdiff
Move LOCK/UNLOCK from GC_unregister_disappearing_link_inner outer
authorIvan Maidanski <ivmai@mail.ru>
Sat, 17 Nov 2012 14:55:14 +0000 (18:55 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Sat, 17 Nov 2012 14:55:14 +0000 (18:55 +0400)
* finalize.c (GC_unregister_disappearing_link_inner): Add comment;
change return type (return entry of unregistered linked or NULL);
do not check link alignment; do not acquire the lock and do not free
the unregistered entry.
* finalize.c (GC_unregister_disappearing_link): Check link alignment,
invoke GC_unregister_disappearing_link_inner holding the allocation
lock and free found entry (if any).

finalize.c

index 4cb699bd83c7555087b076666a75eeef7bc0186f..257fb6192649684114997456533d4fa021e65615 100644 (file)
@@ -212,40 +212,45 @@ GC_API int GC_CALL GC_general_register_disappearing_link(void * * link,
 # define FREE_DL_ENTRY(curr_dl) GC_free(curr_dl)
 #endif
 
-GC_INLINE int GC_unregister_disappearing_link_inner(
+/* Unregisters given link and returns the link entry to free.   */
+/* Assume the lock is held.                                     */
+GC_INLINE struct disappearing_link *GC_unregister_disappearing_link_inner(
                                 struct dl_hashtbl_s *dl_hashtbl, void **link)
 {
-    struct disappearing_link *curr_dl, *prev_dl;
-    size_t index;
-    DCL_LOCK_STATE;
-
-    if (((word)link & (ALIGNMENT-1)) != 0) return(0); /* Nothing to do. */
+    struct disappearing_link *curr_dl;
+    struct disappearing_link *prev_dl = NULL;
+    size_t index = HASH2(link, dl_hashtbl->log_size);
 
-    LOCK();
-    index = HASH2(link, dl_hashtbl -> log_size);
-    prev_dl = NULL;
     for (curr_dl = dl_hashtbl -> head[index]; curr_dl;
          curr_dl = dl_next(curr_dl)) {
         if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) {
+            /* Remove found entry from the table. */
             if (NULL == prev_dl) {
                 dl_hashtbl -> head[index] = dl_next(curr_dl);
             } else {
                 dl_set_next(prev_dl, dl_next(curr_dl));
             }
             dl_hashtbl -> entries--;
-            UNLOCK();
-            FREE_DL_ENTRY(curr_dl);
-            return(1);
+            break;
         }
         prev_dl = curr_dl;
     }
-    UNLOCK();
-    return(0);
+    return curr_dl;
 }
 
 GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
 {
-    return GC_unregister_disappearing_link_inner(&GC_dl_hashtbl, link);
+    struct disappearing_link *curr_dl;
+    DCL_LOCK_STATE;
+
+    if (((word)link & (ALIGNMENT-1)) != 0) return(0); /* Nothing to do. */
+
+    LOCK();
+    curr_dl = GC_unregister_disappearing_link_inner(&GC_dl_hashtbl, link);
+    UNLOCK();
+    if (NULL == curr_dl) return 0;
+    FREE_DL_ENTRY(curr_dl);
+    return 1;
 }
 
 #ifndef GC_MOVE_DISAPPEARING_LINK_NOT_NEEDED