OLD | NEW |
1 // Copyright (c) 2008, Google Inc. | 1 // Copyright (c) 2008, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 17 matching lines...) Expand all Loading... |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 // --- | 30 // --- |
31 // Author: Sanjay Ghemawat <opensource@google.com> | 31 // Author: Sanjay Ghemawat <opensource@google.com> |
32 | 32 |
33 #ifndef TCMALLOC_THREAD_CACHE_H_ | 33 #ifndef TCMALLOC_THREAD_CACHE_H_ |
34 #define TCMALLOC_THREAD_CACHE_H_ | 34 #define TCMALLOC_THREAD_CACHE_H_ |
35 | 35 |
36 #include <config.h> | 36 #include <config.h> |
37 #ifdef HAVE_PTHREAD | 37 #ifdef HAVE_PTHREAD |
38 #include <pthread.h> | 38 #include <pthread.h> // for pthread_t, pthread_key_t |
39 #endif | 39 #endif |
| 40 #include <stddef.h> // for size_t, NULL |
| 41 #ifdef HAVE_STDINT_H |
| 42 #include <stdint.h> // for uint32_t, uint64_t |
| 43 #endif |
| 44 #include <sys/types.h> // for ssize_t |
40 #include "common.h" | 45 #include "common.h" |
41 #include "linked_list.h" | 46 #include "linked_list.h" |
42 #include "maybe_threads.h" | 47 #include "maybe_threads.h" |
43 #include "page_heap_allocator.h" | 48 #include "page_heap_allocator.h" |
44 #include "sampler.h" | 49 #include "sampler.h" |
45 #include "static_vars.h" | 50 #include "static_vars.h" |
46 | 51 |
| 52 #include "common.h" // for SizeMap, kMaxSize, etc |
| 53 #include "internal_logging.h" // for ASSERT, etc |
| 54 #include "linked_list.h" // for SLL_Pop, SLL_PopRange, etc |
| 55 #include "page_heap_allocator.h" // for PageHeapAllocator |
| 56 #include "sampler.h" // for Sampler |
| 57 #include "static_vars.h" // for Static |
| 58 |
47 namespace tcmalloc { | 59 namespace tcmalloc { |
48 | 60 |
49 // Even if we have support for thread-local storage in the compiler | 61 // Even if we have support for thread-local storage in the compiler |
50 // and linker, the OS may not support it. We need to check that at | 62 // and linker, the OS may not support it. We need to check that at |
51 // runtime. Right now, we have to keep a manual set of "bad" OSes. | 63 // runtime. Right now, we have to keep a manual set of "bad" OSes. |
52 #if defined(HAVE_TLS) | 64 #if defined(HAVE_TLS) |
53 extern bool kernel_supports_tls; // defined in thread_cache.cc | 65 extern bool kernel_supports_tls; // defined in thread_cache.cc |
54 void CheckIfKernelSupportsTLS(); | 66 void CheckIfKernelSupportsTLS(); |
55 inline bool KernelSupportsTLS() { | 67 inline bool KernelSupportsTLS() { |
56 return kernel_supports_tls; | 68 return kernel_supports_tls; |
57 } | 69 } |
58 #endif // HAVE_TLS | 70 #endif // HAVE_TLS |
59 | 71 |
60 //------------------------------------------------------------------- | 72 //------------------------------------------------------------------- |
61 // Data kept per thread | 73 // Data kept per thread |
62 //------------------------------------------------------------------- | 74 //------------------------------------------------------------------- |
63 | 75 |
64 class ThreadCache { | 76 class ThreadCache { |
65 public: | 77 public: |
66 // Default bound on the total amount of thread caches. | |
67 static const size_t kDefaultOverallThreadCacheSize = 16 << 20; | |
68 | |
69 // All ThreadCache objects are kept in a linked list (for stats collection) | 78 // All ThreadCache objects are kept in a linked list (for stats collection) |
70 ThreadCache* next_; | 79 ThreadCache* next_; |
71 ThreadCache* prev_; | 80 ThreadCache* prev_; |
72 | 81 |
73 void Init(pthread_t tid); | 82 void Init(pthread_t tid); |
74 void Cleanup(); | 83 void Cleanup(); |
75 | 84 |
76 // Accessors (mostly just for printing stats) | 85 // Accessors (mostly just for printing stats) |
77 int freelist_length(size_t cl) const { return list_[cl].length(); } | 86 int freelist_length(size_t cl) const { return list_[cl].length(); } |
78 | 87 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 } | 215 } |
207 | 216 |
208 void PopRange(int N, void **start, void **end) { | 217 void PopRange(int N, void **start, void **end) { |
209 SLL_PopRange(&list_, N, start, end); | 218 SLL_PopRange(&list_, N, start, end); |
210 ASSERT(length_ >= N); | 219 ASSERT(length_ >= N); |
211 length_ -= N; | 220 length_ -= N; |
212 if (length_ < lowater_) lowater_ = length_; | 221 if (length_ < lowater_) lowater_ = length_; |
213 } | 222 } |
214 }; | 223 }; |
215 | 224 |
216 // The number of bytes one ThreadCache will steal from another when | |
217 // the first ThreadCache is forced to Scavenge(), delaying the | |
218 // next call to Scavenge for this thread. | |
219 static const size_t kStealAmount = 1 << 16; | |
220 | |
221 // Lower and upper bounds on the per-thread cache sizes | |
222 static const size_t kMinThreadCacheSize = kMaxSize * 2; //kStealAmount; | |
223 static const size_t kMaxThreadCacheSize = 2 << 20; | |
224 | |
225 // The number of times that a deallocation can cause a freelist to | |
226 // go over its max_length() before shrinking max_length(). | |
227 static const int kMaxOverages = 3; | |
228 | |
229 // Gets and returns an object from the central cache, and, if possible, | 225 // Gets and returns an object from the central cache, and, if possible, |
230 // also adds some objects of that size class to this thread cache. | 226 // also adds some objects of that size class to this thread cache. |
231 void* FetchFromCentralCache(size_t cl, size_t byte_size); | 227 void* FetchFromCentralCache(size_t cl, size_t byte_size); |
232 | 228 |
233 // Releases some number of items from src. Adjusts the list's max_length | 229 // Releases some number of items from src. Adjusts the list's max_length |
234 // to eventually converge on num_objects_to_move(cl). | 230 // to eventually converge on num_objects_to_move(cl). |
235 void ListTooLong(FreeList* src, size_t cl); | 231 void ListTooLong(FreeList* src, size_t cl); |
236 | 232 |
237 // Releases N items from this thread cache. | 233 // Releases N items from this thread cache. |
238 void ReleaseToCentralCache(FreeList* src, size_t cl, int N); | 234 void ReleaseToCentralCache(FreeList* src, size_t cl, int N); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 // because we may be in the thread destruction code and may have | 389 // because we may be in the thread destruction code and may have |
394 // already cleaned up the cache for this thread. | 390 // already cleaned up the cache for this thread. |
395 inline ThreadCache* ThreadCache::GetCacheIfPresent() { | 391 inline ThreadCache* ThreadCache::GetCacheIfPresent() { |
396 if (!tsd_inited_) return NULL; | 392 if (!tsd_inited_) return NULL; |
397 return GetThreadHeap(); | 393 return GetThreadHeap(); |
398 } | 394 } |
399 | 395 |
400 } // namespace tcmalloc | 396 } // namespace tcmalloc |
401 | 397 |
402 #endif // TCMALLOC_THREAD_CACHE_H_ | 398 #endif // TCMALLOC_THREAD_CACHE_H_ |
OLD | NEW |