1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file |
3 | // distributed with this work for additional information |
4 | // regarding copyright ownership. The ASF licenses this file |
5 | // to you under the Apache License, Version 2.0 (the |
6 | // "License"); you may not use this file except in compliance |
7 | // with the License. You may obtain a copy of the License at |
8 | // |
9 | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | // |
11 | // Unless required by applicable law or agreed to in writing, |
12 | // software distributed under the License is distributed on an |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | // KIND, either express or implied. See the License for the |
15 | // specific language governing permissions and limitations |
16 | // under the License. |
17 | |
18 | // bthread - A M:N threading library to make applications more concurrent. |
19 | |
20 | // Date: Tue Jul 10 17:40:58 CST 2012 |
21 | |
22 | #ifndef BTHREAD_TYPES_H |
23 | #define BTHREAD_TYPES_H |
24 | |
25 | #include <stdint.h> // uint64_t |
26 | #if defined(__cplusplus) |
27 | #include "butil/logging.h" // CHECK |
28 | #endif |
29 | |
30 | typedef uint64_t bthread_t; |
31 | |
32 | // tid returned by bthread_start_* never equals this value. |
33 | static const bthread_t INVALID_BTHREAD = 0; |
34 | |
35 | struct sockaddr; |
36 | |
37 | typedef unsigned bthread_stacktype_t; |
38 | static const bthread_stacktype_t BTHREAD_STACKTYPE_UNKNOWN = 0; |
39 | static const bthread_stacktype_t BTHREAD_STACKTYPE_PTHREAD = 1; |
40 | static const bthread_stacktype_t BTHREAD_STACKTYPE_SMALL = 2; |
41 | static const bthread_stacktype_t BTHREAD_STACKTYPE_NORMAL = 3; |
42 | static const bthread_stacktype_t BTHREAD_STACKTYPE_LARGE = 4; |
43 | |
44 | typedef unsigned bthread_attrflags_t; |
45 | static const bthread_attrflags_t BTHREAD_LOG_START_AND_FINISH = 8; |
46 | static const bthread_attrflags_t BTHREAD_LOG_CONTEXT_SWITCH = 16; |
47 | static const bthread_attrflags_t BTHREAD_NOSIGNAL = 32; |
48 | |
49 | // Key of thread-local data, created by bthread_key_create. |
50 | typedef struct { |
51 | uint32_t index; // index in KeyTable |
52 | uint32_t version; // ABA avoidance |
53 | } bthread_key_t; |
54 | |
55 | static const bthread_key_t INVALID_BTHREAD_KEY = { 0, 0 }; |
56 | |
57 | #if defined(__cplusplus) |
58 | // Overload operators for bthread_key_t |
59 | inline bool operator==(bthread_key_t key1, bthread_key_t key2) |
60 | { return key1.index == key2.index && key1.version == key2.version; } |
61 | inline bool operator!=(bthread_key_t key1, bthread_key_t key2) |
62 | { return !(key1 == key2); } |
63 | inline bool operator<(bthread_key_t key1, bthread_key_t key2) { |
64 | return key1.index != key2.index ? (key1.index < key2.index) : |
65 | (key1.version < key2.version); |
66 | } |
67 | inline bool operator>(bthread_key_t key1, bthread_key_t key2) |
68 | { return key2 < key1; } |
69 | inline bool operator<=(bthread_key_t key1, bthread_key_t key2) |
70 | { return !(key2 < key1); } |
71 | inline bool operator>=(bthread_key_t key1, bthread_key_t key2) |
72 | { return !(key1 < key2); } |
73 | inline std::ostream& operator<<(std::ostream& os, bthread_key_t key) { |
74 | return os << "bthread_key_t{index=" << key.index << " version=" |
75 | << key.version << '}'; |
76 | } |
77 | #endif // __cplusplus |
78 | |
79 | typedef struct { |
80 | pthread_mutex_t mutex; |
81 | void* free_keytables; |
82 | int destroyed; |
83 | } bthread_keytable_pool_t; |
84 | |
85 | typedef struct { |
86 | size_t nfree; |
87 | } bthread_keytable_pool_stat_t; |
88 | |
89 | // Attributes for thread creation. |
90 | typedef struct bthread_attr_t { |
91 | bthread_stacktype_t stack_type; |
92 | bthread_attrflags_t flags; |
93 | bthread_keytable_pool_t* keytable_pool; |
94 | |
95 | #if defined(__cplusplus) |
96 | void operator=(unsigned stacktype_and_flags) { |
97 | stack_type = (stacktype_and_flags & 7); |
98 | flags = (stacktype_and_flags & ~(unsigned)7u); |
99 | keytable_pool = NULL; |
100 | } |
101 | bthread_attr_t operator|(unsigned other_flags) const { |
102 | CHECK(!(other_flags & 7)) << "flags=" << other_flags; |
103 | bthread_attr_t tmp = *this; |
104 | tmp.flags |= (other_flags & ~(unsigned)7u); |
105 | return tmp; |
106 | } |
107 | #endif // __cplusplus |
108 | } bthread_attr_t; |
109 | |
110 | // bthreads started with this attribute will run on stack of worker pthread and |
111 | // all bthread functions that would block the bthread will block the pthread. |
112 | // The bthread will not allocate its own stack, simply occupying a little meta |
113 | // memory. This is required to run JNI code which checks layout of stack. The |
114 | // obvious drawback is that you need more worker pthreads when you have a lot |
115 | // of such bthreads. |
116 | static const bthread_attr_t BTHREAD_ATTR_PTHREAD = |
117 | { BTHREAD_STACKTYPE_PTHREAD, 0, NULL }; |
118 | |
119 | // bthreads created with following attributes will have different size of |
120 | // stacks. Default is BTHREAD_ATTR_NORMAL. |
121 | static const bthread_attr_t BTHREAD_ATTR_SMALL = |
122 | { BTHREAD_STACKTYPE_SMALL, 0, NULL }; |
123 | static const bthread_attr_t BTHREAD_ATTR_NORMAL = |
124 | { BTHREAD_STACKTYPE_NORMAL, 0, NULL }; |
125 | static const bthread_attr_t BTHREAD_ATTR_LARGE = |
126 | { BTHREAD_STACKTYPE_LARGE, 0, NULL }; |
127 | |
128 | // bthreads created with this attribute will print log when it's started, |
129 | // context-switched, finished. |
130 | static const bthread_attr_t BTHREAD_ATTR_DEBUG = { |
131 | BTHREAD_STACKTYPE_NORMAL, |
132 | BTHREAD_LOG_START_AND_FINISH | BTHREAD_LOG_CONTEXT_SWITCH, |
133 | NULL |
134 | }; |
135 | |
136 | static const size_t BTHREAD_EPOLL_THREAD_NUM = 1; |
137 | static const bthread_t BTHREAD_ATOMIC_INIT = 0; |
138 | |
139 | // Min/Max number of work pthreads. |
140 | static const int BTHREAD_MIN_CONCURRENCY = 3 + BTHREAD_EPOLL_THREAD_NUM; |
141 | static const int BTHREAD_MAX_CONCURRENCY = 1024; |
142 | |
143 | typedef struct { |
144 | void* impl; |
145 | // following fields are part of previous impl. and not used right now. |
146 | // Don't remove them to break ABI compatibility. |
147 | unsigned head; |
148 | unsigned size; |
149 | unsigned conflict_head; |
150 | unsigned conflict_size; |
151 | } bthread_list_t; |
152 | |
153 | // TODO: bthread_contention_site_t should be put into butex. |
154 | typedef struct { |
155 | int64_t duration_ns; |
156 | size_t sampling_range; |
157 | } bthread_contention_site_t; |
158 | |
159 | typedef struct { |
160 | unsigned* butex; |
161 | bthread_contention_site_t csite; |
162 | } bthread_mutex_t; |
163 | |
164 | typedef struct { |
165 | } bthread_mutexattr_t; |
166 | |
167 | typedef struct { |
168 | bthread_mutex_t* m; |
169 | int* seq; |
170 | } bthread_cond_t; |
171 | |
172 | typedef struct { |
173 | } bthread_condattr_t; |
174 | |
175 | typedef struct { |
176 | } bthread_rwlock_t; |
177 | |
178 | typedef struct { |
179 | } bthread_rwlockattr_t; |
180 | |
181 | typedef struct { |
182 | unsigned int count; |
183 | } bthread_barrier_t; |
184 | |
185 | typedef struct { |
186 | } bthread_barrierattr_t; |
187 | |
188 | typedef struct { |
189 | uint64_t value; |
190 | } bthread_id_t; |
191 | |
192 | // bthread_id returned by bthread_id_create* can never be this value. |
193 | // NOTE: don't confuse with INVALID_BTHREAD! |
194 | static const bthread_id_t INVALID_BTHREAD_ID = {0}; |
195 | |
196 | #if defined(__cplusplus) |
197 | // Overload operators for bthread_id_t |
198 | inline bool operator==(bthread_id_t id1, bthread_id_t id2) |
199 | { return id1.value == id2.value; } |
200 | inline bool operator!=(bthread_id_t id1, bthread_id_t id2) |
201 | { return !(id1 == id2); } |
202 | inline bool operator<(bthread_id_t id1, bthread_id_t id2) |
203 | { return id1.value < id2.value; } |
204 | inline bool operator>(bthread_id_t id1, bthread_id_t id2) |
205 | { return id2 < id1; } |
206 | inline bool operator<=(bthread_id_t id1, bthread_id_t id2) |
207 | { return !(id2 < id1); } |
208 | inline bool operator>=(bthread_id_t id1, bthread_id_t id2) |
209 | { return !(id1 < id2); } |
210 | inline std::ostream& operator<<(std::ostream& os, bthread_id_t id) |
211 | { return os << id.value; } |
212 | #endif // __cplusplus |
213 | |
214 | typedef struct { |
215 | void* impl; |
216 | // following fields are part of previous impl. and not used right now. |
217 | // Don't remove them to break ABI compatibility. |
218 | unsigned head; |
219 | unsigned size; |
220 | unsigned conflict_head; |
221 | unsigned conflict_size; |
222 | } bthread_id_list_t; |
223 | |
224 | typedef uint64_t bthread_timer_t; |
225 | |
226 | #endif // BTHREAD_TYPES_H |
227 | |