X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=hs-boehmgc.git;a=blobdiff_plain;f=gc-7.2%2Finclude%2Fprivate%2Fthread_local_alloc.h;fp=gc-7.2%2Finclude%2Fprivate%2Fthread_local_alloc.h;h=68d6d88bfa830ce9a7f6671918d7871ba525cfa6;hp=0000000000000000000000000000000000000000;hb=324587ba93dc77f37406d41fd2a20d0e0d94fb1d;hpb=2a4ea609491b225a1ceb06da70396e93916f137a diff --git a/gc-7.2/include/private/thread_local_alloc.h b/gc-7.2/include/private/thread_local_alloc.h new file mode 100644 index 0000000..68d6d88 --- /dev/null +++ b/gc-7.2/include/private/thread_local_alloc.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2000-2005 by Hewlett-Packard Company. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + */ + +/* Included indirectly from a thread-library-specific file. */ +/* This is the interface for thread-local allocation, whose */ +/* implementation is mostly thread-library-independent. */ +/* Here we describe only the interface that needs to be known */ +/* and invoked from the thread support layer; the actual */ +/* implementation also exports GC_malloc and friends, which */ +/* are declared in gc.h. */ + +#ifndef GC_THREAD_LOCAL_ALLOC_H +#define GC_THREAD_LOCAL_ALLOC_H + +#include "private/gc_priv.h" + +#ifdef THREAD_LOCAL_ALLOC + +#include "gc_inline.h" + +#if defined(USE_HPUX_TLS) +# error USE_HPUX_TLS macro was replaced by USE_COMPILER_TLS +#endif + +#if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_WIN32_SPECIFIC) \ + && !defined(USE_WIN32_COMPILER_TLS) && !defined(USE_COMPILER_TLS) \ + && !defined(USE_CUSTOM_SPECIFIC) +# if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) +# if defined(__GNUC__) /* Fixed for versions past 2.95? */ \ + || defined(MSWINCE) +# define USE_WIN32_SPECIFIC +# else +# define USE_WIN32_COMPILER_TLS +# endif /* !GNU */ +# elif defined(LINUX) && !defined(ARM32) && !defined(AVR32) \ + && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >=3)) +# define USE_COMPILER_TLS +# elif defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) \ + || defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS) \ + || defined(GC_NETBSD_THREADS) || defined(GC_RTEMS_PTHREADS) +# define USE_PTHREAD_SPECIFIC +# elif defined(GC_HPUX_THREADS) +# ifdef __GNUC__ +# define USE_PTHREAD_SPECIFIC + /* Empirically, as of gcc 3.3, USE_COMPILER_TLS doesn't work. */ +# else +# define USE_COMPILER_TLS +# endif +# else +# define USE_CUSTOM_SPECIFIC /* Use our own. */ +# endif +#endif + +#include + +/* One of these should be declared as the tlfs field in the */ +/* structure pointed to by a GC_thread. */ +typedef struct thread_local_freelists { + void * ptrfree_freelists[TINY_FREELISTS]; + void * normal_freelists[TINY_FREELISTS]; +# ifdef GC_GCJ_SUPPORT + void * gcj_freelists[TINY_FREELISTS]; +# define ERROR_FL ((void *)(word)-1) + /* Value used for gcj_freelist[-1]; allocation is */ + /* erroneous. */ +# endif + /* Free lists contain either a pointer or a small count */ + /* reflecting the number of granules allocated at that */ + /* size. */ + /* 0 ==> thread-local allocation in use, free list */ + /* empty. */ + /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */ + /* too few objects of this size have been */ + /* allocated by this thread. */ + /* >= HBLKSIZE => pointer to nonempty free list. */ + /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to */ + /* local alloc, equivalent to 0. */ +# define DIRECT_GRANULES (HBLKSIZE/GRANULE_BYTES) + /* Don't use local free lists for up to this much */ + /* allocation. */ +} *GC_tlfs; + +#if defined(USE_PTHREAD_SPECIFIC) +# define GC_getspecific pthread_getspecific +# define GC_setspecific pthread_setspecific +# define GC_key_create pthread_key_create +# define GC_remove_specific(key) /* No need for cleanup on exit. */ + typedef pthread_key_t GC_key_t; +#elif defined(USE_COMPILER_TLS) || defined(USE_WIN32_COMPILER_TLS) +# define GC_getspecific(x) (x) +# define GC_setspecific(key, v) ((key) = (v), 0) +# define GC_key_create(key, d) 0 +# define GC_remove_specific(key) /* No need for cleanup on exit. */ + typedef void * GC_key_t; +#elif defined(USE_WIN32_SPECIFIC) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# define NOSERVICE +# include +# define GC_getspecific TlsGetValue +# define GC_setspecific(key, v) !TlsSetValue(key, v) + /* We assume 0 == success, msft does the opposite. */ +# ifndef TLS_OUT_OF_INDEXES + /* this is currently missing in WinCE */ +# define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF +# endif +# define GC_key_create(key, d) \ + ((d) != 0 || (*(key) = TlsAlloc()) == TLS_OUT_OF_INDEXES ? -1 : 0) +# define GC_remove_specific(key) /* No need for cleanup on exit. */ + /* Need TlsFree on process exit/detach? */ + typedef DWORD GC_key_t; +#elif defined(USE_CUSTOM_SPECIFIC) +# include "private/specific.h" +#else +# error implement me +#endif + +/* Each thread structure must be initialized. */ +/* This call must be made from the new thread. */ +/* Caller holds allocation lock. */ +GC_INNER void GC_init_thread_local(GC_tlfs p); + +/* Called when a thread is unregistered, or exits. */ +/* We hold the allocator lock. */ +GC_INNER void GC_destroy_thread_local(GC_tlfs p); + +/* The thread support layer must arrange to mark thread-local */ +/* free lists explicitly, since the link field is often */ +/* invisible to the marker. It knows how to find all threads; */ +/* we take care of an individual thread freelist structure. */ +GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p); + +extern +#if defined(USE_COMPILER_TLS) + __thread +#elif defined(USE_WIN32_COMPILER_TLS) + __declspec(thread) +#endif +GC_key_t GC_thread_key; +/* This is set up by the thread_local_alloc implementation. No need */ +/* for cleanup on thread exit. But the thread support layer makes sure */ +/* that GC_thread_key is traced, if necessary. */ + +#endif /* THREAD_LOCAL_ALLOC */ + +#endif /* GC_THREAD_LOCAL_ALLOC_H */