void acl_fiber_rwlock_wunlock(ACL_FIBER_RWLOCK *lk) { ACL_FIBER *fiber; if (lk->writer == NULL) acl_msg_fatal("%s(%d), %s: wunlock: not locked", __FILE__, __LINE__, __FUNCTION__); lk->writer = NULL; if (lk->readers != 0) acl_msg_fatal("%s(%d), %s: wunlock: readers", __FILE__, __LINE__, __FUNCTION__); while ((fiber = FIRST_FIBER(&lk->rwaiting)) != NULL) { acl_ring_detach(&lk->rwaiting); lk->readers++; acl_fiber_ready(fiber); } if (lk->readers == 0 && (fiber = FIRST_FIBER(&lk->wwaiting)) != NULL) { acl_ring_detach(&lk->wwaiting); lk->writer = fiber; acl_fiber_ready(fiber); } }
void acl_fiber_rwlock_runlock(ACL_FIBER_RWLOCK *lk) { ACL_FIBER *fiber; if (--lk->readers == 0 && (fiber = FIRST_FIBER(&lk->wwaiting))) { acl_ring_detach(&lk->wwaiting); lk->writer = fiber; acl_fiber_ready(fiber); } }
int acl_fiber_sem_post(ACL_FIBER_SEM *sem) { ACL_FIBER *ready; if (sem->tid != acl_pthread_self()) return -1; if ((ready = FIRST_FIBER(&sem->waiting)) == NULL) { sem->num++; return sem->num; } acl_ring_detach(&ready->me); acl_fiber_ready(ready); return sem->num; }
void acl_fiber_mutex_unlock(ACL_FIBER_MUTEX *lk) { ACL_FIBER *ready, *curr = acl_fiber_running(); if (lk->owner == NULL) acl_msg_fatal("%s(%d), %s: qunlock: owner NULL", __FILE__, __LINE__, __FUNCTION__); if (lk->owner != curr) acl_msg_fatal("%s(%d), %s: invalid owner=%p, %p", __FILE__, __LINE__, __FUNCTION__, lk->owner, curr); acl_ring_detach(&lk->me); ready = FIRST_FIBER(&lk->waiting); if ((lk->owner = ready) != NULL) { acl_ring_detach(&ready->me); acl_fiber_ready(ready); } }
static int __rlock(ACL_FIBER_RWLOCK *lk, int block) { ACL_FIBER *curr; if (lk->writer == NULL && FIRST_FIBER(&lk->wwaiting) == NULL) { lk->readers++; return 1; } if (!block) return 0; curr = acl_fiber_running(); acl_ring_prepend(&lk->rwaiting, &curr->me); acl_fiber_switch(); /* if switch to me because other killed me, I should detach myself */ acl_ring_detach(&curr->me); return 1; }