Skip to content

Commit

Permalink
Notify scheduler if its child thread is blocked/not
Browse files Browse the repository at this point in the history
* Current state of the thread is not modified when there is a asnd
  event to it, thread state is only modified when a thread is switched
  to or from. So cos_sched_rcv will be notified if the thread is
  BLOCKED(RCVING and has no events pending) or not as opposed to
  whether the thread state is RCVING, so a scheduler can switch to it
  if it sees eligible. This may not be a permanent solution, see
  Issue gwsystems#198.
  • Loading branch information
phanikishoreg committed Sep 24, 2016
1 parent af6e7a8 commit d28f2a3
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 34 deletions.
4 changes: 2 additions & 2 deletions src/components/implementation/no_interface/vkernel/vkernel.c
Expand Up @@ -53,7 +53,7 @@ scheduler(void)
{
static unsigned int i;
thdid_t tid;
int rcving;
int blocked;
cycles_t cycles;
int index;

Expand All @@ -67,7 +67,7 @@ scheduler(void)
VM_BUDGET_FIXED, VM_PRIO_FIXED, TCAP_DELEG_YIELD)) assert(0);
}

while (cos_sched_rcv(BOOT_CAPTBL_SELF_INITRCV_BASE, &tid, &rcving, &cycles)) ;
while (cos_sched_rcv(BOOT_CAPTBL_SELF_INITRCV_BASE, &tid, &blocked, &cycles)) ;
}
}

Expand Down
21 changes: 9 additions & 12 deletions src/components/implementation/tests/micro_booter/mb_tests.c
Expand Up @@ -141,9 +141,6 @@ async_thd_fn(void *thdcap)
{
thdcap_t tc = (thdcap_t)thdcap;
arcvcap_t rc = rcc_global;
thdid_t tid;
int rcving;
cycles_t cycles;
int pending;

PRINTC("Asynchronous event thread handler.\n");
Expand All @@ -169,7 +166,7 @@ async_thd_parent(void *thdcap)
asndcap_t sc = scp_global;
int ret, pending;
thdid_t tid;
int rcving;
int blocked;
cycles_t cycles;

PRINTC("--> sending\n");
Expand All @@ -181,8 +178,8 @@ async_thd_parent(void *thdcap)
if (ret) PRINTC("--> asnd returned %d.\n", ret);
PRINTC("--> Back in the asnder.\n");
PRINTC("--> receiving to get notifications\n");
pending = cos_sched_rcv(rc, &tid, &rcving, &cycles);
PRINTC("--> pending %d, thdid %d, rcving %d, cycles %lld\n", pending, tid, rcving, cycles);
pending = cos_sched_rcv(rc, &tid, &blocked, &cycles);
PRINTC("--> pending %d, thdid %d, blocked %d, cycles %lld\n", pending, tid, blocked, cycles);

async_test_flag = 0;
while (1) cos_thd_switch(tc);
Expand Down Expand Up @@ -351,7 +348,7 @@ test_timer(void)

for (i = 0 ; i <= 16 ; i++) {
thdid_t tid;
int rcving;
int blocked;
cycles_t cycles, now;
tcap_time_t timer;

Expand All @@ -363,7 +360,7 @@ test_timer(void)
if (i > 0) t += c-p;

/* FIXME: we should avoid calling this two times in the common case, return "more evts" */
while (cos_sched_rcv(BOOT_CAPTBL_SELF_INITRCV_BASE, &tid, &rcving, &cycles) != 0) ;
while (cos_sched_rcv(BOOT_CAPTBL_SELF_INITRCV_BASE, &tid, &blocked, &cycles) != 0) ;
}

PRINTC("\tCycles per tick (1000 microseconds) = %lld\n", t/16);
Expand Down Expand Up @@ -426,7 +423,7 @@ test_budgets_single(void)
for (i = 1 ; i < 10 ; i++) {
cycles_t s, e;
thdid_t tid;
int rcving;
int blocked;
cycles_t cycles;

if (cos_tcap_transfer(bt.c.rc, BOOT_CAPTBL_SELF_INITTCAP_BASE, i * 100000, TCAP_PRIO_MAX + 2)) assert(0);
Expand All @@ -437,7 +434,7 @@ test_budgets_single(void)
PRINTC("%lld,\t", e-s);

/* FIXME: we should avoid calling this two times in the common case, return "more evts" */
while (cos_sched_rcv(BOOT_CAPTBL_SELF_INITRCV_BASE, &tid, &rcving, &cycles) != 0) ;
while (cos_sched_rcv(BOOT_CAPTBL_SELF_INITRCV_BASE, &tid, &blocked, &cycles) != 0) ;
}
PRINTC("Done.\n");
}
Expand All @@ -457,7 +454,7 @@ test_budgets_multi(void)
for (i = 1 ; i < 10 ; i++) {
tcap_res_t res;
thdid_t tid;
int rcving;
int blocked;
cycles_t cycles, s, e;

/* test both increasing budgets and constant budgets */
Expand All @@ -473,7 +470,7 @@ test_budgets_multi(void)
rdtscll(e);
PRINTC("g:%llu c:%llu p:%llu => %llu,\t", mbt.g.cyc - s, mbt.c.cyc - s, mbt.p.cyc - s, e - s);

cos_sched_rcv(BOOT_CAPTBL_SELF_INITRCV_BASE, &tid, &rcving, &cycles);
cos_sched_rcv(BOOT_CAPTBL_SELF_INITRCV_BASE, &tid, &blocked, &cycles);
PRINTC("%d=%llu\n", tid, cycles);
}
PRINTC("Done.\n");
Expand Down
2 changes: 1 addition & 1 deletion src/components/include/cos_kernel_api.h
Expand Up @@ -83,7 +83,7 @@ int cos_asnd(asndcap_t snd);
/* returns non-zero if there are still pending events (i.e. there have been pending snds) */
int cos_rcv(arcvcap_t rcv);
/* returns the same value as cos_rcv, but also information about scheduling events */
int cos_sched_rcv(arcvcap_t rcv, thdid_t *thdid, int *rcving, cycles_t *cycles);
int cos_sched_rcv(arcvcap_t rcv, thdid_t *thdid, int *blocked, cycles_t *cycles);

int cos_introspect(struct cos_compinfo *ci, capid_t cap, unsigned long op);

Expand Down
8 changes: 4 additions & 4 deletions src/components/lib/cos_kernel_api.c
Expand Up @@ -658,15 +658,15 @@ cos_asnd(asndcap_t snd)
{ return call_cap_op(snd, 0, 0, 0, 0, 0); }

int
cos_sched_rcv(arcvcap_t rcv, thdid_t *thdid, int *receiving, cycles_t *cycles)
cos_sched_rcv(arcvcap_t rcv, thdid_t *thdid, int *blocked, cycles_t *cycles)
{
unsigned long thd_state = 0;
unsigned long cyc = 0;
int ret;

ret = call_cap_retvals_asm(rcv, 0, 0, 0, 0, 0, &thd_state, &cyc);

*receiving = (int)(thd_state >> (sizeof(thd_state)*8-1));
*blocked = (int)(thd_state >> (sizeof(thd_state)*8-1));
*thdid = (thdid_t)(thd_state & ((1 << (sizeof(thdid_t)*8))-1));
*cycles = cyc;

Expand All @@ -677,11 +677,11 @@ int
cos_rcv(arcvcap_t rcv)
{
thdid_t tid = 0;
int rcving;
int blocked;
cycles_t cyc;
int ret;

ret = cos_sched_rcv(rcv, &tid, &rcving, &cyc);
ret = cos_sched_rcv(rcv, &tid, &blocked, &cyc);
assert(tid == 0);

return ret;
Expand Down
30 changes: 15 additions & 15 deletions src/kernel/include/thd.h
Expand Up @@ -177,21 +177,6 @@ thd_rcvcap_evt_dequeue(struct thread *head) { return list_dequeue(&head->event_h
static inline int
thd_track_exec(struct thread *t) { return !list_empty(&t->event_list); }

static inline int
thd_state_evt_deliver(struct thread *t, unsigned long *thd_state, unsigned long *cycles)
{
struct thread *e = thd_rcvcap_evt_dequeue(t);

assert(thd_bound2rcvcap(t));
if (!e) return 0;

*thd_state = e->tid | (e->state & THD_STATE_RCVING ? 1<<31 : 0);
*cycles = e->exec;
e->exec = 0;

return 1;
}

static int
thd_rcvcap_pending(struct thread *t)
{ return t->rcvcap.pending || list_first(&t->event_head) != NULL; }
Expand All @@ -211,6 +196,21 @@ thd_rcvcap_pending_dec(struct thread *arcvt)
return pending;
}

static inline int
thd_state_evt_deliver(struct thread *t, unsigned long *thd_state, unsigned long *cycles)
{
struct thread *e = thd_rcvcap_evt_dequeue(t);

assert(thd_bound2rcvcap(t));
if (!e) return 0;

*thd_state = e->tid | (e->state & THD_STATE_RCVING ? (thd_rcvcap_pending(e) ? 0 : 1<<31) : 0);
*cycles = e->exec;
e->exec = 0;

return 1;
}

static int
thd_activate(struct captbl *t, capid_t cap, capid_t capin, struct thread *thd, capid_t compcap, int init_data)
{
Expand Down

0 comments on commit d28f2a3

Please sign in to comment.