Lines Matching refs:rwl

34 #define VALID_RWLOCK(rwl)	ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC)
51 print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
57 rwl, isc_thread_self(), operation,
63 (rwl->type == isc_rwlocktype_read ?
68 rwl->active, rwl->granted, rwl->readers_waiting,
69 rwl->writers_waiting);
74 isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
79 REQUIRE(rwl != NULL);
85 rwl->magic = 0;
88 rwl->write_requests = 0;
89 rwl->write_completions = 0;
90 rwl->cnt_and_flag = 0;
91 rwl->readers_waiting = 0;
92 rwl->write_granted = 0;
99 rwl->write_quota = write_quota;
101 rwl->type = isc_rwlocktype_read;
102 rwl->original = isc_rwlocktype_none;
103 rwl->active = 0;
104 rwl->granted = 0;
105 rwl->readers_waiting = 0;
106 rwl->writers_waiting = 0;
109 rwl->read_quota = read_quota;
112 rwl->write_quota = write_quota;
115 result = isc_mutex_init(&rwl->lock);
119 result = isc_condition_init(&rwl->readable);
129 result = isc_condition_init(&rwl->writeable);
140 rwl->magic = RWLOCK_MAGIC;
145 (void)isc_condition_destroy(&rwl->readable);
147 DESTROYLOCK(&rwl->lock);
153 isc_rwlock_destroy(isc_rwlock_t *rwl) {
154 REQUIRE(VALID_RWLOCK(rwl));
157 REQUIRE(rwl->write_requests == rwl->write_completions &&
158 rwl->cnt_and_flag == 0 && rwl->readers_waiting == 0);
160 LOCK(&rwl->lock);
161 REQUIRE(rwl->active == 0 &&
162 rwl->readers_waiting == 0 &&
163 rwl->writers_waiting == 0);
164 UNLOCK(&rwl->lock);
167 rwl->magic = 0;
168 (void)isc_condition_destroy(&rwl->readable);
169 (void)isc_condition_destroy(&rwl->writeable);
170 DESTROYLOCK(&rwl->lock);
241 isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
244 REQUIRE(VALID_RWLOCK(rwl));
248 ISC_MSG_PRELOCK, "prelock"), rwl, type);
252 if (rwl->write_requests != rwl->write_completions) {
254 LOCK(&rwl->lock);
255 if (rwl->write_requests != rwl->write_completions) {
256 rwl->readers_waiting++;
257 WAIT(&rwl->readable, &rwl->lock);
258 rwl->readers_waiting--;
260 UNLOCK(&rwl->lock);
263 cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
266 if ((rwl->cnt_and_flag & WRITER_ACTIVE) == 0)
270 LOCK(&rwl->lock);
271 rwl->readers_waiting++;
272 if ((rwl->cnt_and_flag & WRITER_ACTIVE) != 0)
273 WAIT(&rwl->readable, &rwl->lock);
274 rwl->readers_waiting--;
275 UNLOCK(&rwl->lock);
308 rwl->write_granted = 0;
313 prev_writer = isc_atomic_xadd(&rwl->write_requests, 1);
314 while (rwl->write_completions != prev_writer) {
315 LOCK(&rwl->lock);
316 if (rwl->write_completions != prev_writer) {
317 WAIT(&rwl->writeable, &rwl->lock);
318 UNLOCK(&rwl->lock);
321 UNLOCK(&rwl->lock);
326 cntflag = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0,
332 LOCK(&rwl->lock);
333 if (rwl->cnt_and_flag != 0)
334 WAIT(&rwl->writeable, &rwl->lock);
335 UNLOCK(&rwl->lock);
338 INSIST((rwl->cnt_and_flag & WRITER_ACTIVE) != 0);
339 rwl->write_granted++;
344 ISC_MSG_POSTLOCK, "postlock"), rwl, type);
351 isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
354 REQUIRE(VALID_RWLOCK(rwl));
358 ISC_MSG_PRELOCK, "prelock"), rwl, type);
363 if (rwl->write_requests != rwl->write_completions)
367 cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
373 cntflag = isc_atomic_xadd(&rwl->cnt_and_flag,
380 rwl->write_completions != rwl->write_requests) {
381 LOCK(&rwl->lock);
382 BROADCAST(&rwl->writeable);
383 UNLOCK(&rwl->lock);
390 cntflag = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0,
399 (void)isc_atomic_xadd(&rwl->write_completions, -1);
401 rwl->write_granted++;
406 ISC_MSG_POSTLOCK, "postlock"), rwl, type);
413 isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
416 REQUIRE(VALID_RWLOCK(rwl));
419 prevcnt = isc_atomic_cmpxchg(&rwl->cnt_and_flag,
433 (void)isc_atomic_xadd(&rwl->write_completions, -1);
442 isc_rwlock_downgrade(isc_rwlock_t *rwl) {
445 REQUIRE(VALID_RWLOCK(rwl));
448 prev_readers = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
453 (void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE);
454 (void)isc_atomic_xadd(&rwl->write_completions, 1);
457 LOCK(&rwl->lock);
458 if (rwl->readers_waiting > 0)
459 BROADCAST(&rwl->readable);
460 UNLOCK(&rwl->lock);
464 isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
467 REQUIRE(VALID_RWLOCK(rwl));
471 ISC_MSG_PREUNLOCK, "preunlock"), rwl, type);
475 prev_cnt = isc_atomic_xadd(&rwl->cnt_and_flag, -READER_INCR);
483 rwl->write_completions != rwl->write_requests) {
484 LOCK(&rwl->lock);
485 BROADCAST(&rwl->writeable);
486 UNLOCK(&rwl->lock);
495 (void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE);
496 (void)isc_atomic_xadd(&rwl->write_completions, 1);
498 if (rwl->write_granted >= rwl->write_quota ||
499 rwl->write_requests == rwl->write_completions ||
500 (rwl->cnt_and_flag & ~WRITER_ACTIVE) != 0) {
509 LOCK(&rwl->lock);
510 if (rwl->readers_waiting > 0) {
512 BROADCAST(&rwl->readable);
514 UNLOCK(&rwl->lock);
517 if (rwl->write_requests != rwl->write_completions &&
519 LOCK(&rwl->lock);
520 BROADCAST(&rwl->writeable);
521 UNLOCK(&rwl->lock);
528 rwl, type);
537 doit(isc_rwlock_t *rwl, isc_rwlocktype_t type, isc_boolean_t nonblock) {
542 REQUIRE(VALID_RWLOCK(rwl));
544 LOCK(&rwl->lock);
548 ISC_MSG_PRELOCK, "prelock"), rwl, type);
552 if (rwl->readers_waiting != 0)
556 ((rwl->active == 0 ||
557 (rwl->type == isc_rwlocktype_read &&
558 (rwl->writers_waiting == 0 ||
559 rwl->granted < rwl->read_quota)))))
561 rwl->type = isc_rwlocktype_read;
562 rwl->active++;
563 rwl->granted++;
570 rwl->readers_waiting++;
571 WAIT(&rwl->readable, &rwl->lock);
572 rwl->readers_waiting--;
576 if (rwl->writers_waiting != 0)
579 if (!skip && rwl->active == 0) {
580 rwl->type = isc_rwlocktype_write;
581 rwl->active = 1;
582 rwl->granted++;
589 rwl->writers_waiting++;
590 WAIT(&rwl->writeable, &rwl->lock);
591 rwl->writers_waiting--;
598 ISC_MSG_POSTLOCK, "postlock"), rwl, type);
601 UNLOCK(&rwl->lock);
607 isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
608 return (doit(rwl, type, ISC_FALSE));
612 isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
613 return (doit(rwl, type, ISC_TRUE));
617 isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
620 REQUIRE(VALID_RWLOCK(rwl));
621 LOCK(&rwl->lock);
622 REQUIRE(rwl->type == isc_rwlocktype_read);
623 REQUIRE(rwl->active != 0);
626 if (rwl->active == 1) {
627 rwl->original = (rwl->original == isc_rwlocktype_none) ?
629 rwl->type = isc_rwlocktype_write;
633 UNLOCK(&rwl->lock);
638 isc_rwlock_downgrade(isc_rwlock_t *rwl) {
640 REQUIRE(VALID_RWLOCK(rwl));
641 LOCK(&rwl->lock);
642 REQUIRE(rwl->type == isc_rwlocktype_write);
643 REQUIRE(rwl->active == 1);
645 rwl->type = isc_rwlocktype_read;
646 rwl->original = (rwl->original == isc_rwlocktype_none) ?
652 if (rwl->original == isc_rwlocktype_none &&
653 (rwl->writers_waiting == 0 || rwl->granted < rwl->read_quota) &&
654 rwl->readers_waiting > 0)
655 BROADCAST(&rwl->readable);
657 UNLOCK(&rwl->lock);
661 isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
663 REQUIRE(VALID_RWLOCK(rwl));
664 LOCK(&rwl->lock);
665 REQUIRE(rwl->type == type);
671 ISC_MSG_PREUNLOCK, "preunlock"), rwl, type);
674 INSIST(rwl->active > 0);
675 rwl->active--;
676 if (rwl->active == 0) {
677 if (rwl->original != isc_rwlocktype_none) {
678 rwl->type = rwl->original;
679 rwl->original = isc_rwlocktype_none;
681 if (rwl->type == isc_rwlocktype_read) {
682 rwl->granted = 0;
683 if (rwl->writers_waiting > 0) {
684 rwl->type = isc_rwlocktype_write;
685 SIGNAL(&rwl->writeable);
686 } else if (rwl->readers_waiting > 0) {
688 BROADCAST(&rwl->readable);
691 if (rwl->readers_waiting > 0) {
692 if (rwl->writers_waiting > 0 &&
693 rwl->granted < rwl->write_quota) {
694 SIGNAL(&rwl->writeable);
696 rwl->granted = 0;
697 rwl->type = isc_rwlocktype_read;
698 BROADCAST(&rwl->readable);
700 } else if (rwl->writers_waiting > 0) {
701 rwl->granted = 0;
702 SIGNAL(&rwl->writeable);
704 rwl->granted = 0;
708 INSIST(rwl->original == isc_rwlocktype_none);
713 rwl, type);
716 UNLOCK(&rwl->lock);
725 isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
728 REQUIRE(rwl != NULL);
733 rwl->type = isc_rwlocktype_read;
734 rwl->active = 0;
735 rwl->magic = RWLOCK_MAGIC;
741 isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
742 REQUIRE(VALID_RWLOCK(rwl));
745 if (rwl->type != isc_rwlocktype_read && rwl->active != 0)
747 rwl->type = isc_rwlocktype_read;
748 rwl->active++;
750 if (rwl->active != 0)
752 rwl->type = isc_rwlocktype_write;
753 rwl->active = 1;
759 isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
760 return (isc_rwlock_lock(rwl, type));
764 isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
767 REQUIRE(VALID_RWLOCK(rwl));
768 REQUIRE(rwl->type == isc_rwlocktype_read);
769 REQUIRE(rwl->active != 0);
772 if (rwl->active == 1)
773 rwl->type = isc_rwlocktype_write;
780 isc_rwlock_downgrade(isc_rwlock_t *rwl) {
782 REQUIRE(VALID_RWLOCK(rwl));
783 REQUIRE(rwl->type == isc_rwlocktype_write);
784 REQUIRE(rwl->active == 1);
786 rwl->type = isc_rwlocktype_read;
790 isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
791 REQUIRE(VALID_RWLOCK(rwl));
792 REQUIRE(rwl->type == type);
796 INSIST(rwl->active > 0);
797 rwl->active--;
803 isc_rwlock_destroy(isc_rwlock_t *rwl) {
804 REQUIRE(rwl != NULL);
805 REQUIRE(rwl->active == 0);
806 rwl->magic = 0;