Upgrade Boehm GC to 7.2alpha4.
[cacao.git] / src / mm / boehm-gc / include / private / thread_local_alloc.h
1 /*
2  * Copyright (c) 2000-2005 by Hewlett-Packard Company.  All rights reserved.
3  *
4  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
6  *
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.
12  */
13
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.                                        */
21
22 #ifndef GC_THREAD_LOCAL_ALLOC_H
23 #define GC_THREAD_LOCAL_ALLOC_H
24
25 #include "private/gc_priv.h"
26
27 #if defined(THREAD_LOCAL_ALLOC)
28
29 #include "gc_inline.h"
30
31 # if defined(USE_HPUX_TLS)
32 #   error USE_HPUX_TLS macro was replaced by USE_COMPILER_TLS
33 # endif
34
35 # if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_WIN32_SPECIFIC) && \
36      !defined(USE_WIN32_COMPILER_TLS) && !defined(USE_COMPILER_TLS) && \
37      !defined(USE_CUSTOM_SPECIFIC)
38 #   if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
39 #     if defined(__GNUC__)  /* Fixed for versions past 2.95? */ \
40          || defined(MSWINCE)
41 #       define USE_WIN32_SPECIFIC
42 #     else
43 #       define USE_WIN32_COMPILER_TLS
44 #     endif /* !GNU */
45 #   elif defined(LINUX) && !defined(ARM32) && \
46                  (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >=3))
47 #     define USE_COMPILER_TLS
48 #   elif (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
49          defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) || \
50          defined(GC_NETBSD_THREADS)
51 #     define USE_PTHREAD_SPECIFIC
52 #   elif defined(GC_HPUX_THREADS)
53 #     ifdef __GNUC__
54 #      define USE_PTHREAD_SPECIFIC
55          /* Empirically, as of gcc 3.3, USE_COMPILER_TLS doesn't work.  */
56 #     else
57 #      define USE_COMPILER_TLS
58 #     endif
59 #   else
60 #     define USE_CUSTOM_SPECIFIC  /* Use our own.       */
61 #   endif
62 # endif
63
64 # include <stdlib.h>
65
66 /* One of these should be declared as the tlfs field in the     */
67 /* structure pointed to by a GC_thread.                         */
68 typedef struct thread_local_freelists {
69 #   ifdef THREAD_LOCAL_ALLOC
70         void * ptrfree_freelists[TINY_FREELISTS];
71         void * normal_freelists[TINY_FREELISTS];
72 #       ifdef GC_GCJ_SUPPORT
73           void * gcj_freelists[TINY_FREELISTS];
74 #         define ERROR_FL ((void *)(word)-1)
75                 /* Value used for gcj_freelist[-1]; allocation is       */
76                 /* erroneous.                                           */
77 #       endif
78                 /* Free lists contain either a pointer or a small count */
79                 /* reflecting the number of granules allocated at that  */
80                 /* size.                                                */
81                 /* 0 ==> thread-local allocation in use, free list      */
82                 /*       empty.                                         */
83                 /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
84                 /*       too few objects of this size have been         */
85                 /*       allocated by this thread.                      */
86                 /* >= HBLKSIZE  => pointer to nonempty free list.       */
87                 /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to      */
88                 /*    local alloc, equivalent to 0.                     */
89 #       define DIRECT_GRANULES (HBLKSIZE/GRANULE_BYTES)
90                 /* Don't use local free lists for up to this much       */
91                 /* allocation.                                          */
92
93 #   endif
94 } *GC_tlfs;
95
96 # if defined(USE_PTHREAD_SPECIFIC)
97 #   define GC_getspecific pthread_getspecific
98 #   define GC_setspecific pthread_setspecific
99 #   define GC_key_create pthread_key_create
100 #   define GC_remove_specific(key)  /* No need for cleanup on exit. */
101     typedef pthread_key_t GC_key_t;
102 # elif defined(USE_COMPILER_TLS) || defined(USE_WIN32_COMPILER_TLS)
103 #   define GC_getspecific(x) (x)
104 #   define GC_setspecific(key, v) ((key) = (v), 0)
105 #   define GC_key_create(key, d) 0
106 #   define GC_remove_specific(key)  /* No need for cleanup on exit. */
107     typedef void * GC_key_t;
108 # elif defined(USE_WIN32_SPECIFIC)
109 #   include <windows.h>
110 #   define GC_getspecific TlsGetValue
111 #   define GC_setspecific(key, v) !TlsSetValue(key, v)
112         /* We assume 0 == success, msft does the opposite.      */
113 #   ifndef TLS_OUT_OF_INDEXES
114       /* this is currently missing in WinCE */
115 #     define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
116 #   endif
117 #   define GC_key_create(key, d)  \
118         ((d) != 0 || (*(key) = TlsAlloc()) == TLS_OUT_OF_INDEXES ? -1 : 0)
119 #   define GC_remove_specific(key)  /* No need for cleanup on thread exit. */
120         /* Need TlsFree on process exit/detach ? */
121     typedef DWORD GC_key_t;
122 # elif defined(USE_CUSTOM_SPECIFIC)
123 #   include "private/specific.h"
124 # else
125 #   error implement me
126 # endif
127
128
129 /* Each thread structure must be initialized.   */
130 /* This call must be made from the new thread.  */
131 /* Caller holds allocation lock.                */
132 GC_INNER void GC_init_thread_local(GC_tlfs p);
133
134 /* Called when a thread is unregistered, or exits.      */
135 /* We hold the allocator lock.                          */
136 GC_INNER void GC_destroy_thread_local(GC_tlfs p);
137
138 /* The thread support layer must arrange to mark thread-local   */
139 /* free lists explicitly, since the link field is often         */
140 /* invisible to the marker.  It knows how to find all threads;  */
141 /* we take care of an individual thread freelist structure.     */
142 GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p);
143
144 extern
145 #if defined(USE_COMPILER_TLS)
146   __thread
147 #elif defined(USE_WIN32_COMPILER_TLS)
148   __declspec(thread)
149 #endif
150 GC_key_t GC_thread_key;
151
152 /* This is set up by the thread_local_alloc implementation.  But the    */
153 /* thread support layer calls GC_remove_specific(GC_thread_key)         */
154 /* before a thread exits.                                               */
155 /* And the thread support layer makes sure that GC_thread_key is traced,*/
156 /* if necessary.                                                        */
157
158 #endif /* THREAD_LOCAL_ALLOC */
159
160 #endif /* GC_THREAD_LOCAL_ALLOC_H */