18 #include <glog/logging.h> 25 #include <condition_variable> 33 #include <sys/prctl.h> 41 std::atomic_flag locked = ATOMIC_FLAG_INIT;
45 while (locked.test_and_set(std::memory_order_acquire)) {
49 void unlock() { locked.clear(std::memory_order_release); }
52 using timepoint_t = std::chrono::time_point<std::chrono::high_resolution_clock>;
54 inline timepoint_t now() {
return std::chrono::high_resolution_clock::now(); }
56 inline double seconds_since(timepoint_t then) {
57 return std::chrono::duration_cast<std::chrono::seconds>(now() - then)
61 inline double ms_since(timepoint_t then) {
62 return std::chrono::duration_cast<std::chrono::milliseconds>(now() - then)
66 inline double nano_since(timepoint_t then) {
67 return std::chrono::duration_cast<std::chrono::nanoseconds>(now() - then)
73 inline void split(
const std::string& s,
char delim,
74 std::vector<std::string>& elems) {
78 while (std::getline(ss, item, delim)) {
79 elems.push_back(item);
83 inline std::vector<std::string> split(
const std::string& s,
char delim) {
84 std::vector<std::string> elems;
85 split(s, delim, elems);
91 #define THREAD_RETURN_SUCCESS() \ 93 void* val = malloc(sizeof(int)); \ 94 *((int*)val) = EXIT_SUCCESS; \ 99 T sum(
const std::vector<T>& vec) {
101 for (
const T& v : vec) {
107 template <
typename T>
112 template <
typename T>
118 return value_.load();
121 void set(
const T& v) {
122 std::unique_lock<std::mutex> lock(m_);
128 bool test_and_set(
const T& test,
const T&
set) {
129 std::unique_lock<std::mutex> lock(m_);
130 if (value_ == test) {
139 bool wait_and_set(
const T& wait_for,
const T& set_to) {
140 std::unique_lock<std::mutex> lock(m_);
141 if (value_ == wait_for) {
147 T temp = value_.load();
148 cv_.wait(lock, [&] {
return value_ == wait_for; });
155 T wait_for_change(
const T& v) {
156 std::unique_lock<std::mutex> lock(m_);
157 if (value_ != v)
return value_;
158 cv_.wait(lock, [&] {
return value_ != v; });
162 void wait_until_changed_to(
const T& v) {
163 std::unique_lock<std::mutex> lock(m_);
164 if (value_ == v)
return;
165 cv_.wait(lock, [&] {
return value_ == v; });
168 void wait_until_changed_to_for(
const T& v,
int ms) {
169 std::unique_lock<std::mutex> lock(m_);
170 if (value_ == v)
return;
171 cv_.wait_for(lock, std::chrono::milliseconds(ms),
172 [&] {
return value_ = v; });
177 std::condition_variable cv_;
178 std::atomic<T> value_;
184 std::unique_lock<std::mutex> lock(m_);
190 bool raised() {
return bit_.load(); }
193 std::unique_lock<std::mutex> lock(m_);
194 cv_.wait(lock, [&] {
return bit_.load(); });
197 void wait_for(
int ms) {
198 std::unique_lock<std::mutex> lock(m_);
199 cv_.wait_for(lock, std::chrono::milliseconds(ms),
200 [&] {
return bit_.load(); });
205 std::condition_variable cv_;
206 std::atomic<bool> bit_{
false};
215 inline void print_trace() {
217 sprintf(pid_buf,
"%d", getpid());
219 name_buf[readlink(
"/proc/self/exe", name_buf, 511)] = 0;
220 prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
221 int child_pid = fork();
224 fprintf(stdout,
"stack trace for %s pid=%s\n", name_buf, pid_buf);
225 execlp(
"gdb",
"gdb",
"--batch",
"-n",
"-ex",
"thread apply all bt",
226 name_buf, pid_buf, NULL);
229 waitpid(child_pid, NULL, 0);
Definition: database.cpp:36