2
* Copyright (c) 2000-2005 by Hewlett-Packard Company. All rights reserved.
4
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
7
* Permission is hereby granted to use or copy this program
8
* for any purpose, provided the above notices are retained on all copies.
9
* Permission to modify the code and to distribute modified code is granted,
10
* provided the above notices are retained, and a notice that the code was
11
* modified is included with the above copyright notice.
14
/* Included indirectly from a thread-library-specific file. */
15
/* This is the interface for thread-local allocation, whose */
16
/* implementation is mostly thread-library-independent. */
17
/* Here we describe only the interface that needs to be known */
18
/* and invoked from the thread support layer; the actual */
19
/* implementation also exports GC_malloc and friends, which */
20
/* are declared in gc.h. */
22
#include "private/gc_priv.h"
24
#if defined(THREAD_LOCAL_ALLOC)
26
#include "gc_inline.h"
29
# if defined USE_HPUX_TLS
30
# error USE_HPUX_TLS macro was replaced by USE_COMPILER_TLS
33
# if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_WIN32_SPECIFIC) && \
34
!defined(USE_WIN32_COMPILER_TLS) && !defined(USE_COMPILER_TLS) && \
35
!defined(USE_CUSTOM_SPECIFIC)
36
# if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
37
# if defined(__GNUC__) /* Fixed for versions past 2.95? */
38
# define USE_WIN32_SPECIFIC
40
# define USE_WIN32_COMPILER_TLS
42
# elif defined(LINUX) && !defined(ARM32) && !defined(AVR32) && \
43
(__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >=3))
44
# define USE_COMPILER_TLS
45
# elif (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
46
defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) || \
47
defined(GC_NETBSD_THREADS)
48
# define USE_PTHREAD_SPECIFIC
49
# elif defined(GC_HPUX_THREADS)
51
# define USE_PTHREAD_SPECIFIC
52
/* Empirically, as of gcc 3.3, USE_COMPILER_TLS doesn't work. */
54
# define USE_COMPILER_TLS
57
# define USE_CUSTOM_SPECIFIC /* Use our own. */
63
/* One of these should be declared as the tlfs field in the */
64
/* structure pointed to by a GC_thread. */
65
typedef struct thread_local_freelists {
66
# ifdef THREAD_LOCAL_ALLOC
67
void * ptrfree_freelists[TINY_FREELISTS];
68
void * normal_freelists[TINY_FREELISTS];
69
# ifdef GC_GCJ_SUPPORT
70
void * gcj_freelists[TINY_FREELISTS];
71
# define ERROR_FL (void *)(-1)
72
/* Value used for gcj_freelist[-1]; allocation is */
75
/* Free lists contain either a pointer or a small count */
76
/* reflecting the number of granules allocated at that */
78
/* 0 ==> thread-local allocation in use, free list */
80
/* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
81
/* too few objects of this size have been */
82
/* allocated by this thread. */
83
/* >= HBLKSIZE => pointer to nonempty free list. */
84
/* > DIRECT_GRANULES, < HBLKSIZE ==> transition to */
85
/* local alloc, equivalent to 0. */
86
# define DIRECT_GRANULES (HBLKSIZE/GRANULE_BYTES)
87
/* Don't use local free lists for up to this much */
93
# if defined(USE_PTHREAD_SPECIFIC)
94
# define GC_getspecific pthread_getspecific
95
# define GC_setspecific pthread_setspecific
96
# define GC_key_create pthread_key_create
97
# define GC_remove_specific(key) /* No need for cleanup on exit. */
98
typedef pthread_key_t GC_key_t;
99
# elif defined(USE_COMPILER_TLS) || defined(USE_WIN32_COMPILER_TLS)
100
# define GC_getspecific(x) (x)
101
# define GC_setspecific(key, v) ((key) = (v), 0)
102
# define GC_key_create(key, d) 0
103
# define GC_remove_specific(key) /* No need for cleanup on exit. */
104
typedef void * GC_key_t;
105
# elif defined(USE_WIN32_SPECIFIC)
106
# include <windows.h>
107
# define GC_getspecific TlsGetValue
108
# define GC_setspecific(key, v) !TlsSetValue(key, v)
109
/* We assume 0 == success, msft does the opposite. */
110
# define GC_key_create(key, d) \
111
((d) != 0? (ABORT("Destructor unsupported by TlsAlloc"),0) \
112
: ((*(key) = TlsAlloc()) == TLS_OUT_OF_INDEXES? \
113
(ABORT("Out of tls"), 0): \
115
# define GC_remove_specific(key) /* No need for cleanup on thread exit. */
116
/* Need TlsFree on process exit/detach ? */
117
typedef DWORD GC_key_t;
118
# elif defined(USE_CUSTOM_SPECIFIC)
119
# include "private/specific.h"
125
/* Each thread structure must be initialized. */
126
/* This call must be made from the new thread. */
127
/* Caller holds allocation lock. */
128
void GC_init_thread_local(GC_tlfs p);
130
/* Called when a thread is unregistered, or exits. */
131
/* We hold the allocator lock. */
132
void GC_destroy_thread_local(GC_tlfs p);
134
/* The thread support layer must arrange to mark thread-local */
135
/* free lists explicitly, since the link field is often */
136
/* invisible to the marker. It knows hoe to find all threads; */
137
/* we take care of an individual thread freelist structure. */
138
void GC_mark_thread_local_fls_for(GC_tlfs p);
141
#if defined(USE_COMPILER_TLS)
143
#elif defined(USE_WIN32_COMPILER_TLS)
146
GC_key_t GC_thread_key;
148
/* This is set up by the thread_local_alloc implementation. But the */
149
/* thread support layer calls GC_remove_specific(GC_thread_key) */
150
/* before a thread exits. */
151
/* And the thread support layer makes sure that GC_thread_key is traced,*/
154
#endif /* THREAD_LOCAL_ALLOC */