/** * 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; }
/* 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 } }