diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2011-07-26 20:09:54 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2011-07-26 20:09:54 +0400 |
commit | e35a4171fe47dfbf847e08988ea6cec4dfc8d124 (patch) | |
tree | 25f3501669fbf24a4b370c4f8b0c0701b1da4062 /specific.c | |
parent | ffa0c9ea38b3dd87e91b5ed2118c74002fed6782 (diff) | |
download | bdwgc-e35a4171fe47dfbf847e08988ea6cec4dfc8d124.tar.gz |
gc7.0alpha1 tarball importgc7_0alpha1
Diffstat (limited to 'specific.c')
-rw-r--r-- | specific.c | 44 |
1 files changed, 39 insertions, 5 deletions
@@ -11,16 +11,17 @@ * modified is included with the above copyright notice. */ -#include "private/gc_priv.h" /* For GC_compare_and_exchange, GC_memory_barrier */ +#include "private/gc_priv.h" /* For configuration, pthreads.h. */ +#include "atomic_ops.h" #if defined(GC_LINUX_THREADS) #include "private/specific.h" static tse invalid_tse = {INVALID_QTID, 0, 0, INVALID_THREADID}; - /* A thread-specific data entry which will never */ - /* appear valid to a reader. Used to fill in empty */ - /* cache entries to avoid a check for 0. */ + /* A thread-specific data entry which will never */ + /* appear valid to a reader. Used to fill in empty */ + /* cache entries to avoid a check for 0. */ int PREFIXED(key_create) (tsd ** key_ptr, void (* destructor)(void *)) { int i; @@ -57,7 +58,7 @@ int PREFIXED(setspecific) (tsd * key, void * value) { GC_ASSERT(entry -> qtid == INVALID_QTID); /* There can only be one writer at a time, but this needs to be */ /* atomic with respect to concurrent readers. */ - *(volatile tse **)(key -> hash + hash_val) = entry; + AO_store_release((volatile AO_t *)(key -> hash + hash_val), (AO_t)entry); pthread_mutex_unlock(&(key -> lock)); return 0; } @@ -125,4 +126,37 @@ void * PREFIXED(slow_getspecific) (tsd * key, unsigned long qtid, return entry -> value; } +#ifdef GC_ASSERTIONS + +/* Check that that all elements of the data structure associated */ +/* with key are marked. */ +void PREFIXED(check_tsd_marks) (tsd *key) +{ + int i; + tse *p; + + if (!GC_is_marked(GC_base(key))) { + ABORT("Unmarked thread-specific-data table"); + } + for (i = 0; i < TS_HASH_SIZE; ++i) { + for (p = key -> hash[i]; p != 0; p = p -> next) { + if (!GC_is_marked(GC_base(p))) { + GC_err_printf( + "Thread-specific-data entry at %p not marked\n",p); + ABORT("Unmarked tse"); + } + } + } + for (i = 0; i < TS_CACHE_SIZE; ++i) { + p = key -> cache[i]; + if (p != &invalid_tse && !GC_is_marked(GC_base(p))) { + GC_err_printf( + "Cached thread-specific-data entry at %p not marked\n",p); + ABORT("Unmarked cached tse"); + } + } +} + +#endif + #endif /* GC_LINUX_THREADS */ |