add support for whenAll to waitWithSemaphore
[folly.git] / folly / ThreadCachedArena.h
1 /*
2  * Copyright 2014 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       size_t maxAlign = SysArena::kDefaultMaxAlign);
47
48   void* allocate(size_t size) {
49     SysArena* arena = arena_.get();
50     if (UNLIKELY(!arena)) {
51       arena = allocateThreadLocalArena();
52     }
53
54     return arena->allocate(size);
55   }
56
57   void deallocate(void* p) {
58     // Deallocate? Never!
59   }
60
61  private:
62   ThreadCachedArena(const ThreadCachedArena&) = delete;
63   ThreadCachedArena(ThreadCachedArena&&) = delete;
64   ThreadCachedArena& operator=(const ThreadCachedArena&) = delete;
65   ThreadCachedArena& operator=(ThreadCachedArena&&) = delete;
66
67   SysArena* allocateThreadLocalArena();
68
69   // Zombify the blocks in arena, saving them for deallocation until
70   // the ThreadCachedArena is destroyed.
71   void zombify(SysArena&& arena);
72
73   const size_t minBlockSize_;
74   const size_t maxAlign_;
75   SysArena zombies_;  // allocated from threads that are now dead
76   std::mutex zombiesMutex_;
77   ThreadLocalPtr<SysArena> arena_;  // per-thread arena
78 };
79
80 template <>
81 struct IsArenaAllocator<ThreadCachedArena> : std::true_type { };
82
83 }  // namespace folly
84
85 #endif /* FOLLY_THREADCACHEDARENA_H_ */
86