Skip to content

Commit 0dec9cd

Browse files
committed
refine usage of instrusive list
1 parent 2263716 commit 0dec9cd

3 files changed

Lines changed: 40 additions & 43 deletions

File tree

net/utils.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ limitations under the License.
2222
#include <unistd.h>
2323

2424
#include <chrono>
25-
#include <list>
2625
#include <thread>
2726
#include <string>
2827

@@ -297,9 +296,7 @@ class DefaultResolver : public Resolver {
297296
auto ips = dnscache_.borrow(host, ctr);
298297
if (ips->empty()) LOG_ERRNO_RETURN(0, IPAddr(), "Domain resolution for '`' failed", host);
299298
SCOPED_LOCK(*ips);
300-
auto ret = ips->front();
301-
ips->node = ret->next(); // access in round robin order
302-
return ret->addr;
299+
return ips->round_robin_next()->addr;
303300
}
304301

305302
public:

thread/list.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ class intrusive_list_node : public __intrusive_list_node
266266
};
267267

268268

269-
template<typename NodeType>
269+
template<typename NodeType, bool AssertAtDestruction = true>
270270
class intrusive_list
271271
{
272272
public:
@@ -277,7 +277,7 @@ class intrusive_list
277277
{ // node (NodeType*) MUST be intrusive_list_node<T>, which
278278
// should be implicitly convertible to __intrusive_list_node*
279279
__intrusive_list_node* __node = node;
280-
assert(__node == nullptr);
280+
if (AssertAtDestruction) assert(__node == nullptr);
281281
_unused(__node);
282282
}
283283
void push_back(NodeType* ptr)
@@ -436,5 +436,15 @@ class intrusive_list
436436
}
437437
node = nullptr;
438438
}
439+
NodeType* round_robin_next() {
440+
auto x = node;
441+
node = node->next();
442+
return x;
443+
}
444+
NodeType* round_robin_prev() {
445+
auto x = node;
446+
node = node->prev();
447+
return x;
448+
}
439449
};
440450

thread/thread.cpp

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)