MCPcopy Create free account
hub / github.com/apache/brpc / butex_wait_from_pthread

Function butex_wait_from_pthread

src/bthread/butex.cpp:612–668  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

610}
611
612static int butex_wait_from_pthread(TaskGroup* g, Butex* b, int expected_value,
613 const timespec* abstime, bool prepend) {
614 TaskMeta* task = NULL;
615 ButexPthreadWaiter pw;
616 pw.tid = 0;
617 pw.sig.store(PTHREAD_NOT_SIGNALLED, butil::memory_order_relaxed);
618 int rc = 0;
619
620 if (g) {
621 task = g->current_task();
622 task->current_waiter.store(&pw, butil::memory_order_release);
623 }
624 b->waiter_lock.lock();
625 if (b->value.load(butil::memory_order_relaxed) != expected_value) {
626 b->waiter_lock.unlock();
627 errno = EWOULDBLOCK;
628 rc = -1;
629 } else if (task != NULL && task->interrupted) {
630 b->waiter_lock.unlock();
631 // Race with set and may consume multiple interruptions, which are OK.
632 task->interrupted = false;
633 errno = EINTR;
634 rc = -1;
635 } else {
636 if (prepend) {
637 b->waiters.Prepend(&pw);
638 } else {
639 b->waiters.Append(&pw);
640 }
641 pw.container.store(b, butil::memory_order_relaxed);
642 b->waiter_lock.unlock();
643
644#ifdef SHOW_BTHREAD_BUTEX_WAITER_COUNT_IN_VARS
645 bvar::Adder<int64_t>& num_waiters = butex_waiter_count();
646 num_waiters << 1;
647#endif
648 rc = wait_pthread(pw, abstime);
649#ifdef SHOW_BTHREAD_BUTEX_WAITER_COUNT_IN_VARS
650 num_waiters << -1;
651#endif
652 }
653 if (task) {
654 // If current_waiter is NULL, TaskGroup::interrupt() is running and
655 // using pw, spin until current_waiter != NULL.
656 BT_LOOP_WHEN(task->current_waiter.exchange(
657 NULL, butil::memory_order_acquire) == NULL,
658 30/*nops before sched_yield*/);
659 if (task->interrupted) {
660 task->interrupted = false;
661 if (rc == 0) {
662 errno = EINTR;
663 return -1;
664 }
665 }
666 }
667 return rc;
668}
669

Callers 1

butex_waitFunction · 0.85

Calls 9

wait_pthreadFunction · 0.85
current_taskMethod · 0.80
storeMethod · 0.45
lockMethod · 0.45
loadMethod · 0.45
unlockMethod · 0.45
PrependMethod · 0.45
AppendMethod · 0.45
exchangeMethod · 0.45

Tested by

no test coverage detected