Skip to content

Commit

Permalink
wasp_c_extensions/_cgc: a SmartPointer has a replace method now
Browse files Browse the repository at this point in the history
  • Loading branch information
a1ezzz committed Sep 11, 2022
1 parent 775512c commit ecf0891
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 25 deletions.
144 changes: 123 additions & 21 deletions wasp_c_extensions/_cgc/cgc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,52 +150,154 @@ void ConcurrentGarbageCollector::collect()
this->parallel_gc.fetch_sub(1, std::memory_order_seq_cst);
}

SmartPointer::SmartPointer(PointerDestructor* p):
usage_counter(1),
concurrency_liveness_flag(1),
pointer(p)
ResourceSmartLock::ResourceSmartLock():
is_dead(true),
usage_counter(0),
concurrency_call_counter(0),
concurrency_liveness_flag(false)
{}

ResourceSmartLock::~ResourceSmartLock(){
assert(this->is_dead.load(std::memory_order_seq_cst) == true);
assert(this->usage_counter.load(std::memory_order_seq_cst) == 0);
};

bool ResourceSmartLock::able_to_reset(){
return (this->is_dead.load(std::memory_order_seq_cst) == true) &&
(this->usage_counter.load(std::memory_order_seq_cst) == 0) &&
(this->concurrency_call_counter.load(std::memory_order_seq_cst) == 0);
}

bool ResourceSmartLock::reset()
{
if (! p) {
throw NullPointerException();
if (
(this->is_dead.load(std::memory_order_seq_cst) == true) &&
(this->usage_counter.load(std::memory_order_seq_cst) == 0) &&
(this->concurrency_call_counter.load(std::memory_order_seq_cst) == 0)
){
this->usage_counter.store(1, std::memory_order_seq_cst);
this->is_dead.store(false, std::memory_order_seq_cst);

return true;
}

return false;
}

SmartPointer::~SmartPointer(){}
bool ResourceSmartLock::acquire(){
if (this->is_dead.load(std::memory_order_seq_cst)){
return false;
}

PointerDestructor* SmartPointer::acquire(){
PointerDestructor* pointer = this->pointer.load(std::memory_order_seq_cst);
this->concurrency_call_counter.fetch_add(1, std::memory_order_seq_cst);

if (! pointer){
return NULL;
if(! this->concurrency_liveness_flag.load(std::memory_order_seq_cst)){
this->concurrency_call_counter.fetch_sub(1, std::memory_order_seq_cst);
return false;
}

this->concurrency_liveness_flag.store(true, std::memory_order_seq_cst);

this->usage_counter.fetch_add(1, std::memory_order_seq_cst);

if(! this->concurrency_liveness_flag.load(std::memory_order_seq_cst)){
this->concurrency_call_counter.fetch_sub(1, std::memory_order_seq_cst);
return false;
}

this->concurrency_call_counter.fetch_sub(1, std::memory_order_seq_cst);

return true;
}

bool ResourceSmartLock::release(){
size_t sub_result = 0, sub_overflow_value = -1;

sub_result = this->usage_counter.fetch_sub(1, std::memory_order_seq_cst);
assert(sub_result != sub_overflow_value);

if (sub_result > 1){
return false;
}

this->concurrency_liveness_flag.store(false, std::memory_order_seq_cst);

if (this->usage_counter.load(std::memory_order_seq_cst)){
return false; // parallel acquire on the way
}

this->is_dead.store(true, std::memory_order_seq_cst);

return true;
}

SmartPointer::SmartPointer(PointerDestructor* p):
pointer_lock(),
pointer(p),
zombie_pointer(NULL)
{
if (! p) {
throw NullPointerException();
}

assert(this->pointer_lock.reset());
}

SmartPointer::~SmartPointer(){}

PointerDestructor* SmartPointer::acquire(){
PointerDestructor* pointer = this->pointer.load(std::memory_order_seq_cst);

if (! pointer){ // TODO: check is it require?!
return NULL;
}

return pointer;
if (this->pointer_lock.acquire()){
return pointer;
}
return NULL;
}

void SmartPointer::release(){

PointerDestructor* pointer = this->pointer.load(std::memory_order_seq_cst);
PointerDestructor *pointer = this->pointer.load(std::memory_order_seq_cst);

assert(pointer != NULL);

if (this->usage_counter.fetch_sub(1, std::memory_order_seq_cst) > 1){
return;
if (this->pointer_lock.release()){
if (this->pointer.compare_exchange_strong(pointer, NULL, std::memory_order_seq_cst)){
pointer->destroyable();
return;
}
assert(0); // there must not be a concurrency at this point
}
}

this->concurrency_liveness_flag.store(false, std::memory_order_seq_cst);
bool SmartPointer::replace(PointerDestructor* new_ptr){

if (this->usage_counter.load(std::memory_order_seq_cst)){
return; // parallel acquire on the way
PointerDestructor* null_ptr = this->pointer.load(std::memory_order_seq_cst);

assert(new_ptr != NULL);

if (null_ptr){
return false;
}

pointer->destroyable();
this->pointer.store(NULL, std::memory_order_seq_cst);
}
if (this->pointer_lock.able_to_reset()){ // TODO: check if it is possible to reduce ifs
if (this->zombie_pointer.compare_exchange_strong(null_ptr, new_ptr, std::memory_order_seq_cst)) {
if (this->pointer_lock.able_to_reset()){
if (this->pointer_lock.reset()){
if (this->pointer.compare_exchange_strong(null_ptr, new_ptr, std::memory_order_seq_cst)){
this->zombie_pointer.store(NULL, std::memory_order_seq_cst);
return true;
}
assert(0);
}
assert(0);
}
this->zombie_pointer.store(NULL, std::memory_order_seq_cst);
}
}

return false;
}
32 changes: 28 additions & 4 deletions wasp_c_extensions/_cgc/cgc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,43 @@ class ConcurrentGCItem:
void destroyable();
};

class ResourceSmartLock{

std::atomic<bool> is_dead; // marks this resource as unavailable
std::atomic<size_t> usage_counter; // this counter shows how many pending "releases" there are.
// This counter is for managing acquire-release concurrency
std::atomic<size_t> concurrency_call_counter; // this counter show how many calls to the "acquire" method
// are at the moment. This counter is for managing acquire-reset concurrency
std::atomic<bool> concurrency_liveness_flag; // TODO: check that concurrency_call_counter is not enough

public:
ResourceSmartLock();
virtual ~ResourceSmartLock();

bool able_to_reset();

bool reset();

bool acquire();

bool release();
};

class SmartPointer
{

std::atomic<size_t> usage_counter;
std::atomic<bool> concurrency_liveness_flag;
ResourceSmartLock pointer_lock;
std::atomic<PointerDestructor*> pointer;
std::atomic<PointerDestructor*> zombie_pointer;

public:
SmartPointer(PointerDestructor*);
virtual ~SmartPointer();

PointerDestructor* acquire();
void release();
virtual PointerDestructor* acquire();
virtual void release();

bool replace(PointerDestructor* new_ptr);
};

}; // namespace wasp::cgc
Expand Down

0 comments on commit ecf0891

Please sign in to comment.