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
30typedef uint64_t bthread_t;
31
32// tid returned by bthread_start_* never equals this value.
33static const bthread_t INVALID_BTHREAD = 0;
34
35struct sockaddr;
36
37typedef unsigned bthread_stacktype_t;
38static const bthread_stacktype_t BTHREAD_STACKTYPE_UNKNOWN = 0;
39static const bthread_stacktype_t BTHREAD_STACKTYPE_PTHREAD = 1;
40static const bthread_stacktype_t BTHREAD_STACKTYPE_SMALL = 2;
41static const bthread_stacktype_t BTHREAD_STACKTYPE_NORMAL = 3;
42static const bthread_stacktype_t BTHREAD_STACKTYPE_LARGE = 4;
43
44typedef unsigned bthread_attrflags_t;
45static const bthread_attrflags_t BTHREAD_LOG_START_AND_FINISH = 8;
46static const bthread_attrflags_t BTHREAD_LOG_CONTEXT_SWITCH = 16;
47static const bthread_attrflags_t BTHREAD_NOSIGNAL = 32;
48
49// Key of thread-local data, created by bthread_key_create.
50typedef struct {
51 uint32_t index; // index in KeyTable
52 uint32_t version; // ABA avoidance
53} bthread_key_t;
54
55static const bthread_key_t INVALID_BTHREAD_KEY = { 0, 0 };
56
57#if defined(__cplusplus)
58// Overload operators for bthread_key_t
59inline bool operator==(bthread_key_t key1, bthread_key_t key2)
60{ return key1.index == key2.index && key1.version == key2.version; }
61inline bool operator!=(bthread_key_t key1, bthread_key_t key2)
62{ return !(key1 == key2); }
63inline 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}
67inline bool operator>(bthread_key_t key1, bthread_key_t key2)
68{ return key2 < key1; }
69inline bool operator<=(bthread_key_t key1, bthread_key_t key2)
70{ return !(key2 < key1); }
71inline bool operator>=(bthread_key_t key1, bthread_key_t key2)
72{ return !(key1 < key2); }
73inline 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
79typedef struct {
80 pthread_mutex_t mutex;
81 void* free_keytables;
82 int destroyed;
83} bthread_keytable_pool_t;
84
85typedef struct {
86 size_t nfree;
87} bthread_keytable_pool_stat_t;
88
89// Attributes for thread creation.
90typedef 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.
116static 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.
121static const bthread_attr_t BTHREAD_ATTR_SMALL =
122{ BTHREAD_STACKTYPE_SMALL, 0, NULL };
123static const bthread_attr_t BTHREAD_ATTR_NORMAL =
124{ BTHREAD_STACKTYPE_NORMAL, 0, NULL };
125static 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.
130static 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
136static const size_t BTHREAD_EPOLL_THREAD_NUM = 1;
137static const bthread_t BTHREAD_ATOMIC_INIT = 0;
138
139// Min/Max number of work pthreads.
140static const int BTHREAD_MIN_CONCURRENCY = 3 + BTHREAD_EPOLL_THREAD_NUM;
141static const int BTHREAD_MAX_CONCURRENCY = 1024;
142
143typedef 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.
154typedef struct {
155 int64_t duration_ns;
156 size_t sampling_range;
157} bthread_contention_site_t;
158
159typedef struct {
160 unsigned* butex;
161 bthread_contention_site_t csite;
162} bthread_mutex_t;
163
164typedef struct {
165} bthread_mutexattr_t;
166
167typedef struct {
168 bthread_mutex_t* m;
169 int* seq;
170} bthread_cond_t;
171
172typedef struct {
173} bthread_condattr_t;
174
175typedef struct {
176} bthread_rwlock_t;
177
178typedef struct {
179} bthread_rwlockattr_t;
180
181typedef struct {
182 unsigned int count;
183} bthread_barrier_t;
184
185typedef struct {
186} bthread_barrierattr_t;
187
188typedef 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!
194static const bthread_id_t INVALID_BTHREAD_ID = {0};
195
196#if defined(__cplusplus)
197// Overload operators for bthread_id_t
198inline bool operator==(bthread_id_t id1, bthread_id_t id2)
199{ return id1.value == id2.value; }
200inline bool operator!=(bthread_id_t id1, bthread_id_t id2)
201{ return !(id1 == id2); }
202inline bool operator<(bthread_id_t id1, bthread_id_t id2)
203{ return id1.value < id2.value; }
204inline bool operator>(bthread_id_t id1, bthread_id_t id2)
205{ return id2 < id1; }
206inline bool operator<=(bthread_id_t id1, bthread_id_t id2)
207{ return !(id2 < id1); }
208inline bool operator>=(bthread_id_t id1, bthread_id_t id2)
209{ return !(id1 < id2); }
210inline std::ostream& operator<<(std::ostream& os, bthread_id_t id)
211{ return os << id.value; }
212#endif // __cplusplus
213
214typedef 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
224typedef uint64_t bthread_timer_t;
225
226#endif // BTHREAD_TYPES_H
227