// bthread - A M:N threading library to make applications more concurrent. // Copyright (c) 2012 Baidu, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Author: Ge,Jun (gejun@baidu.com) // Date: Tue Jul 10 17:40:58 CST 2012 #ifndef BTHREAD_TYPES_H #define BTHREAD_TYPES_H #include <stdint.h> // uint64_t #if defined(__cplusplus) #include "butil/logging.h" // CHECK #endif typedef uint64_t bthread_t; // tid returned by bthread_start_* never equals this value. static const bthread_t INVALID_BTHREAD = 0; struct sockaddr; typedef unsigned bthread_stacktype_t; static const bthread_stacktype_t BTHREAD_STACKTYPE_UNKNOWN = 0; static const bthread_stacktype_t BTHREAD_STACKTYPE_PTHREAD = 1; static const bthread_stacktype_t BTHREAD_STACKTYPE_SMALL = 2; static const bthread_stacktype_t BTHREAD_STACKTYPE_NORMAL = 3; static const bthread_stacktype_t BTHREAD_STACKTYPE_LARGE = 4; typedef unsigned bthread_attrflags_t; static const bthread_attrflags_t BTHREAD_LOG_START_AND_FINISH = 8; static const bthread_attrflags_t BTHREAD_LOG_CONTEXT_SWITCH = 16; static const bthread_attrflags_t BTHREAD_NOSIGNAL = 32; // Key of thread-local data, created by bthread_key_create. typedef struct { uint32_t index; // index in KeyTable uint32_t version; // ABA avoidance } bthread_key_t; static const bthread_key_t INVALID_BTHREAD_KEY = { 0, 0 }; #if defined(__cplusplus) // Overload operators for bthread_key_t inline bool operator==(bthread_key_t key1, bthread_key_t key2) { return key1.index == key2.index && key1.version == key2.version; } inline bool operator!=(bthread_key_t key1, bthread_key_t key2) { return !(key1 == key2); } inline bool operator<(bthread_key_t key1, bthread_key_t key2) { return key1.index != key2.index ? (key1.index < key2.index) : (key1.version < key2.version); } inline bool operator>(bthread_key_t key1, bthread_key_t key2) { return key2 < key1; } inline bool operator<=(bthread_key_t key1, bthread_key_t key2) { return !(key2 < key1); } inline bool operator>=(bthread_key_t key1, bthread_key_t key2) { return !(key1 < key2); } inline std::ostream& operator<<(std::ostream& os, bthread_key_t key) { return os << "bthread_key_t{index=" << key.index << " version=" << key.version << '}'; } #endif // __cplusplus typedef struct { pthread_mutex_t mutex; void* free_keytables; int destroyed; } bthread_keytable_pool_t; typedef struct { size_t nfree; } bthread_keytable_pool_stat_t; // Attributes for thread creation. typedef struct bthread_attr_t { bthread_stacktype_t stack_type; bthread_attrflags_t flags; bthread_keytable_pool_t* keytable_pool; #if defined(__cplusplus) void operator=(unsigned stacktype_and_flags) { stack_type = (stacktype_and_flags & 7); flags = (stacktype_and_flags & ~(unsigned)7u); keytable_pool = NULL; } bthread_attr_t operator|(unsigned other_flags) const { CHECK(!(other_flags & 7)) << "flags=" << other_flags; bthread_attr_t tmp = *this; tmp.flags |= (other_flags & ~(unsigned)7u); return tmp; } #endif // __cplusplus } bthread_attr_t; // bthreads started with this attribute will run on stack of worker pthread and // all bthread functions that would block the bthread will block the pthread. // The bthread will not allocate its own stack, simply occupying a little meta // memory. This is required to run JNI code which checks layout of stack. The // obvious drawback is that you need more worker pthreads when you have a lot // of such bthreads. static const bthread_attr_t BTHREAD_ATTR_PTHREAD = { BTHREAD_STACKTYPE_PTHREAD, 0, NULL }; // bthreads created with following attributes will have different size of // stacks. Default is BTHREAD_ATTR_NORMAL. static const bthread_attr_t BTHREAD_ATTR_SMALL = { BTHREAD_STACKTYPE_SMALL, 0, NULL }; static const bthread_attr_t BTHREAD_ATTR_NORMAL = { BTHREAD_STACKTYPE_NORMAL, 0, NULL }; static const bthread_attr_t BTHREAD_ATTR_LARGE = { BTHREAD_STACKTYPE_LARGE, 0, NULL }; // bthreads created with this attribute will print log when it's started, // context-switched, finished. static const bthread_attr_t BTHREAD_ATTR_DEBUG = { BTHREAD_STACKTYPE_NORMAL, BTHREAD_LOG_START_AND_FINISH | BTHREAD_LOG_CONTEXT_SWITCH, NULL }; static const size_t BTHREAD_EPOLL_THREAD_NUM = 1; static const bthread_t BTHREAD_ATOMIC_INIT = 0; // Min/Max number of work pthreads. static const int BTHREAD_MIN_CONCURRENCY = 3 + BTHREAD_EPOLL_THREAD_NUM; static const int BTHREAD_MAX_CONCURRENCY = 1024; typedef struct { void* impl; // following fields are part of previous impl. and not used right now. // Don't remove them to break ABI compatibility. unsigned head; unsigned size; unsigned conflict_head; unsigned conflict_size; } bthread_list_t; // TODO: bthread_contention_site_t should be put into butex. typedef struct { int64_t duration_ns; size_t sampling_range; } bthread_contention_site_t; typedef struct { unsigned* butex; bthread_contention_site_t csite; } bthread_mutex_t; typedef struct { } bthread_mutexattr_t; typedef struct { bthread_mutex_t* m; int* seq; } bthread_cond_t; typedef struct { } bthread_condattr_t; typedef struct { } bthread_rwlock_t; typedef struct { } bthread_rwlockattr_t; typedef struct { unsigned int count; } bthread_barrier_t; typedef struct { } bthread_barrierattr_t; typedef struct { uint64_t value; } bthread_id_t; // bthread_id returned by bthread_id_create* can never be this value. // NOTE: don't confuse with INVALID_BTHREAD! static const bthread_id_t INVALID_BTHREAD_ID = {0}; #if defined(__cplusplus) // Overload operators for bthread_id_t inline bool operator==(bthread_id_t id1, bthread_id_t id2) { return id1.value == id2.value; } inline bool operator!=(bthread_id_t id1, bthread_id_t id2) { return !(id1 == id2); } inline bool operator<(bthread_id_t id1, bthread_id_t id2) { return id1.value < id2.value; } inline bool operator>(bthread_id_t id1, bthread_id_t id2) { return id2 < id1; } inline bool operator<=(bthread_id_t id1, bthread_id_t id2) { return !(id2 < id1); } inline bool operator>=(bthread_id_t id1, bthread_id_t id2) { return !(id1 < id2); } inline std::ostream& operator<<(std::ostream& os, bthread_id_t id) { return os << id.value; } #endif // __cplusplus typedef struct { void* impl; // following fields are part of previous impl. and not used right now. // Don't remove them to break ABI compatibility. unsigned head; unsigned size; unsigned conflict_head; unsigned conflict_size; } bthread_id_list_t; typedef uint64_t bthread_timer_t; #endif // BTHREAD_TYPES_H