Commit ebe5882e authored by Xavier Thompson's avatar Xavier Thompson

Add option to let CyObject locks throw a c++ exception on contention

parent 38595590
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#define CyObject_CONTENDING_WRITER_FLAG (1 << 0) #define CyObject_CONTENDING_WRITER_FLAG (1 << 0)
#define CyObject_CONTENDING_READER_FLAG (1 << 1) #define CyObject_CONTENDING_READER_FLAG (1 << 1)
#define CyObject_RAISE_ON_CONTENTION 1
#include <pthread.h> #include <pthread.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -59,7 +61,9 @@ ...@@ -59,7 +61,9 @@
int tryrlock(); int tryrlock();
int trywlock(); int trywlock();
}; };
#if CyObject_RAISE_ON_CONTENTION == 0
pthread_mutex_t CyLock::log_guard = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t CyLock::log_guard = PTHREAD_MUTEX_INITIALIZER;
#endif
struct CyPyObject { struct CyPyObject {
PyObject_HEAD PyObject_HEAD
...@@ -302,6 +306,8 @@ ...@@ -302,6 +306,8 @@
#ifdef __cplusplus #ifdef __cplusplus
#include <cstdlib> #include <cstdlib>
#include <cstddef> #include <cstddef>
#include <sstream>
#include <stdexcept>
// atomic is already included in ModuleSetupCode // atomic is already included in ModuleSetupCode
// #include <atomic> // #include <atomic>
#else #else
...@@ -320,6 +326,12 @@ void CyLock::rlock() { ...@@ -320,6 +326,12 @@ void CyLock::rlock() {
pthread_mutex_lock(&this->guard); pthread_mutex_lock(&this->guard);
if (this->write_count > 0) { if (this->write_count > 0) {
#if CyObject_RAISE_ON_CONTENTION
pid_t owner_id = this->owner_id;
std::ostringstream msg;
msg << "Data Race between [this] reader #" << caller_id << " and [other] writer #" << owner_id << " on lock " << this;
throw std::runtime_error(msg.str());
#else
pid_t owner_id = this->owner_id; pid_t owner_id = this->owner_id;
pthread_mutex_lock(&(CyLock::log_guard)); pthread_mutex_lock(&(CyLock::log_guard));
printf( printf(
...@@ -329,6 +341,7 @@ void CyLock::rlock() { ...@@ -329,6 +341,7 @@ void CyLock::rlock() {
,this, caller_id, owner_id ,this, caller_id, owner_id
); );
pthread_mutex_unlock(&(CyLock::log_guard)); pthread_mutex_unlock(&(CyLock::log_guard));
#endif
} }
while (this->write_count > 0) { while (this->write_count > 0) {
...@@ -399,6 +412,12 @@ void CyLock::wlock() { ...@@ -399,6 +412,12 @@ void CyLock::wlock() {
// The other way around could result in several writers acquiring the lock. // The other way around could result in several writers acquiring the lock.
if (this->readers_nb > 0) { if (this->readers_nb > 0) {
#if CyObject_RAISE_ON_CONTENTION
pid_t owner_id = this->owner_id;
std::ostringstream msg;
msg << "Data Race between [this] writer #" << caller_id << " and [other] reader #" << owner_id << " on lock " << this;
throw std::runtime_error(msg.str());
#else
if (owner_id == CyObject_MANY_OWNERS) { if (owner_id == CyObject_MANY_OWNERS) {
pthread_mutex_lock(&(CyLock::log_guard)); pthread_mutex_lock(&(CyLock::log_guard));
printf( printf(
...@@ -418,6 +437,7 @@ void CyLock::wlock() { ...@@ -418,6 +437,7 @@ void CyLock::wlock() {
); );
pthread_mutex_unlock(&(CyLock::log_guard)); pthread_mutex_unlock(&(CyLock::log_guard));
} }
#endif
} }
while (this->readers_nb > 0) { while (this->readers_nb > 0) {
...@@ -425,6 +445,12 @@ void CyLock::wlock() { ...@@ -425,6 +445,12 @@ void CyLock::wlock() {
} }
if (this->write_count > 0) { if (this->write_count > 0) {
#if CyObject_RAISE_ON_CONTENTION
pid_t owner_id = this->owner_id;
std::ostringstream msg;
msg << "Data Race between [this] writer #" << caller_id << " and [other] writer #" << owner_id << " on lock " << this;
throw std::runtime_error(msg.str());
#else
pthread_mutex_lock(&(CyLock::log_guard)); pthread_mutex_lock(&(CyLock::log_guard));
printf( printf(
"Contention with another writer detected while wlocking lock [%p] in thread #%d:\n" "Contention with another writer detected while wlocking lock [%p] in thread #%d:\n"
...@@ -433,6 +459,7 @@ void CyLock::wlock() { ...@@ -433,6 +459,7 @@ void CyLock::wlock() {
,this, caller_id, owner_id ,this, caller_id, owner_id
); );
pthread_mutex_unlock(&(CyLock::log_guard)); pthread_mutex_unlock(&(CyLock::log_guard));
#endif
} }
while (this->write_count > 0) { while (this->write_count > 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment