Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- structures:
- ```c
- /* per-domain SMR state */
- struct smr {
- seq_t rd_seq;
- seq_t wr_seq;
- };
- struct smr_cpu {
- seq_t oldest_seq; /* oldest observed sequence */
- size_t nest; /* nesting depth */
- lock_t stall_lock;
- list_t stalled; /* sorted list of trackers by seq */
- seq_t stall_min; /* quick cache of stalled head sequence */
- };
- /* trackers are on the thread stacks (or ig could have a limit of like 3 per thread), they follow a thread's smr state */
- struct smr_tracker {
- seq_t seq; /* tracker sequence */
- thread_t *td;
- struct smr_cpu *cpu; /* stall queue we're on */
- struct list_entry link;
- };
- ```
- then read side:
- ```c
- smr_enter(smr, t):
- preempt_disable();
- cpu = percpu(smr);
- if (cpu->nest++ == 0) {
- // first section
- s = atomic_load(&smr->wr_seq);
- atomic_store(cpu->oldest_seq, s);
- } else s = cpu->oldest_seq;
- t->seq = s;
- t->cpu = NULL;
- t->td = curthread;
- list_push(&curthread->smr_sections, t);
- preempt_enable();
- ```
- ```c
- smr_exit(smr, t):
- preempt_disable();
- list_remove(&curthread->smr_sections, t);
- cpu = percpu(smr);
- if (t->cpu == NULL) {
- // never got preempted
- if (--cpu->nest == 0)
- atomic_store(&cpu->oldest_seq, INVALID);
- } else {
- // we did get preempted
- lock(&t->cpu->stall_lock);
- list_remove(&t->cpu->stalled, t);
- t->cpu->stall_min = get_new_min(t->cpu);
- unlock(&t->cpu->stall_lock);
- }
- preempt_enable();
- ```
- then on preemption:
- ```c
- if (!list_empty(td->smr_sections)) {
- for each tracker t on td->smr_sections with t->cpu == NULL:
- lock(&cpu->stall_lock);
- sorted_insert(&cpu->stalled, t);
- cpu->stall_min = head of stalled
- unlock(&cpu->stall_lock);
- t->cpu = cpu;
- cpu->nest = 0;
- atomic_store(cpu->oldest_seq, INVALID);
- }
- ```
Advertisement
Add Comment
Please, Sign In to add comment