mirror of
https://github.com/Z3Prover/z3
synced 2025-07-03 11:25:40 +00:00
fix race condition in cooperate
This commit is contained in:
parent
6a0708fc8e
commit
37882f5afa
2 changed files with 14 additions and 24 deletions
|
@ -17,24 +17,17 @@ Notes:
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
|
#ifndef SINGLE_THREAD
|
||||||
|
|
||||||
#include "util/cooperate.h"
|
#include "util/cooperate.h"
|
||||||
#include "util/trace.h"
|
#include "util/trace.h"
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
#include <thread>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
struct cooperation_lock {
|
static std::mutex lock;
|
||||||
std::recursive_mutex m_lock;
|
static std::atomic<std::thread::id> owner_thread;
|
||||||
char const * m_task;
|
|
||||||
std::thread::id m_owner_thread;
|
|
||||||
cooperation_lock() {
|
|
||||||
m_task = nullptr;
|
|
||||||
}
|
|
||||||
~cooperation_lock() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static cooperation_lock g_lock;
|
|
||||||
|
|
||||||
bool cooperation_ctx::g_cooperate = false;
|
bool cooperation_ctx::g_cooperate = false;
|
||||||
|
|
||||||
|
@ -42,17 +35,17 @@ void cooperation_ctx::checkpoint(char const * task) {
|
||||||
SASSERT(cooperation_ctx::enabled());
|
SASSERT(cooperation_ctx::enabled());
|
||||||
|
|
||||||
std::thread::id tid = std::this_thread::get_id();
|
std::thread::id tid = std::this_thread::get_id();
|
||||||
if (g_lock.m_owner_thread == tid) {
|
if (owner_thread == tid) {
|
||||||
g_lock.m_owner_thread = std::thread::id();
|
owner_thread = std::thread::id();
|
||||||
g_lock.m_lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// this critical section is used to force the owner thread to give a chance to
|
// this critical section is used to force the owner thread to give a chance to
|
||||||
// another thread to get the lock
|
// another thread to get the lock
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
g_lock.m_lock.lock();
|
lock.lock();
|
||||||
TRACE("cooperate_detail", tout << task << ", tid: " << tid << "\n";);
|
TRACE("cooperate_detail", tout << task << ", tid: " << tid << "\n";);
|
||||||
CTRACE("cooperate", g_lock.m_task != task, tout << "moving to task: " << task << "\n";);
|
owner_thread = tid;
|
||||||
g_lock.m_owner_thread = tid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -16,10 +16,9 @@ Author:
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#ifndef COOPERATE_H_
|
#pragma once
|
||||||
#define COOPERATE_H_
|
|
||||||
|
|
||||||
#ifndef _NO_OMP_
|
#ifndef SINGLE_THREAD
|
||||||
|
|
||||||
class cooperation_ctx {
|
class cooperation_ctx {
|
||||||
static bool g_cooperate;
|
static bool g_cooperate;
|
||||||
|
@ -35,5 +34,3 @@ inline void cooperate(char const * task) {
|
||||||
#else
|
#else
|
||||||
inline void cooperate(char const *) {}
|
inline void cooperate(char const *) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue