4683 // * Use Taura-Oyama-Yonenzawa locks.
4684 // * It's possible to construct a 1-0 lock if we encode the lockword as
4685 // (List,LockByte). Acquire will CAS the full lockword while Release
4686 // will STB 0 into the LockByte. The 1-0 scheme admits stranding, so
4687 // acquiring threads use timers (ParkTimed) to detect and recover from
4688 // the stranding window. Thread/Node structures must be aligned on 256-byte
4689 // boundaries by using placement-new.
4690 // * Augment MCS with advisory back-link fields maintained with CAS().
4691 // Pictorially: LockWord -> T1 <-> T2 <-> T3 <-> ... <-> Tn <-> Owner.
4692 // The validity of the backlinks must be ratified before we trust the value.
4693 // If the backlinks are invalid the exiting thread must back-track through the
4694 // the forward links, which are always trustworthy.
4695 // * Add a successor indication. The LockWord is currently encoded as
4696 // (List, LOCKBIT:1). We could also add a SUCCBIT or an explicit _succ variable
4697 // to provide the usual futile-wakeup optimization.
4698 // See RTStt for details.
4699 // * Consider schedctl.sc_nopreempt to cover the critical section.
4700 //
4701
4702
4703 typedef volatile intptr_t MutexT; // Mux Lock-word
4704 const intptr_t LOCKBIT = 1;
4705
4706 void Thread::muxAcquire(volatile intptr_t * Lock, const char * LockName) {
4707 intptr_t w = Atomic::cmpxchg(LOCKBIT, Lock, (intptr_t)0);
4708 if (w == 0) return;
4709 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg(w|LOCKBIT, Lock, w) == w) {
4710 return;
4711 }
4712
4713 TEVENT(muxAcquire - Contention);
4714 ParkEvent * const Self = Thread::current()->_MuxEvent;
4715 assert((intptr_t(Self) & LOCKBIT) == 0, "invariant");
4716 for (;;) {
4717 int its = (os::is_MP() ? 100 : 0) + 1;
4718
4719 // Optional spin phase: spin-then-park strategy
4720 while (--its >= 0) {
4721 w = *Lock;
4722 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg(w|LOCKBIT, Lock, w) == w) {
4723 return;
|
4683 // * Use Taura-Oyama-Yonenzawa locks.
4684 // * It's possible to construct a 1-0 lock if we encode the lockword as
4685 // (List,LockByte). Acquire will CAS the full lockword while Release
4686 // will STB 0 into the LockByte. The 1-0 scheme admits stranding, so
4687 // acquiring threads use timers (ParkTimed) to detect and recover from
4688 // the stranding window. Thread/Node structures must be aligned on 256-byte
4689 // boundaries by using placement-new.
4690 // * Augment MCS with advisory back-link fields maintained with CAS().
4691 // Pictorially: LockWord -> T1 <-> T2 <-> T3 <-> ... <-> Tn <-> Owner.
4692 // The validity of the backlinks must be ratified before we trust the value.
4693 // If the backlinks are invalid the exiting thread must back-track through the
4694 // the forward links, which are always trustworthy.
4695 // * Add a successor indication. The LockWord is currently encoded as
4696 // (List, LOCKBIT:1). We could also add a SUCCBIT or an explicit _succ variable
4697 // to provide the usual futile-wakeup optimization.
4698 // See RTStt for details.
4699 // * Consider schedctl.sc_nopreempt to cover the critical section.
4700 //
4701
4702
4703 const intptr_t LOCKBIT = 1;
4704
4705 void Thread::muxAcquire(volatile intptr_t * Lock, const char * LockName) {
4706 intptr_t w = Atomic::cmpxchg(LOCKBIT, Lock, (intptr_t)0);
4707 if (w == 0) return;
4708 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg(w|LOCKBIT, Lock, w) == w) {
4709 return;
4710 }
4711
4712 TEVENT(muxAcquire - Contention);
4713 ParkEvent * const Self = Thread::current()->_MuxEvent;
4714 assert((intptr_t(Self) & LOCKBIT) == 0, "invariant");
4715 for (;;) {
4716 int its = (os::is_MP() ? 100 : 0) + 1;
4717
4718 // Optional spin phase: spin-then-park strategy
4719 while (--its >= 0) {
4720 w = *Lock;
4721 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg(w|LOCKBIT, Lock, w) == w) {
4722 return;
|