diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2012-11-17 18:55:14 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2012-11-17 18:55:14 +0400 |
commit | df392f378463ae22e7b0f9da253dd13aa3840d9f (patch) | |
tree | 8d1818eb76e8eae5f078b8c965cca94f1287e6b8 /finalize.c | |
parent | be9ce1b95138c7a8e1bde4c22f610adc80ccbc21 (diff) | |
download | bdwgc-df392f378463ae22e7b0f9da253dd13aa3840d9f.tar.gz |
Move LOCK/UNLOCK from GC_unregister_disappearing_link_inner outer
* 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).
Diffstat (limited to 'finalize.c')
-rw-r--r-- | finalize.c | 35 |
1 files changed, 20 insertions, 15 deletions
@@ -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 |