예제 #1
0
파일: fp_rr.c 프로젝트: Neymello/Composite
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");
}
예제 #2
0
파일: mem_man.c 프로젝트: nks5295/Composite
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;
}
예제 #3
0
파일: fp_rr.c 프로젝트: Neymello/Composite
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;
}
예제 #4
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;
}
예제 #5
0
void core1_low() {
	printc("core %ld low prio thd %d running.\n", cos_cpuid(), cos_get_thd_id());
	while (1) {
		rdtscll(c1_tsc);
	}
}
예제 #6
0
파일: pong.c 프로젝트: interwq/Composite
/////////////////// 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;
}
예제 #7
0
파일: pong.c 프로젝트: interwq/Composite
//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;
}