summaryrefslogtreecommitdiff
path: root/finalize.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2012-11-17 18:55:14 +0400
committerIvan Maidanski <ivmai@mail.ru>2012-11-17 18:55:14 +0400
commitdf392f378463ae22e7b0f9da253dd13aa3840d9f (patch)
tree8d1818eb76e8eae5f078b8c965cca94f1287e6b8 /finalize.c
parentbe9ce1b95138c7a8e1bde4c22f610adc80ccbc21 (diff)
downloadbdwgc-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.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/finalize.c b/finalize.c
index 4cb699bd..257fb619 100644
--- a/finalize.c
+++ b/finalize.c
@@ -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