@@ -513,10 +513,7 @@ namespace photon
513513 }
514514 };
515515
516- static spinlock vcpu_list_lock; // lock when add, remove, iterate next
517- static rwlock vcpu_list_rwlock; // rlock when iterate, wlock when remove
518- static vcpu_t * pvcpu = nullptr ;
519- struct vcpu_t : public vcpu_base {
516+ struct vcpu_t0 : public vcpu_base {
520517// offset 16B
521518 SleepQueue sleepq; // sizeof(sleepq) should be 24: ptr, size and capcity
522519// offset 40B
@@ -529,9 +526,10 @@ namespace photon
529526 // threads scheduled by other vCPUs are added to standbyq by those vCPUs,
530527 // then moved to runq later by this vCPU at some proper occasion.
531528 thread_list standbyq;
529+ };
530+ struct vcpu_t : public vcpu_t0 , intrusive_list_node<vcpu_t > {
532531// offset 64B
533- vcpu_t *prev, *next;
534-
532+ // vcpu_t *prev, *next; // embedded in intrusive_list_node
535533 template <typename T>
536534 void move_to_standbyq_atomic (T x)
537535 {
@@ -559,42 +557,34 @@ namespace photon
559557 }
560558
561559 NullEventEngine _default_event_engine;
562-
563- vcpu_t (uint8_t flags_) {
564- flags = flags_;
565- master_event_engine = &_default_event_engine;
566- SCOPED_LOCK (vcpu_list_lock);
567- if (!pvcpu) {
568- pvcpu = prev = next = this ;
569- } else {
570- next = pvcpu;
571- prev = pvcpu->prev ;
572- prev->next = this ;
573- pvcpu->prev = this ;
574- }
575- }
576- void remove_from_list () {
577- scoped_rwlock _ (vcpu_list_rwlock, WLOCK );
578- SCOPED_LOCK (vcpu_list_lock);
579- auto pr = prev;
580- auto nx = next;
581- pr->next = nx;
582- nx->prev = pr;
583- if (pvcpu == this )
584- pvcpu = (nx != this ) ? nx : nullptr ;
585- }
586-
587560 bool is_master_event_engine_default () {
588561 return &_default_event_engine == master_event_engine;
589562 }
590-
591563 void reset_master_event_engine_default () {
592564 auto & mee = master_event_engine;
593565 if (&_default_event_engine == mee) return ;
594566 delete mee;
595567 mee = &_default_event_engine;
596568 }
569+
570+ static spinlock vcpu_list_lock; // lock when add, remove, iterate next
571+ static rwlock vcpu_list_rwlock; // rlock when iterate, wlock when remove
572+ static intrusive_list<vcpu_t , false > pvcpu;
573+ vcpu_t (uint8_t flags_) {
574+ flags = flags_;
575+ master_event_engine = &_default_event_engine;
576+ SCOPED_LOCK (vcpu_list_lock);
577+ pvcpu.push_back (this );
578+ }
579+ void go_offline () { // by removing this from list
580+ scoped_rwlock _ (vcpu_list_rwlock, WLOCK );
581+ SCOPED_LOCK (vcpu_list_lock);
582+ pvcpu.erase (this );
583+ }
597584 };
585+ spinlock vcpu_t ::vcpu_list_lock;
586+ rwlock vcpu_t ::vcpu_list_rwlock;
587+ intrusive_list<vcpu_t , false > vcpu_t ::pvcpu;
598588
599589 class RunQ {
600590 public:
@@ -1971,8 +1961,8 @@ R"(
19711961 assert (CURRENT == vcpu->idle_worker );
19721962 if (0 == (vcpu->flags & VCPU_ENABLE_ACTIVE_WORK_STEALING ))
19731963 return false ;
1974- scoped_rwlock _ (vcpu_list_rwlock, RLOCK );
1975- auto u = vcpu->next ;
1964+ scoped_rwlock _ (vcpu_t :: vcpu_list_rwlock, RLOCK );
1965+ auto u = vcpu->next () ;
19761966 while (u != vcpu) {
19771967 if (0 == (u->flags & VCPU_ENABLE_PASSIVE_WORK_STEALING ))
19781968 continue ;
@@ -1981,8 +1971,8 @@ R"(
19811971 vcpu->idle_worker ->insert_list_tail (th);
19821972 return true ;
19831973 }
1984- SCOPED_LOCK (vcpu_list_lock);
1985- u = u->next ;
1974+ SCOPED_LOCK (vcpu_t :: vcpu_list_lock);
1975+ u = u->next () ;
19861976 }
19871977 return false ;
19881978 }
@@ -2124,7 +2114,7 @@ R"(
21242114 assert (!AtomicRunQ (rq).single ());
21252115 assert (vcpu->nthreads == 2 ); // idler & current alive
21262116 deallocate_tls (&rq.current ->tls );
2127- vcpu->remove_from_list ();
2117+ vcpu->go_offline ();
21282118 vcpu->state = states::DONE ; // instruct idle_worker to exit
21292119 thread_join (vcpu->idle_worker );
21302120 rq.current ->state = states::DONE ;
0 commit comments