Commit ea0b8c13 authored by Xavier Thompson's avatar Xavier Thompson

Normalise indentation in CyObject.cpp

parent 39b5bfaa
...@@ -12,309 +12,308 @@ ...@@ -12,309 +12,308 @@
#endif /* Has GCC */ #endif /* Has GCC */
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
#include <atomic> #include <atomic>
#include <cstdint> #include <cstdint>
using namespace std; using namespace std;
#define CyObject_ATOMIC_REFCOUNT_TYPE atomic_int #define CyObject_ATOMIC_REFCOUNT_TYPE atomic_int
#define CyObject_NO_OWNER -1 #define CyObject_NO_OWNER -1
#define CyObject_MANY_OWNERS -2 #define CyObject_MANY_OWNERS -2
#define CyObject_WRITER_OFFSET (16) #define CyObject_WRITER_OFFSET (16)
#define CyObject_FETCH_CONTENDERS_ADD_WRITER(n) n.fetch_add((1 << CyObject_WRITER_OFFSET)) #define CyObject_FETCH_CONTENDERS_ADD_WRITER(n) n.fetch_add((1 << CyObject_WRITER_OFFSET))
#define CyObject_FETCH_CONTENDERS_SUB_WRITER(n) n.fetch_sub((1 << CyObject_WRITER_OFFSET)) #define CyObject_FETCH_CONTENDERS_SUB_WRITER(n) n.fetch_sub((1 << CyObject_WRITER_OFFSET))
#define CyObject_FETCH_CONTENDERS_ADD_READER(n) n.fetch_add(1) #define CyObject_FETCH_CONTENDERS_ADD_READER(n) n.fetch_add(1)
#define CyObject_FETCH_CONTENDERS_SUB_READER(n) n.fetch_sub(1) #define CyObject_FETCH_CONTENDERS_SUB_READER(n) n.fetch_sub(1)
#define CyObject_WRITERS_FROM_CONTENDERS(n) (n >> CyObject_WRITER_OFFSET) #define CyObject_WRITERS_FROM_CONTENDERS(n) (n >> CyObject_WRITER_OFFSET)
#define CyObject_READERS_FROM_CONTENDERS(n) (n & ((1 << CyObject_WRITER_OFFSET) -1)) #define CyObject_READERS_FROM_CONTENDERS(n) (n & ((1 << CyObject_WRITER_OFFSET) -1))
#define CyObject_HAS_WRITER_CONTENDERS(n) (n > (1 << CyObject_WRITER_OFFSET) - 1) #define CyObject_HAS_WRITER_CONTENDERS(n) (n > (1 << CyObject_WRITER_OFFSET) - 1)
#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)
#include <pthread.h> #include <pthread.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <vector> #include <vector>
#include <type_traits> #include <type_traits>
class RecursiveUpgradeableRWLock { class RecursiveUpgradeableRWLock {
pthread_mutex_t guard; pthread_mutex_t guard;
pthread_cond_t wait_readers_depart; pthread_cond_t wait_readers_depart;
pthread_cond_t wait_writer_depart; pthread_cond_t wait_writer_depart;
atomic<pid_t> owner_id; atomic<pid_t> owner_id;
atomic_int32_t readers_nb; atomic_int32_t readers_nb;
atomic_uint32_t contenders; atomic_uint32_t contenders;
uint32_t write_count; uint32_t write_count;
public: public:
RecursiveUpgradeableRWLock() { RecursiveUpgradeableRWLock() {
pthread_mutex_init(&this->guard, NULL); pthread_mutex_init(&this->guard, NULL);
pthread_cond_init(&this->wait_readers_depart, NULL); pthread_cond_init(&this->wait_readers_depart, NULL);
pthread_cond_init(&this->wait_writer_depart, NULL); pthread_cond_init(&this->wait_writer_depart, NULL);
this->owner_id = CyObject_NO_OWNER; this->owner_id = CyObject_NO_OWNER;
this->readers_nb = 0; this->readers_nb = 0;
this->write_count = 0; this->write_count = 0;
this->contenders = 0; this->contenders = 0;
} }
void wlock(); void wlock();
void rlock(); void rlock();
void unwlock(); void unwlock();
void unrlock(); void unrlock();
int tryrlock(); int tryrlock();
int trywlock(); int trywlock();
}; };
struct CyPyObject { struct CyPyObject {
PyObject_HEAD PyObject_HEAD
}; };
class CyObject : public CyPyObject { class CyObject : public CyPyObject {
private: private:
CyObject_ATOMIC_REFCOUNT_TYPE nogil_ob_refcnt; CyObject_ATOMIC_REFCOUNT_TYPE nogil_ob_refcnt;
RecursiveUpgradeableRWLock ob_lock; RecursiveUpgradeableRWLock ob_lock;
public: public:
CyObject(): nogil_ob_refcnt(1) {} CyObject(): nogil_ob_refcnt(1) {}
virtual ~CyObject() {} virtual ~CyObject() {}
void CyObject_INCREF(); void CyObject_INCREF();
int CyObject_DECREF(); int CyObject_DECREF();
int CyObject_GETREF(); int CyObject_GETREF();
void CyObject_RLOCK(); void CyObject_RLOCK();
void CyObject_WLOCK(); void CyObject_WLOCK();
void CyObject_UNRLOCK(); void CyObject_UNRLOCK();
void CyObject_UNWLOCK(); void CyObject_UNWLOCK();
int CyObject_TRYRLOCK(); int CyObject_TRYRLOCK();
int CyObject_TRYWLOCK(); int CyObject_TRYWLOCK();
}; };
/* All this is made available by member injection inside the module scope */ /* All this is made available by member injection inside the module scope */
struct ActhonResultInterface : public CyObject { struct ActhonResultInterface : public CyObject {
virtual void pushVoidStarResult(void* result) = 0; virtual void pushVoidStarResult(void* result) = 0;
virtual void* getVoidStarResult() const = 0; virtual void* getVoidStarResult() const = 0;
virtual void pushIntResult(int result) = 0; virtual void pushIntResult(int result) = 0;
virtual int getIntResult() const = 0; virtual int getIntResult() const = 0;
operator int() { return this->getIntResult(); } operator int() { return this->getIntResult(); }
operator void*() { return this->getVoidStarResult(); } operator void*() { return this->getVoidStarResult(); }
}; };
struct ActhonMessageInterface; struct ActhonMessageInterface;
struct ActhonSyncInterface : public CyObject { struct ActhonSyncInterface : public CyObject {
virtual int isActivable() const = 0; virtual int isActivable() const = 0;
virtual int isCompleted() const = 0; virtual int isCompleted() const = 0;
virtual void insertActivity(ActhonMessageInterface* msg) = 0; virtual void insertActivity(ActhonMessageInterface* msg) = 0;
virtual void removeActivity(ActhonMessageInterface* msg) = 0; virtual void removeActivity(ActhonMessageInterface* msg) = 0;
}; };
struct ActhonMessageInterface : public CyObject { struct ActhonMessageInterface : public CyObject {
ActhonSyncInterface* _sync_method; ActhonSyncInterface* _sync_method;
ActhonResultInterface* _result; ActhonResultInterface* _result;
virtual int activate() = 0; virtual int activate() = 0;
ActhonMessageInterface(ActhonSyncInterface* sync_method, ActhonMessageInterface(ActhonSyncInterface* sync_method, ActhonResultInterface* result_object);
ActhonResultInterface* result_object); virtual ~ActhonMessageInterface();
virtual ~ActhonMessageInterface(); };
};
struct ActhonQueueInterface : public CyObject {
struct ActhonQueueInterface : public CyObject { virtual void push(ActhonMessageInterface* message) = 0;
virtual void push(ActhonMessageInterface* message) = 0; virtual int activate() = 0;
virtual int activate() = 0; virtual int is_empty() const = 0;
virtual int is_empty() const = 0; };
};
struct ActhonActivableClass : public CyObject {
struct ActhonActivableClass : public CyObject { ActhonQueueInterface *_active_queue_class = NULL;
ActhonQueueInterface *_active_queue_class = NULL; ActhonResultInterface *(*_active_result_class)(void);
ActhonResultInterface *(*_active_result_class)(void); ActhonActivableClass(){} // Used in Activated classes inheritance chain (base Activated calls this, derived calls the 2 args version below)
ActhonActivableClass(){} // Used in Activated classes inheritance chain (base Activated calls this, derived calls the 2 args version below) ActhonActivableClass(ActhonQueueInterface * queue_object, ActhonResultInterface *(*result_constructor)(void));
ActhonActivableClass(ActhonQueueInterface * queue_object, ActhonResultInterface *(*result_constructor)(void)); virtual ~ActhonActivableClass();
virtual ~ActhonActivableClass(); };
};
/*
/* * Let Cy_INCREF, Cy_DECREF and Cy_XDECREF accept any argument type
* Let Cy_INCREF, Cy_DECREF and Cy_XDECREF accept any argument type * but only do the work when the argument is actually a CyObject
* but only do the work when the argument is actually a CyObject */
*/ template <typename T, typename std::enable_if<!std::is_convertible<T, CyObject*>::value, int>::type = 0>
template <typename T, typename std::enable_if<!std::is_convertible<T, CyObject*>::value, int>::type = 0> static inline void Cy_DECREF(T) {}
static inline void Cy_DECREF(T) {}
template <typename T, typename std::enable_if<!std::is_convertible<T, CyObject*>::value, int>::type = 0>
template <typename T, typename std::enable_if<!std::is_convertible<T, CyObject*>::value, int>::type = 0> static inline void Cy_XDECREF(T) {}
static inline void Cy_XDECREF(T) {}
template <typename T, typename std::enable_if<!std::is_convertible<T, CyObject*>::value, int>::type = 0>
template <typename T, typename std::enable_if<!std::is_convertible<T, CyObject*>::value, int>::type = 0> static inline void Cy_INCREF(T) {}
static inline void Cy_INCREF(T) {}
template <typename T, typename std::enable_if<std::is_convertible<T, CyObject*>::value, int>::type = 0>
template <typename T, typename std::enable_if<std::is_convertible<T, CyObject*>::value, int>::type = 0> static inline void Cy_DECREF(T &ob) {
static inline void Cy_DECREF(T &ob) {
if(ob->CyObject_DECREF())
ob = NULL;
}
template <typename T, typename std::enable_if<std::is_convertible<T, CyObject*>::value, int>::type = 0>
static inline void Cy_XDECREF(T &ob) {
if (ob != NULL) {
if(ob->CyObject_DECREF()) if(ob->CyObject_DECREF())
ob = NULL; ob = NULL;
} }
}
template <typename T, typename std::enable_if<std::is_convertible<T, CyObject*>::value, int>::type = 0>
static inline void Cy_INCREF(T ob) {
if (ob != NULL)
ob->CyObject_INCREF();
}
static inline int _Cy_GETREF(CyObject *ob) { template <typename T, typename std::enable_if<std::is_convertible<T, CyObject*>::value, int>::type = 0>
return ob->CyObject_GETREF(); static inline void Cy_XDECREF(T &ob) {
} if (ob != NULL) {
if(ob->CyObject_DECREF())
static inline void _Cy_RLOCK(CyObject *ob) { ob = NULL;
if (ob != NULL) { }
ob->CyObject_RLOCK();
}
else {
fprintf(stderr, "ERROR: trying to read lock NULL !\n");
} }
}
static inline void _Cy_WLOCK(CyObject *ob) { template <typename T, typename std::enable_if<std::is_convertible<T, CyObject*>::value, int>::type = 0>
if (ob != NULL) { static inline void Cy_INCREF(T ob) {
ob->CyObject_WLOCK(); if (ob != NULL)
ob->CyObject_INCREF();
} }
else {
fprintf(stderr, "ERROR: trying to write lock NULL !\n");
}
}
static inline void _Cy_UNRLOCK(CyObject *ob) { static inline int _Cy_GETREF(CyObject *ob) {
if (ob != NULL) { return ob->CyObject_GETREF();
ob->CyObject_UNRLOCK();
} }
else {
fprintf(stderr, "ERROR: trying to unrlock NULL !\n"); static inline void _Cy_RLOCK(CyObject *ob) {
if (ob != NULL) {
ob->CyObject_RLOCK();
}
else {
fprintf(stderr, "ERROR: trying to read lock NULL !\n");
}
} }
}
static inline void _Cy_UNWLOCK(CyObject *ob) { static inline void _Cy_WLOCK(CyObject *ob) {
if (ob != NULL) { if (ob != NULL) {
ob->CyObject_UNWLOCK(); ob->CyObject_WLOCK();
}
else {
fprintf(stderr, "ERROR: trying to write lock NULL !\n");
}
} }
else {
fprintf(stderr, "ERROR: trying to unwlock NULL !\n"); static inline void _Cy_UNRLOCK(CyObject *ob) {
if (ob != NULL) {
ob->CyObject_UNRLOCK();
}
else {
fprintf(stderr, "ERROR: trying to unrlock NULL !\n");
}
} }
}
static inline int _Cy_TRYRLOCK(CyObject *ob) { static inline void _Cy_UNWLOCK(CyObject *ob) {
return ob->CyObject_TRYRLOCK(); if (ob != NULL) {
} ob->CyObject_UNWLOCK();
}
else {
fprintf(stderr, "ERROR: trying to unwlock NULL !\n");
}
}
static inline int _Cy_TRYWLOCK(CyObject *ob) { static inline int _Cy_TRYRLOCK(CyObject *ob) {
return ob->CyObject_TRYWLOCK(); return ob->CyObject_TRYRLOCK();
} }
/* static inline int _Cy_TRYWLOCK(CyObject *ob) {
* Check whether a CyObject is an instance of a given type. return ob->CyObject_TRYWLOCK();
* }
* template:
* - T: the type
*/
template <typename T, typename O>
static inline int isinstanceof(O ob) {
static_assert(std::is_convertible<T, CyObject *>::value, "wrong type 'T' for isinstanceof[T]");
return dynamic_cast<T>(ob) != NULL;
}
/* /*
* Cast from CyObject to PyObject: * Check whether a CyObject is an instance of a given type.
* - borrow an atomic reference *
* - return a new Python reference * template:
* * - T: the type
* Note: an optimisation could be to steal a reference but only decrement */
* when Python already has a reference, because calls to this function template <typename T, typename O>
* are likely (certain even?) to be followed by a Cy_DECREF; stealing the static inline int isinstanceof(O ob) {
* reference would mean that Cy_DECREF should not be called after this. static_assert(std::is_convertible<T, CyObject *>::value, "wrong type 'T' for isinstanceof[T]");
*/ return dynamic_cast<T>(ob) != NULL;
static inline PyObject* __Pyx_PyObject_FromCyObject(CyObject * cy) {
// convert NULL to None
if (cy == NULL) {
Py_INCREF(Py_None);
return Py_None;
} }
PyObject * ob = reinterpret_cast<PyObject *>(static_cast<CyPyObject *>(cy));
// artificial atomic increment the first time Python gets a reference
if (Py_REFCNT(ob) == 0)
cy->CyObject_INCREF();
// return a new Python reference
Py_INCREF(ob);
return ob;
}
/* /*
* Cast from PyObject to CyObject: * Cast from CyObject to PyObject:
* - borrow an Python reference * - borrow an atomic reference
* - return a new atomic reference * - return a new Python reference
* *
* In case of conversion failure: * Note: an optimisation could be to steal a reference but only decrement
* - raise an exception * when Python already has a reference, because calls to this function
* - return NULL * are likely (certain even?) to be followed by a Cy_DECREF; stealing the
* * reference would mean that Cy_DECREF should not be called after this.
* template: */
* - U: the type of the underlying cypclass static inline PyObject* __Pyx_PyObject_FromCyObject(CyObject * cy) {
*/ // convert NULL to None
template <typename U> if (cy == NULL) {
static inline U* __Pyx_PyObject_AsCyObject(PyObject * ob, PyTypeObject * type) { Py_INCREF(Py_None);
// the PyObject is not of the expected type return Py_None;
if ( !PyType_IsSubtype(Py_TYPE(ob), type) ) { }
PyErr_Format(PyExc_TypeError, "Cannot convert PyObject %s to CyObject %s", Py_TYPE(ob)->tp_name, type->tp_name); PyObject * ob = reinterpret_cast<PyObject *>(static_cast<CyPyObject *>(cy));
return NULL; // artificial atomic increment the first time Python gets a reference
if (Py_REFCNT(ob) == 0)
cy->CyObject_INCREF();
// return a new Python reference
Py_INCREF(ob);
return ob;
} }
CyPyObject * wrapper = (CyPyObject *)ob; /*
U * underlying = dynamic_cast<U *>(static_cast<CyObject *>(wrapper)); * Cast from PyObject to CyObject:
* - borrow an Python reference
* - return a new atomic reference
*
* In case of conversion failure:
* - raise an exception
* - return NULL
*
* template:
* - U: the type of the underlying cypclass
*/
template <typename U>
static inline U* __Pyx_PyObject_AsCyObject(PyObject * ob, PyTypeObject * type) {
// the PyObject is not of the expected type
if ( !PyType_IsSubtype(Py_TYPE(ob), type) ) {
PyErr_Format(PyExc_TypeError, "Cannot convert PyObject %s to CyObject %s", Py_TYPE(ob)->tp_name, type->tp_name);
return NULL;
}
// failed dynamic cast: should not happen CyPyObject * wrapper = (CyPyObject *)ob;
if (underlying == NULL) { U * underlying = dynamic_cast<U *>(static_cast<CyObject *>(wrapper));
PyErr_Format(PyExc_TypeError, "Could not convert %s PyObject wrapper to its underlying CyObject", type->tp_name);
return NULL;
}
// return a new atomic reference // failed dynamic cast: should not happen
underlying->CyObject_INCREF(); if (underlying == NULL) {
return underlying; PyErr_Format(PyExc_TypeError, "Could not convert %s PyObject wrapper to its underlying CyObject", type->tp_name);
} return NULL;
}
// return a new atomic reference
underlying->CyObject_INCREF();
return underlying;
}
/* Cast argument to CyObject* type. */ /* Cast argument to CyObject* type. */
#define _CyObject_CAST(ob) ob #define _CyObject_CAST(ob) ob
#define Cy_GETREF(ob) (_Cy_GETREF(_CyObject_CAST(ob))) #define Cy_GETREF(ob) (_Cy_GETREF(_CyObject_CAST(ob)))
#define Cy_GOTREF(ob) #define Cy_GOTREF(ob)
#define Cy_XGOTREF(ob) #define Cy_XGOTREF(ob)
#define Cy_GIVEREF(ob) #define Cy_GIVEREF(ob)
#define Cy_XGIVEREF(ob) #define Cy_XGIVEREF(ob)
#define Cy_RLOCK(ob) _Cy_RLOCK(ob) #define Cy_RLOCK(ob) _Cy_RLOCK(ob)
#define Cy_WLOCK(ob) _Cy_WLOCK(ob) #define Cy_WLOCK(ob) _Cy_WLOCK(ob)
#define Cy_UNRLOCK(ob) _Cy_UNRLOCK(ob) #define Cy_UNRLOCK(ob) _Cy_UNRLOCK(ob)
#define Cy_UNWLOCK(ob) _Cy_UNWLOCK(ob) #define Cy_UNWLOCK(ob) _Cy_UNWLOCK(ob)
#define Cy_TRYRLOCK(ob) _Cy_TRYRLOCK(ob) #define Cy_TRYRLOCK(ob) _Cy_TRYRLOCK(ob)
#define Cy_TRYWLOCK(ob) _Cy_TRYWLOCK(ob) #define Cy_TRYWLOCK(ob) _Cy_TRYWLOCK(ob)
#endif #endif
#endif #endif
/////////////// CyObjects /////////////// /////////////// CyObjects ///////////////
#ifdef __cplusplus #ifdef __cplusplus
#include <cstdlib> #include <cstdlib>
#include <cstddef> #include <cstddef>
// atomic is already included in ModuleSetupCode // atomic is already included in ModuleSetupCode
// #include <atomic> // #include <atomic>
#else #else
#error C++ needed for cython+ nogil classes #error C++ needed for cython+ nogil classes
#endif /* __cplusplus */ #endif /* __cplusplus */
...@@ -505,50 +504,50 @@ void RecursiveUpgradeableRWLock::unwlock() { ...@@ -505,50 +504,50 @@ void RecursiveUpgradeableRWLock::unwlock() {
void CyObject::CyObject_INCREF() void CyObject::CyObject_INCREF()
{ {
atomic_fetch_add(&(this->nogil_ob_refcnt), 1); atomic_fetch_add(&(this->nogil_ob_refcnt), 1);
} }
int CyObject::CyObject_DECREF() int CyObject::CyObject_DECREF()
{ {
if (atomic_fetch_sub(&(this->nogil_ob_refcnt), 1) == 1) { if (atomic_fetch_sub(&(this->nogil_ob_refcnt), 1) == 1) {
delete this; delete this;
return 1; return 1;
} }
return 0; return 0;
} }
int CyObject::CyObject_GETREF() int CyObject::CyObject_GETREF()
{ {
return this->nogil_ob_refcnt; return this->nogil_ob_refcnt;
} }
void CyObject::CyObject_RLOCK() void CyObject::CyObject_RLOCK()
{ {
this->ob_lock.rlock(); this->ob_lock.rlock();
} }
void CyObject::CyObject_WLOCK() void CyObject::CyObject_WLOCK()
{ {
this->ob_lock.wlock(); this->ob_lock.wlock();
} }
int CyObject::CyObject_TRYRLOCK() int CyObject::CyObject_TRYRLOCK()
{ {
return this->ob_lock.tryrlock(); return this->ob_lock.tryrlock();
} }
int CyObject::CyObject_TRYWLOCK() int CyObject::CyObject_TRYWLOCK()
{ {
return this->ob_lock.trywlock(); return this->ob_lock.trywlock();
} }
void CyObject::CyObject_UNRLOCK() void CyObject::CyObject_UNRLOCK()
{ {
this->ob_lock.unrlock(); this->ob_lock.unrlock();
} }
void CyObject::CyObject_UNWLOCK() void CyObject::CyObject_UNWLOCK()
{ {
this->ob_lock.unwlock(); this->ob_lock.unwlock();
} }
......
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