/**
 * Assuming that the top of the stack is passed
 */
static inline struct cos_stk_item *
stkmgr_get_cos_stk_item(vaddr_t addr){
	int i;
    
	for(i = 0; i < MAX_NUM_STACKS; i++){
		if(addr == (vaddr_t)D_COS_STK_ADDR(all_stk_list[i].d_addr)){
			return &all_stk_list[i];
		}
	}

	return NULL;
}
static inline int
spd_freelist_add(spdid_t spdid, struct cos_stk_item *csi)
{
	struct spd_stk_info *ssi = get_spd_stk_info(spdid);

	/* Should either belong to this spd, or not to another (we
	 * don't want it mapped into two components) */
	assert(csi->parent_spdid == spdid || EMPTY_LIST(csi, next, prev));
	assert(ssi->ci);

	/* FIXME: race */
	csi->stk->next = (struct cos_stk*)ssi->ci->cos_stacks.freelists[0].freelist;
	ssi->ci->cos_stacks.freelists[0].freelist = D_COS_STK_ADDR(csi->d_addr);

	return 0;
}
Exemple #3
0
/* map a stack into d_spdid.
 * TODO: use cbufs. */
void *
stkmgr_grant_stack(spdid_t d_spdid)
{
	struct cbuf_comp_info *cci;
	void *p, *ret = NULL;
	vaddr_t d_addr;

	printl("stkmgr_grant_stack (cbuf)\n");

	CBUF_TAKE();
	cci = cbuf_comp_info_get(d_spdid);
	if (!cci) goto done;

	if (cbuf_alloc_map(d_spdid, &d_addr, (void**)&p, NULL, PAGE_SIZE, MAPPING_RW)) goto done;
	ret = (void*)D_COS_STK_ADDR(d_addr);

done:
	CBUF_RELEASE();
	return ret;
}
/**
 * cos_init
 */
void 
cos_init(void *arg){
	int i;
	struct cos_stk_item *stk_item;

	DOUT("<stkmgr>: STACK in cos_init\n");
   
	memset(spd_stk_info_list, 0, sizeof(struct spd_stk_info) * MAX_NUM_SPDS);
    
	for(i = 0; i < MAX_NUM_SPDS; i++){
		spd_stk_info_list[i].spdid = i;    
		INIT_LIST(&spd_stk_info_list[i].stk_list, next, prev);
		INIT_LIST(&spd_stk_info_list[i].bthd_list, next, prev);
	}

	// Initialize our free stack list
	for(i = 0; i < MAX_NUM_STACKS; i++){
        
		// put stk list is some known state
		stk_item = &(all_stk_list[i]);
		stk_item->stk  = NULL;
		INIT_LIST(stk_item, next, prev);
        
		// allocate a page
		stk_item->hptr = alloc_page();
		if (stk_item->hptr == NULL){
			DOUT("<stk_mgr>: ERROR, could not allocate stack\n"); 
		} else {
			// figure out or location of the top of the stack
			stk_item->stk = (struct cos_stk *)D_COS_STK_ADDR((char *)stk_item->hptr);
			freelist_add(stk_item);
		}
	}
	stacks_allocated = 0;

	// Map all of the spds we can into this component
	for (i = 0 ; i < MAX_NUM_SPDS ; i++) {
		spdid_t spdid;
		void *hp;

		hp = cos_get_vas_page();
		spdid = cinfo_get_spdid(i);
		if (!spdid) break;

		if(cinfo_map(cos_spd_id(), (vaddr_t)hp, spdid)){
			DOUT("Could not map cinfo page for %d\n", spdid);
			BUG();
		}
		spd_stk_info_list[spdid].ci = hp; 
        
		DOUT("mapped -- id: %ld, hp:%x, sp:%x\n",
		     spd_stk_info_list[spdid].ci->cos_this_spd_id, 
		     (unsigned int)spd_stk_info_list[spdid].ci->cos_heap_ptr,
		     (unsigned int)spd_stk_info_list[spdid].ci->cos_stacks.freelists[0].freelist);
    
		stacks_target += DEFAULT_TARGET_ALLOC;
		spd_stk_info_list[spdid].num_allocated = 0;
		spd_stk_info_list[spdid].num_desired = DEFAULT_TARGET_ALLOC;
	}

	LOCK_INIT();
	
	DOUT("Done mapping components information pages!\n");
	DOUT("<stkmgr>: init finished\n");
	return;
}
static void
stkmgr_print_ci_freelist(void)
{
	int i;
	struct spd_stk_info *info;
	//void *curr;
	struct cos_stk_item *stk_item;//, *p;

	for(i = 0; i < MAX_NUM_SPDS; i++){
		unsigned int cnt = 0;

		info = &spd_stk_info_list[i];
		if(info->ci == NULL) continue;

		if (info->num_allocated == 0 && info->num_blocked_thds == 0) continue;

		for (stk_item = FIRST_LIST(&info->stk_list, next, prev) ;
		     stk_item != &info->stk_list ; 
		     stk_item = FIRST_LIST(stk_item, next, prev)) {
			if (stk_item->stk->flags & IN_USE) cnt++;
		}
		printc("stkmgr: spdid %d w/ %d stacks, %d on freelist, %d blocked\n", 
		       i, info->num_allocated, cnt, info->num_blocked_thds);
		assert(info->num_allocated == stkmgr_num_alloc_stks(info->spdid));
#ifdef PRINT_FREELIST_ELEMENTS
		curr = (void *)info->ci->cos_stacks.freelists[0].freelist;
		if(curr) {
			DOUT("\tcomponent freelist: %p\n", curr);
			p = stk_item = stkmgr_get_cos_stk_item((vaddr_t)curr);
			while (stk_item) {
				DOUT("\tStack:\n"	\
				       "\t\tcurr: %X\n"	\
				       "\t\taddr: %X\n"	\
				       "\t\tnext: %X\n",
				       (unsigned int)stk_item->stk,
				       (unsigned int)D_COS_STK_ADDR(stk_item->d_addr),
				       (unsigned int)stk_item->stk->next);
				print_flags(stk_item->stk);
				curr = stk_item->stk->next;
				stk_item = stkmgr_get_cos_stk_item((vaddr_t)curr);
				if (p == stk_item) {
					printc("<<WTF: freelist recursion...>>\n");
					break;
				}
				p = stk_item;
			}
		}
		for (stk_item = FIRST_LIST(&info->stk_list, next, prev) ;
		     stk_item != &info->stk_list ;
		     stk_item = FIRST_LIST(stk_item, next, prev)) {
			if (!stkmgr_in_freelist(i, stk_item)) {
				DOUT("\tStack off of freelist:\n"	\
				       "\t\tcurr: %X\n"			\
				       "\t\taddr: %X\n"			\
				       "\t\tnext: %X\n",
				       (unsigned int)stk_item->stk,
				       (unsigned int)D_COS_STK_ADDR(stk_item->d_addr),
				       (unsigned int)stk_item->stk->next);
				print_flags(stk_item->stk);
			}
		}
#endif
	}

}