2b87c12179a4bca6345ff5fc0a86829d0485955c
[folly.git] / folly / ThreadCachedArena.h
1 /*
2  * Copyright 2012 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef FOLLY_THREADCACHEDARENA_H_
18 #define FOLLY_THREADCACHEDARENA_H_
19
20 #include <utility>
21 #include <mutex>
22 #include <limits>
23 #include <boost/intrusive/slist.hpp>
24
25 #include "folly/Likely.h"
26 #include "folly/Arena.h"
27 #include "folly/ThreadLocal.h"
28
29 namespace folly {
30
31 /**
32  * Thread-caching arena: allocate memory which gets freed when the arena gets
33  * destroyed.
34  *
35  * The arena itself allocates memory using malloc() in blocks of
36  * at least minBlockSize bytes.
37  *
38  * For speed, each thread gets its own Arena (see Arena.h); when threads
39  * exit, the Arena gets merged into a "zombie" Arena, which will be deallocated
40  * when the ThreadCachedArena object is destroyed.
41  */
42 class ThreadCachedArena {
43  public:
44   explicit ThreadCachedArena(
45       size_t minBlockSize = SysArena::kDefaultMinBlockSize);
46
47   void* allocate(size_t size) {
48     SysArena* arena = arena_.get();
49     if (UNLIKELY(!arena)) {
50       arena = allocateThreadLocalArena();
51     }
52
53     return arena->allocate(size);
54   }
55
56   void deallocate(void* p) {
57     // Deallocate? Never!
58   }
59
60  private:
61   ThreadCachedArena(const ThreadCachedArena&) = delete;
62   ThreadCachedArena(ThreadCachedArena&&) = delete;
63   ThreadCachedArena& operator=(const ThreadCachedArena&) = delete;
64   ThreadCachedArena& operator=(ThreadCachedArena&&) = delete;
65
66   SysArena* allocateThreadLocalArena();
67
68   // Zombify the blocks in arena, saving them for deallocation until
69   // the ThreadCachedArena is destroyed.
70   void zombify(SysArena&& arena);
71
72   size_t minBlockSize_;
73   SysArena zombies_;  // allocated from threads that are now dead
74   std::mutex zombiesMutex_;
75   ThreadLocalPtr<SysArena> arena_;  // per-thread arena
76 };
77
78 }  // namespace folly
79
80 #endif /* FOLLY_THREADCACHEDARENA_H_ */
81