mirror of
https://github.com/Z3Prover/z3
synced 2025-04-07 18:05:21 +00:00
88 lines
2 KiB
C++
88 lines
2 KiB
C++
/*++
|
|
Copyright (c) 2011 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
cooperate.cpp
|
|
|
|
Abstract:
|
|
|
|
Cooperation support
|
|
|
|
Author:
|
|
|
|
Leonardo (leonardo) 2011-05-17
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
#include"z3_omp.h"
|
|
#include"cooperate.h"
|
|
#include"trace.h"
|
|
#include"debug.h"
|
|
|
|
struct cooperation_lock {
|
|
omp_nest_lock_t m_lock;
|
|
char const * m_task;
|
|
volatile int m_owner_thread;
|
|
cooperation_lock() {
|
|
omp_set_nested(1);
|
|
omp_init_nest_lock(&m_lock);
|
|
m_task = 0;
|
|
m_owner_thread = -1;
|
|
}
|
|
~cooperation_lock() {
|
|
omp_destroy_nest_lock(&m_lock);
|
|
}
|
|
};
|
|
|
|
cooperation_lock g_lock;
|
|
|
|
bool cooperation_ctx::g_cooperate = false;
|
|
|
|
void cooperation_ctx::checkpoint(char const * task) {
|
|
SASSERT(cooperation_ctx::enabled());
|
|
|
|
int tid = omp_get_thread_num();
|
|
if (g_lock.m_owner_thread == tid) {
|
|
g_lock.m_owner_thread = -1;
|
|
omp_unset_nest_lock(&(g_lock.m_lock));
|
|
}
|
|
// this critical section is used to force the owner thread to give a chance to
|
|
// another thread to get the lock
|
|
#pragma omp critical (z3_cooperate)
|
|
{
|
|
omp_set_nest_lock(&(g_lock.m_lock));
|
|
TRACE("cooperate_detail", tout << task << ", tid: " << tid << "\n";);
|
|
CTRACE("cooperate", g_lock.m_task != task, tout << "moving to task: " << task << "\n";);
|
|
g_lock.m_owner_thread = tid;
|
|
}
|
|
}
|
|
|
|
cooperation_section::cooperation_section() {
|
|
SASSERT(!cooperation_ctx::enabled());
|
|
SASSERT(!omp_in_parallel());
|
|
cooperation_ctx::g_cooperate = true;
|
|
}
|
|
|
|
cooperation_section::~cooperation_section() {
|
|
SASSERT(cooperation_ctx::enabled());
|
|
cooperation_ctx::g_cooperate = false;
|
|
}
|
|
|
|
init_task::init_task(char const * task) {
|
|
SASSERT(cooperation_ctx::enabled());
|
|
SASSERT(omp_in_parallel());
|
|
cooperation_ctx::checkpoint(task);
|
|
}
|
|
|
|
init_task::~init_task() {
|
|
int tid = omp_get_thread_num();
|
|
if (g_lock.m_owner_thread == tid) {
|
|
g_lock.m_owner_thread = -1;
|
|
omp_unset_nest_lock(&(g_lock.m_lock));
|
|
}
|
|
}
|
|
|
|
|