uprw
#define UPRW(rw) struct uprw *uprw = *(struct uprw **)rw
struct uprw *uprw;
uprw = rump_hypermalloc(sizeof(*uprw), 0, true, "rwinit");
memset(uprw, 0, sizeof(*uprw));
rumpuser_cv_init(&uprw->uprw_rucv_reader);
rumpuser_cv_init(&uprw->uprw_rucv_writer);
memcpy(rw, &uprw, sizeof(void *));
rumpuser_cv_destroy(uprw->uprw_rucv_reader);
rumpuser_cv_destroy(uprw->uprw_rucv_writer);
rump_hyperfree(uprw, sizeof(*uprw));
rucv = uprw->uprw_rucv_reader;
wp = &uprw->uprw_rwant;
rucv = uprw->uprw_rucv_writer;
wp = &uprw->uprw_wwant;
if (uprw->uprw_owner == NULL && uprw->uprw_wwant == 0) {
uprw->uprw_readers++;
if (uprw->uprw_owner == NULL && uprw->uprw_readers == 0) {
uprw->uprw_owner = curlwp;
if (uprw->uprw_readers > 0) {
uprw->uprw_readers--;
KASSERT(uprw->uprw_owner == curlwp);
uprw->uprw_owner = NULL;
if (uprw->uprw_wwant) {
rumpuser_cv_signal(uprw->uprw_rucv_writer);
} else if (uprw->uprw_rwant) {
rumpuser_cv_signal(uprw->uprw_rucv_reader);
if (uprw->uprw_readers == 1 && uprw->uprw_owner == NULL) {
uprw->uprw_readers = 0;
uprw->uprw_owner = curlwp;
return uprw->uprw_owner == curlwp;
return uprw->uprw_readers > 0;
return uprw->uprw_owner || uprw->uprw_readers;