void runqueue_print(void) { struct sched_thd *t; int i = 0; printc("Core %ld: Running threads (thd, prio, ticks):\n", cos_cpuid()); for (i = 0 ; i < NUM_PRIOS ; i++) { for (t = FIRST_LIST(&PERCPU_GET(fprr_state)->priorities[i].runnable, prio_next, prio_prev) ; t != &PERCPU_GET(fprr_state)->priorities[i].runnable ; t = FIRST_LIST(t, prio_next, prio_prev)) { struct sched_accounting *sa = sched_get_accounting(t); unsigned long diff = sa->ticks - sa->prev_ticks; //if (!(diff || sa->cycles)) continue; printc("\t%d, %d, %ld+%ld/%d\n", t->id, i, diff, (unsigned long)sa->cycles, QUANTUM); sa->prev_ticks = sa->ticks; sa->cycles = 0; } } #ifdef DEFERRABLE printc("Suspended threads (thd, prio, ticks):\n"); for (t = FIRST_LIST(&PERCPU_GET(fprr_state)->servers, sched_next, sched_prev) ; t != &PERCPU_GET(fprr_state)->servers ; t = FIRST_LIST(t, sched_next, sched_prev)) { struct sched_accounting *sa = sched_get_accounting(t); unsigned long diff = sa->ticks - sa->prev_ticks; if (!sched_thd_suspended(t)) continue; if (diff || sa->cycles) { printc("\t%d, %d, %ld+%ld/%d\n", t->id, sched_get_metric(t)->priority, diff, (unsigned long)sa->cycles, QUANTUM); sa->prev_ticks = sa->ticks; sa->cycles = 0; } } #endif printc("done printing runqueue.\n"); }
void cos_upcall_fn(upcall_type_t t, void *arg1, void *arg2, void *arg3) { switch (t) { case COS_UPCALL_THD_CREATE: if (cos_cpuid() == INIT_CORE) { int i; for (i = 0; i < NUM_CPU; i++) *PERCPU_GET_TARGET(initialized_core, i) = 0; mm_init(); } else { /* Make sure that the initializing core does * the initialization before any other core * progresses */ while (*PERCPU_GET_TARGET(initialized_core, INIT_CORE) == 0) ; } *PERCPU_GET(initialized_core) = 1; break; default: BUG(); return; } return; }
int thread_param_set(struct sched_thd *t, struct sched_param_s *ps) { unsigned int prio = PRIO_LOWEST; struct sched_thd *c = sched_get_current(); assert(t); while (ps->type != SCHEDP_NOOP) { switch (ps->type) { case SCHEDP_RPRIO: case SCHEDP_RLPRIO: /* The relative priority has been converted to absolute priority in relative_prio_convert(). */ prio = ps->value; /* FIXME: When the IPI handling thread is * creating a thread (requested by a remote * core) , since we can't copy accounting info * from the actual parent (which is on a * different core), we zero the accounting * info instead of touching remote * data-structures. */ if (sched_curr_is_IPI_handler()) sched_clear_accounting(t); else memcpy(sched_get_accounting(t), sched_get_accounting(c), sizeof(struct sched_accounting)); #ifdef DEFERRABLE if (sched_get_accounting(t)->T) ADD_LIST(&PERCPU_GET(fprr_state)->servers, t, sched_next, sched_prev); #endif if (prio > PRIO_LOWEST) prio = PRIO_LOWEST; break; case SCHEDP_PRIO: /* absolute priority */ prio = ps->value; break; case SCHEDP_IDLE: /* idle thread */ prio = PRIO_LOWEST; break; case SCHEDP_INIT: /* idle thread */ prio = PRIO_LOW; break; case SCHEDP_TIMER: /* timer thread */ prio = PRIO_HIGHEST; break; case SCHEDP_IPI_HANDLER: prio = IPI_HANDLER_PRIO; break; case SCHEDP_CORE_ID: assert(ps->value == cos_cpuid()); break; #ifdef DEFERRABLE case SCHEDP_BUDGET: prio = sched_get_metric(t)->priority; sched_get_accounting(t)->C = ps->value; sched_get_accounting(t)->C_used = 0; fp_move_end_runnable(t); break; case SCHEDP_WINDOW: prio = sched_get_metric(t)->priority; sched_get_accounting(t)->T = ps->value; sched_get_accounting(t)->T_exp = 0; if (EMPTY_LIST(t, sched_next, sched_prev) && sched_get_accounting(t)->T) { ADD_LIST(&PERCPU_GET(fprr_state)->servers, t, sched_next, sched_prev); } fp_move_end_runnable(t); break; #endif default: printc("fprr: core %ld received unknown priority option\n", cos_cpuid()); prio = PRIO_LOW; } ps++; } /* printc("fprr: cpu %d has new thd %d @ prio %d\n", cos_cpuid(), t->id, prio); */ if (sched_thd_ready(t)) fp_rem_thd(t); fp_add_thd(t, prio); return 0; }
void cos_init(void) { u64_t start, end, avg, tot = 0, dev = 0, sum = 0, sum2 = 0; int i, j, k, outlier; static int first = 1; if (first) { union sched_param sp; first = 0; init_cache(); sp.c.type = SCHEDP_PRIO; sp.c.value = 20; if (sched_create_thd(cos_spd_id(), sp.v, 0, 0) == 0) BUG(); return; } //#define MPD_ENABLE #ifdef MPD_ENABLE int c0[] = {10, 11, 0}, c1[] = {0}, c2[] = {0}, c3[] = {0}, c_last[] = {0}; int *ms[] = {c0, c1, c2, c3, c_last}; for (j = 0 ; ms[j][0] ; j++) { for (i = 1 ; ms[j][i] != 0 ; i++) { if (cos_mpd_cntl(COS_MPD_MERGE, ms[j][0], ms[j][i])) { printc("merge of %d and %d failed. %d\n", ms[j][0], ms[j][i], 0); } } } printc("mpd done.\n"); #endif call_server(0,99,99,99); /* get stack */ // printc("addr %d, %d\n", &cache[1], &cache[0]); printc("optimal\n"); for (i = 16; i <= ITER; i*= 2) { sum = sum2 = 0; outlier = 0; for (k = 0; k < ITER2; k++) { rdtscll(start); struct cache_line *node = cache; for (j = 0; j < i; j++) { node->data++; node = node->next; } rdtscll(end); cost[k] = (end - start); sum+= (end - start); //call_server(i, 0, 0, 0); } for (k = 0; k < ITER2; k++) { // clean cache.... struct cache_line *node = cache; for (j = 0; j < ITER; j++) { node->data++; node = node->next; } } avg = sum / ITER2; for (k = 0; k < ITER2; k++) { if (cost[k] <= 2*avg) { sum2 += cost[k]; } else outlier++; } printc("Core %d, calling side, cache working set size %d, avg execution time %llu w/o %d outliers\n", cos_cpuid(), i * 64, sum2 / (ITER2-outlier), outlier); } printc("\nsamecore\n"); for (i = 16; i <= ITER; i*= 2) { sum = sum2 = 0; outlier = 0; for (k = 0; k < ITER2; k++) { rdtscll(start); struct cache_line *node = cache; for (j = 0; j < i; j++) { node->data++; node = node->next; } rdtscll(end); cost[k] = (end - start); sum+= (end - start); call_server(i, 0, 0, 0); } for (k = 0; k < ITER2; k++) { // clean cache.... struct cache_line *node = cache; for (j = 0; j < ITER; j++) { node->data++; node = node->next; } } avg = sum / ITER2; for (k = 0; k < ITER2; k++) { if (cost[k] <= 2*avg) { sum2 += cost[k]; } else outlier++; } printc("Core %d, calling side, cache working set size %d, avg execution time %llu w/o %d outliers\n", cos_cpuid(), i * 64, sum2 / (ITER2-outlier), outlier); } printc("\nxcore\n"); for (i = 16; i <= ITER; i*= 2) { sum = sum2 = 0; outlier = 0; for (k = 0; k < ITER2; k++) { rdtscll(start); struct cache_line *node = cache; for (j = 0; j < i; j++) { node->data++; node = node->next; } rdtscll(end); cost[k] = (end - start); sum+= (end - start); call_server_x(i, 0, 0, 0); } for (k = 0; k < ITER2; k++) { // clean cache.... struct cache_line *node = cache; for (j = 0; j < ITER; j++) { node->data++; node = node->next; } } avg = sum / ITER2; for (k = 0; k < ITER2; k++) { if (cost[k] <= 2*avg) { sum2 += cost[k]; } else outlier++; } printc("Core %d, calling side, cache working set size %d, avg execution time %llu w/o %d outliers\n", cos_cpuid(), i * 64, sum2 / (ITER2-outlier), outlier); } printc("done.\n"); /* printc("Core %ld: starting Invocations.\n", cos_cpuid()); */ /* for (i = 0 ; i < ITER ; i++) { */ /* rdtscll(start); */ /* call_server(99,99,99,99); */ /* rdtscll(end); */ /* meas[i] = end-start; */ /* } */ /* for (i = 0 ; i < ITER ; i++) tot += meas[i]; */ /* avg = tot/ITER; */ /* printc("avg %lld\n", avg); */ /* for (tot = 0, i = 0, j = 0 ; i < ITER ; i++) { */ /* if (meas[i] < avg*2) { */ /* tot += meas[i]; */ /* j++; */ /* } */ /* } */ /* printc("avg w/o %d outliers %lld\n", ITER-j, tot/j); */ /* for (i = 0 ; i < ITER ; i++) { */ /* u64_t diff = (meas[i] > avg) ? */ /* meas[i] - avg : */ /* avg - meas[i]; */ /* dev += (diff*diff); */ /* } */ /* dev /= ITER; */ /* printc("deviation^2 = %lld\n", dev); */ // printc("%d invocations took %lld\n", ITER, end-start); return; }
void core1_low() { printc("core %ld low prio thd %d running.\n", cos_cpuid(), cos_get_thd_id()); while (1) { rdtscll(c1_tsc); } }
/////////////////// move to lib later int cos_ainv_handling(void) { struct __cos_ainv_srv_thd curr_data = { .stop = 0 }; struct __cos_ainv_srv_thd *curr = &curr_data; int acap, i; int curr_thd_id = cos_get_thd_id(); assert(curr); printc("upcall thread %d (core %ld) waiting in pong...\n", cos_get_thd_id(), cos_cpuid()); sched_block(cos_spd_id(), 0); printc("upcall thread %d (core %ld) up!\n", cos_get_thd_id(), cos_cpuid()); curr->acap = acap_srv_lookup(cos_spd_id()); curr->cli_ncaps = acap_srv_ncaps(cos_spd_id()); curr->shared_page = acap_srv_lookup_ring(cos_spd_id()); assert(curr->acap && curr->cli_ncaps && curr->shared_page); init_shared_page(&curr->shared_struct, curr->shared_page); curr->fn_mapping = malloc(sizeof(vaddr_t) * curr->cli_ncaps); if (unlikely(curr->fn_mapping == NULL)) goto err_nomem; for (i = 0; i < curr->cli_ncaps; i++) { curr->fn_mapping[i] = (vaddr_t)acap_srv_fn_mapping(cos_spd_id(), i); } assert(curr); acap = curr->acap; printc("server %ld, upcall thd %d has acap %d.\n", cos_spd_id(), curr_thd_id, acap); struct shared_struct *shared_struct = &curr->shared_struct; CK_RING_INSTANCE(inv_ring) *ring = shared_struct->ring; assert(ring); struct inv_data inv; while (curr->stop == 0) { CLEAR_SERVER_ACTIVE(shared_struct); // clear active early to avoid race (and atomic instruction) if (CK_RING_DEQUEUE_SPSC(inv_ring, ring, &inv) == false) { printc("thread %d waiting on acap %d\n", cos_get_thd_id(), acap); cos_areceive(acap); printc("thread %d up from areceive\n", cos_get_thd_id()); } else { SET_SERVER_ACTIVE(shared_struct); /* setting us active */ printc("core %ld: got inv for cap %d, param %d, %d, %d, %d\n", cos_cpuid(), inv.cap, inv.params[0], inv.params[1], inv.params[2], inv.params[3]); if (unlikely(inv.cap > curr->cli_ncaps || !curr->fn_mapping[inv.cap])) { printc("Server thread %d in comp %ld: receiving invalid cap %d\n", cos_get_thd_id(), cos_spd_id(), inv.cap); } else { assert(curr->fn_mapping[inv.cap]); //execute! exec_fn((void *)curr->fn_mapping[inv.cap], 4, inv.params); // and write to the return value. } } } return 0; err_nomem: printc("couldn't allocate memory in spd %ld\n", cos_spd_id()); return -1; } void cos_upcall_fn(upcall_type_t t, void *arg1, void *arg2, void *arg3) { switch (t) { case COS_UPCALL_THD_CREATE: { cos_ainv_handling(); break; } default: /* fault! */ //*(int*)NULL = 0; printc("\n upcall type t %d\n", t); return; } return; }
//volatile int f; //void call(void) { f = *(int*)NULL; return; } int call(int a, int b, int c, int d) { printc("core %ld, spd %ld: doing call in pong with params %d %d %d %d\n", cos_cpuid(), cos_spd_id(), a,b,c,d); return a+b+c+d; }