Lines Matching defs:cxq
63 // queue -- called the cxq -- with CAS and then spin/park.
65 // of the cxq. Colocating the LockByte with the cxq precludes certain races.
94 // -- The contention queue (cxq) contains recently-arrived threads (RATs).
95 // Threads on the cxq eventually drain into the EntryList.
96 // -- Invariant: a thread appears on at most one list -- cxq, EntryList
133 // * The cxq can have multiple concurrent "pushers" but only one concurrent
135 // More precisely, the CAS-based "push" onto cxq is ABA-oblivious.
139 // * Taken together, the cxq and the EntryList constitute or form a
142 // Threads in lock() enqueue onto cxq while threads in unlock() will
155 // drains the cxq into the EntryList, and orders or reorders the threads on the
164 // unlinked from the EntryList and cxq by some previous unlock() operations.
167 // -- Threads on the EntryList or cxq are _not allowed to attempt lock acquisition.
172 // drain the cxq into the EntryList. By convention, only this thread, the holder of
174 // RATs on the cxq into the EntryList. This avoids ABA corruption on the cxq as
191 // transfers threads from the WaitSet to either the EntryList or cxq.
442 if (u == v) return 0 ; // indicate pushed onto cxq
473 // Either Enqueue Self on cxq or acquire the outer lock.
474 // LockWord encoding = (cxq,LOCKBYTE)
486 // ondeck implies not resident on cxq and not resident on EntryList
503 // preemptively drain the cxq into the EntryList.
566 intptr_t cxq = _LockWord.FullWord ;
567 if (((cxq & ~_LBIT)|UNS(_EntryList)) == 0) {
568 return ; // normal fast-path exit - cxq and EntryList both empty
570 if (cxq & _LBIT) {
579 // OnDeck serves as lock to protect cxq and EntryList.
580 // Only the holder of OnDeck can manipulate EntryList or detach the RATs from cxq.
613 cxq = _LockWord.FullWord ;
614 if (cxq & _LBIT) return ;
620 cxq = _LockWord.FullWord ;
621 if ((cxq & ~_LBIT) != 0) {
622 // The EntryList is empty but the cxq is populated.
623 // drain RATs from cxq into EntryList
627 if (cxq & _LBIT) goto Punt ;
628 const intptr_t vfy = CASPTR (&_LockWord, cxq, cxq & _LBIT) ;
629 if (vfy == cxq) break ;
630 cxq = vfy ;
633 // pushing themselves onto the cxq or from lock-unlock operations.
635 // the cxq is prepend-only -- the head is volatile but the interior
636 // of the cxq is stable. In theory if we encounter interference from threads
637 // pushing onto cxq we could simply break off the original cxq suffix and
639 // on the high-traffic LockWord variable. For instance lets say the cxq is "ABCD"
640 // when we first fetch cxq above. Between the fetch -- where we observed "A"
642 // yielding cxq = "PQRABCD". In this case we could simply set A.ListNext
643 // null, leaving cxq = "PQRA" and transfer the "BCD" segment to the EntryList.
644 // Note too, that it's safe for this thread to traverse the cxq
648 // We don't currently reorder the cxq segment as we move it onto
653 _EntryList = List = (ParkEvent *)(cxq & ~_LBIT) ;
658 // cxq|EntryList is empty.
659 // w == NULL implies that cxq|EntryList == NULL in the past.
661 // A thread could have added itself to cxq since this thread previously checked.
662 // Detect and recover by refetching cxq.
668 // Resample LockWord/cxq to recover from possible race.
671 // lock, but encounter contention and enqueue itself on cxq. T2 then drops the
675 // Note that we don't need to recheck EntryList, just cxq.
678 cxq = _LockWord.FullWord ;
679 if ((cxq & ~_LBIT) != 0 && (cxq & _LBIT) == 0) {
691 // Transfer one thread from the WaitSet to the EntryList or cxq.
692 // Currently we just unlink the head of the WaitSet and prepend to the cxq.
700 // push nfy onto the cxq
708 // Note that setting Notified before pushing nfy onto the cxq is
725 // to the cxq. This could be done more efficiently with a single bulk en-mass transfer,
728 // waitset is "ABCD" and the cxq is "XYZ". After a notifyAll() the waitset
729 // will be empty and the cxq will be "DCBAXYZ". This is benign, of course.
758 // on both the WaitSet and the EntryList|cxq at the same time.. That is, a thread
789 // T1 from the WaitSet to the cxq. T2 then drops the lock. T1 resumes,
790 // and then finds *itself* on the cxq. During the course of a normal
792 // or cxq, but in the case of wait() it's possible.
809 // 2. On the cxq or EntryList
810 // 3. Not resident on cxq, EntryList or WaitSet, but in the OnDeck position.
821 // end up on the cxq|EntryList -- it can't be on two lists at once.
848 // A prior notify() operation moved ESelf from the WaitSet to the cxq.
849 // ESelf is now on the cxq, EntryList or at the OnDeck position.
1052 // Either Enqueue Self on cxq or acquire the outer lock.
1059 // ondeck implies not resident on cxq and not resident on EntryList