check state before wait

This commit is contained in:
白喵 2024-06-25 12:39:04 +08:00
parent 25b59ab47b
commit 919c8a68fa

View File

@ -17,8 +17,7 @@ wait_group::~wait_group(void)
void wait_group::add(int n) void wait_group::add(int n)
{ {
state_ += (long long)n << 32; long long state = state_.add_fetch((long long)n << 32);
long long state = state_;
int c = (int)(state >> 32); int c = (int)(state >> 32);
uint32_t w = (uint32_t)state; uint32_t w = (uint32_t)state;
if(c < 0){ if(c < 0){
@ -52,22 +51,26 @@ void wait_group::done(void)
void wait_group::wait(void) void wait_group::wait(void)
{ {
long long state = state_; for(;;){
int c = (int)(state >> 32); long long state = state_;
uint32_t w = (uint32_t)state; int c = (int)(state >> 32);
if(c == 0) return; uint32_t w = (uint32_t)state;
state_++; if(c == 0) return;
bool found; if(state_.cas(state, state + 1) == state){
bool found;
#ifdef _DEBUG #ifdef _DEBUG
unsigned long* tid = box_->pop(-1, &found); unsigned long* tid = box_->pop(-1, &found);
assert(found); assert(found);
delete tid; delete tid;
#else #else
(void) box_->pop(-1, &found); (void) box_->pop(-1, &found);
assert(found); assert(found);
#endif #endif
if(state_ != 0){ if(state_ != 0){
acl_msg_fatal("wait_group: wait_group is reused before previous wait has returned"); acl_msg_fatal("wait_group: wait_group is reused before previous wait has returned");
}
return;
}
} }
} }