/** * \brief given a page, search the block to find * a better page with the same page id * * \param[in] dev uffs device * \param[in] bc block info * \param[in] page page number to be compared with * * \return the better page number, could be the same with the given page */ u16 uffs_FindBestPageInBlock(uffs_Device *dev, uffs_BlockInfo *bc, u16 page) { int i; int best; uffs_Tags *tag, *tag_old; if (page == dev->attr->pages_per_block - 1) return page; uffs_BlockInfoLoad(dev, bc, page); //load old page tag_old = GET_TAG(bc, page); for (i = dev->attr->pages_per_block - 1; i > page; i--) { uffs_BlockInfoLoad(dev, bc, i); tag = GET_TAG(bc, i); if (TAG_PAGE_ID(tag) == TAG_PAGE_ID(tag_old)) { if (TAG_PARENT(tag) == TAG_PARENT(tag_old) && TAG_SERIAL(tag) == TAG_SERIAL(tag_old) && TAG_IS_DIRTY(tag) && //0: dirty, 1:clear TAG_IS_VALID(tag_old)) { //0: valid, 1:invalid break; } } } best = i; #if 0 if (TAG_PAGE_ID(tag_old) == page) { //well, try to speed up by probing the last page .... uffs_BlockInfoLoad(dev, bc, dev->attr->pages_per_block - 1); tag = GET_TAG(bc, dev->attr->pages_per_block - 1); if (TAG_IS_VALID(tag) && TAG_IS_DIRTY(tag) && TAG_PAGE_ID(tag) == dev->attr->pages_per_block - 1) { return page; } } uffs_BlockInfoLoad(dev, bc, UFFS_ALL_PAGES); best = page; //the better page must be ahead of page, so ...i = page + 1; i < ... for (i = page + 1; i < dev->attr->pages_per_block; i++) { tag = GET_TAG(bc, i); if (TAG_PAGE_ID(tag) == TAG_PAGE_ID(tag_old)) { if (TAG_PARENT(tag) == TAG_PARENT(tag_old) && TAG_SERIAL(tag) == TAG_SERIAL(tag_old) && TAG_IS_DIRTY(tag) && //0: dirty, 1:clear TAG_IS_VALID(tag_old)) { //0: valid, 1:invalid if (i > best) best = i; } } } #endif return best; }
/** * \brief calculate data length of a file block * \param[in] dev uffs device * \param[in] bc block info */ int uffs_GetBlockFileDataLength(uffs_Device *dev, uffs_BlockInfo *bc, u8 type) { u16 page_id; u16 i; uffs_Tags *tag; int size = 0; u16 page; u16 lastPage = dev->attr->pages_per_block - 1; uffs_BlockInfoLoad(dev, bc, lastPage); tag = GET_TAG(bc, lastPage); if (TAG_IS_GOOD(tag) && TAG_PAGE_ID(tag) == lastPage) { // First try the last page. // if it's the full loaded file/data block, then we have a quick path. if (type == UFFS_TYPE_FILE) { size = dev->com.pg_data_size * (dev->attr->pages_per_block - 2) + TAG_DATA_LEN(tag); return size; } if (type == UFFS_TYPE_DATA) { size = dev->com.pg_data_size * (dev->attr->pages_per_block - 1) + TAG_DATA_LEN(tag); return size; } } // ok, it's not the full loaded file/data block, // need to read all spares.... uffs_BlockInfoLoad(dev, bc, UFFS_ALL_PAGES); tag = GET_TAG(bc, 0); if (uffs_Assert(TAG_IS_GOOD(tag), "block %d page 0 does not have good tag ?", bc->block)) { if (TAG_TYPE(tag) == UFFS_TYPE_FILE) { page_id = 1; //In file header block, file data page_id from 1 i = 1; //search from page 1 } else { page_id = 0; //in normal file data block, page_id from 0 i = 0; //in normal file data block, search from page 0 } for (; i < dev->attr->pages_per_block; i++) { tag = GET_TAG(bc, i); if (TAG_IS_GOOD(tag)) { if (page_id == TAG_PAGE_ID(tag)) { page = uffs_FindBestPageInBlock(dev, bc, i); if (uffs_Assert(page != UFFS_INVALID_PAGE, "got an invalid page ?")) { size += TAG_DATA_LEN(GET_TAG(bc, page)); page_id++; } } } } } return size; }
/** * \brief calculate data length of a file block * \param[in] dev uffs device * \param[in] bc block info */ int uffs_GetBlockFileDataLength(uffs_Device *dev, uffs_BlockInfo *bc, u8 type) { u16 page_id; u16 i; uffs_Tags *tag; int size = 0; u16 page; u16 lastPage = dev->attr->pages_per_block - 1; // TODO: Need to speed up this procedure! // First try the last page. will hit it // if it's the full loaded file/data block. uffs_BlockInfoLoad(dev, bc, lastPage); tag = GET_TAG(bc, lastPage); if (type == UFFS_TYPE_FILE) { if(TAG_PAGE_ID(tag) == (lastPage - 1) && TAG_DATA_LEN(tag) == dev->com.pg_data_size) { size = dev->com.pg_data_size * (dev->attr->pages_per_block - 1); return size; } } if (type == UFFS_TYPE_DATA) { if(TAG_PAGE_ID(tag) == lastPage && TAG_DATA_LEN(tag) == dev->com.pg_data_size) { size = dev->com.pg_data_size * dev->attr->pages_per_block; return size; } } // ok, it's not the full loaded file/data block, // need to read all spares.... uffs_BlockInfoLoad(dev, bc, UFFS_ALL_PAGES); tag = GET_TAG(bc, 0); if (TAG_TYPE(tag) == UFFS_TYPE_FILE) { page_id = 1; //In file header block, file data page_id from 1 i = 1; //search from page 1 } else { page_id = 0; //in normal file data block, page_id from 0 i = 0; //in normal file data block, search from page 0 } for (; i < dev->attr->pages_per_block; i++) { tag = GET_TAG(bc, i); if (page_id == TAG_PAGE_ID(tag)) { page = uffs_FindBestPageInBlock(dev, bc, i); size += TAG_DATA_LEN(GET_TAG(bc, page)); page_id++; } } return size; }
void wrenDumpValue(Value value) { #if WREN_NAN_TAGGING if (IS_NUM(value)) { printf("%.14g", AS_NUM(value)); } else if (IS_OBJ(value)) { dumpObject(AS_OBJ(value)); } else { switch (GET_TAG(value)) { case TAG_FALSE: printf("false"); break; case TAG_NAN: printf("NaN"); break; case TAG_NULL: printf("null"); break; case TAG_TRUE: printf("true"); break; case TAG_UNDEFINED: UNREACHABLE(); } } #else switch (value.type) { case VAL_FALSE: printf("false"); break; case VAL_NULL: printf("null"); break; case VAL_NUM: printf("%.14g", AS_NUM(value)); break; case VAL_TRUE: printf("true"); break; case VAL_OBJ: dumpObject(AS_OBJ(value)); break; case VAL_UNDEFINED: UNREACHABLE(); } #endif }
int l_remove(node_t *head, key_t key) { node_t *pred, *item, *sitem; while (TRUE) { if (!l_find(&pred, &item, head, key)) { trace("remove item failed %d\n", key); return FALSE; } sitem = STRIP_MARK(item); node_t *inext = sitem->next; /* 先标记再删除 */ if (!CAS(&sitem->next, inext, MARK(inext))) { trace("cas item %p mark failed\n", sitem->next); continue; } sitem->val = NULL_VALUE; int tag = GET_TAG(pred->next) + 1; if (CAS(&pred->next, item, TAG(STRIP_MARK(sitem->next), tag))) { trace("remove item %p success\n", item); haz_defer_free(sitem); return TRUE; } trace("cas item remove item %p failed\n", item); } return FALSE; }
/** * create a new file on a free block * \param[in] dev uffs device * \param[in] parent parent dir serial num * \param[in] serial serial num of this new file * \param[in] bc block information * \param[in] fi file information * \note parent, serial, bc must be provided before, * and all information in fi should be filled well before. */ URET uffs_CreateNewFile(uffs_Device *dev, u16 parent, u16 serial, uffs_BlockInfo *bc, uffs_FileInfo *fi) { uffs_Tags *tag; uffs_Buf *buf; uffs_BlockInfoLoad(dev, bc, 0); tag = GET_TAG(bc, 0); TAG_PARENT(tag) = parent; TAG_SERIAL(tag) = serial; TAG_DATA_LEN(tag) = sizeof(uffs_FileInfo); buf = uffs_BufGet(dev, parent, serial, 0); if (buf == NULL) { uffs_Perror(UFFS_MSG_SERIOUS, "get buf fail."); return U_FAIL; } memcpy(buf->data, fi, TAG_DATA_LEN(tag)); buf->data_len = TAG_DATA_LEN(tag); return uffs_BufPut(dev, buf); }
void wrenPrintValue(Value value) { #if WREN_NAN_TAGGING if (IS_NUM(value)) { printf("%.14g", AS_NUM(value)); } else if (IS_OBJ(value)) { printObject(AS_OBJ(value)); } else { switch (GET_TAG(value)) { case TAG_FALSE: printf("false"); break; case TAG_NAN: printf("NaN"); break; case TAG_NULL: printf("null"); break; case TAG_TRUE: printf("true"); break; } } #else switch (value.type) { case VAL_FALSE: printf("false"); break; case VAL_NULL: printf("null"); break; case VAL_NUM: printf("%.14g", AS_NUM(value)); break; case VAL_TRUE: printf("true"); break; case VAL_OBJ: { printObject(AS_OBJ(value)); } } #endif }
ObjClass* wrenGetClass(WrenVM* vm, Value value) { #if WREN_NAN_TAGGING if (IS_NUM(value)) return vm->numClass; if (IS_OBJ(value)) return getObjectClass(vm, AS_OBJ(value)); switch (GET_TAG(value)) { case TAG_FALSE: return vm->boolClass; case TAG_NAN: return vm->numClass; case TAG_NULL: return vm->nullClass; case TAG_TRUE: return vm->boolClass; } #else switch (value.type) { case VAL_FALSE: return vm->boolClass; case VAL_NULL: return vm->nullClass; case VAL_NUM: return vm->numClass; case VAL_TRUE: return vm->boolClass; case VAL_OBJ: return getObjectClass(vm, value.obj); } #endif return NULL; // Unreachable. }
//deep-bindによる。シンボルが見つからなかったら登録。 //見つかったらそこに値をいれておく。 void bindsym(int symaddr, int valaddr){ int addr,num; char *name; name = symname(symaddr); if((addr=findsym(name)) == NIL){ addr = freshcell(); SET_NAME(addr,name); SET_CDR(addr,E); E = addr; } switch(GET_TAG(valaddr)){ case NUM: { SET_TAG(addr,NUM); num = GET_NUMBER(valaddr); SET_NUMBER(addr,num); break; } case SYM: { SET_TAG(addr,SYM); name = GET_NAME(valaddr); SET_NAME(addr,name); break; } case LIS: { SET_TAG(addr,LIS); SET_BIND(addr,valaddr); break; } } }
int eval(int addr){ int res; if(atomp(addr)){ if(IS_NUMBER(addr)) return(addr); if(IS_SYMBOL(addr)){ res = findsym(GET_NAME(addr)); switch(GET_TAG(res)){ case NUM: return(makenum(GET_NUMBER(res))); case SYM: return(GET_BIND(res)); case LIS: return(GET_BIND(res)); } } } else{ if(HAS_NAME(car(addr),"quote")) return(cadr(addr)); if(subrp(car(addr))) return(apply(symname(car(addr)),evlis(cdr(addr)))); if(fsubrp(car(addr))) return(apply(symname(car(addr)),cdr(addr))); if(lambdap(car(addr))) return(apply(symname(car(addr)),evlis(cdr(addr)))); } return(NIL); }
void print(int addr){ switch(GET_TAG(addr)){ case NUM: printf("%d", GET_NUMBER(addr)); break; case SYM: printf("%s", GET_NAME(addr)); break; case LIS: { printf("("); printlist(addr); break;} } }
int parse_block(int fd1,int fd2) { char tag; read(fd1,&tag,1); switch(GET_TAG(tag)) { case 0x00: parse_titleblock(fd1); break; case 0x01: parse_sheet(fd1); break; case 0x02: parse_component(fd1,fd2); break; case 0x03: parse_wire(fd1); break; case 0x04: parse_bus(fd1); break; case 0x05: parse_junction(fd1); break; case 0x06: parse_port(fd1); break; case 0x07: parse_label(fd1); break; case 0x08: parse_entry(fd1); break; case 0x09: parse_dashed(fd1); break; case 0x0a: parse_power(fd1); break; case 0x0b: parse_text(fd1); break; case 0x0c: parse_marker(fd1); break; case 0x0f: return 0; break; default: fprintf(stderr,"\nUnknown Block Tag\n"); exit(-1); break; } return 1; }
int __stdcall RemoveTag(char * pFilename) { CSmartPtr<wchar_t> spFilename(GetUTF16FromANSI(pFilename), TRUE); int nErrorCode = ERROR_SUCCESS; CSmartPtr<IAPEDecompress> spAPEDecompress(CreateIAPEDecompress(spFilename, &nErrorCode)); if (spAPEDecompress == NULL) return -1; GET_TAG(spAPEDecompress)->Remove(FALSE); return 0; }
/** * Are all the pages in the block used ? */ UBOOL uffs_IsBlockPagesFullUsed(uffs_Device *dev, uffs_BlockInfo *bc) { uffs_Tags *tag; // if the last page is dirty, then the whole block is full uffs_BlockInfoLoad(dev, bc, dev->attr->pages_per_block - 1); tag = GET_TAG(bc, dev->attr->pages_per_block - 1); return TAG_IS_GOOD(tag) ? U_TRUE : U_FALSE; }
/** * Is this block used ? * \param[in] dev uffs device * \param[in] bc block info * \retval U_TRUE block is used * \retval U_FALSE block is free */ UBOOL uffs_IsThisBlockUsed(uffs_Device *dev, uffs_BlockInfo *bc) { uffs_Tags *tag; // if the first page is dirty, then this block is used. uffs_BlockInfoLoad(dev, bc, 0); tag = GET_TAG(bc, 0); return TAG_IS_DIRTY(tag) ? U_TRUE : U_FALSE; }
/** * get block time stamp from a exist block * \param[in] dev uffs device * \param[in] bc block info */ int uffs_GetBlockTimeStamp(uffs_Device *dev, uffs_BlockInfo *bc) { if(uffs_IsThisBlockUsed(dev, bc) == U_FALSE) return uffs_GetFirstBlockTimeStamp(); else{ uffs_BlockInfoLoad(dev, bc, 0); return TAG_BLOCK_TS(GET_TAG(bc, 0)); } }
/** * \brief given a page, search the block to find * a better page with the same page id * * \param[in] dev uffs device * \param[in] bc block info * \param[in] page page number to be compared with * * \return the better page number, could be the same with the given page. * if the given page does not have good tag, return UFFS_INVALID_PAGE. */ u16 uffs_FindBestPageInBlock(uffs_Device *dev, uffs_BlockInfo *bc, u16 page) { int i; uffs_Tags *tag, *tag_old; u16 lastPage = dev->attr->pages_per_block - 1; if (!uffs_Assert(page != UFFS_INVALID_PAGE, "invalid param !")) return page; // just in case ... uffs_BlockInfoLoad(dev, bc, page); // load old page tag_old = GET_TAG(bc, page); if (!uffs_Assert(TAG_IS_GOOD(tag_old), "try to find a invalid page ?")) return UFFS_INVALID_PAGE; if (page == lastPage) // already the last page ? return page; // check for fully loaded block, in which case the given // page id is the best page id uffs_BlockInfoLoad(dev, bc, lastPage); tag = GET_TAG(bc, lastPage); if (TAG_IS_GOOD(tag) && TAG_PAGE_ID(tag) == lastPage) return page; // block not fully loaded, search from bottom to top for (i = lastPage; i > page; i--) { uffs_BlockInfoLoad(dev, bc, i); tag = GET_TAG(bc, i); if (TAG_IS_GOOD(tag) && TAG_PAGE_ID(tag) == TAG_PAGE_ID(tag_old) && TAG_PARENT(tag) == TAG_PARENT(tag_old) && TAG_SERIAL(tag) == TAG_SERIAL(tag_old)) { break; } } return i; }
/* * mm_malloc - Allocate a new block by placing it in a free block, extending * heap if necessary. Blocks are padded with boundary tags and * lengths are changed to conform with alignment. */ void *mm_malloc(size_t size) { size_t asize; /* Adjusted block size */ size_t extendsize; /* Amount to extend heap if no fit */ void *ptr = NULL; /* Pointer */ int list = 0; /* List counter */ /* size_t checksize = size; // Copy of request size // (Reported to checking function) */ /* Filter invalid block size */ if (size == 0) return NULL; /* Adjust block size to include boundary tags and alignment requirements */ if (size <= DSIZE) { asize = 2 * DSIZE; } else { asize = DSIZE * ((size + (DSIZE) + (DSIZE - 1)) / DSIZE); } /* Select a free block of sufficient size from segregated list */ size = asize; while (list < LISTS) { if ((list == LISTS - 1) || ((size <= 1) && (free_lists[list] != NULL))) { ptr = free_lists[list]; // Ignore blocks that are too small or marked with the reallocation bit while ((ptr != NULL) && ((asize > GET_SIZE(HEAD(ptr))) || (GET_TAG(HEAD(ptr))))) { ptr = PRED(ptr); } if (ptr != NULL) break; } size >>= 1; list++; } /* Extend the heap if no free blocks of sufficient size are found */ if (ptr == NULL) { extendsize = MAX(asize, CHUNKSIZE); if ((ptr = extend_heap(extendsize)) == NULL) return NULL; } /* Place the block */ place(ptr, asize); /* // Check heap for consistency line_count++; if (CHECK && CHECK_MALLOC) { mm_check('a', ptr, checksize); } */ /* Return pointer to newly allocated block */ return ptr; }
//-----print------------------ void print(int addr){ switch(GET_TAG(addr)){ case NUM: printf("%d", GET_NUMBER(addr)); break; case SYM: printf("%s", GET_NAME(addr)); break; case SUBR: printf("<subr>"); break; case FSUBR: printf("<fsubr>"); break; case FUNC: printf("<function>"); break; case LIS: { printf("("); printlist(addr); break;} default: printf("<undef>"); break; } }
/** * \brief Is this block the last block of file ? * (no free pages, and full filled with full page_id) */ UBOOL uffs_IsDataBlockReguFull(uffs_Device *dev, uffs_BlockInfo *bc) { uffs_Tags *tag; uffs_BlockInfoLoad(dev, bc, dev->attr->pages_per_block - 1); tag = GET_TAG(bc, dev->attr->pages_per_block - 1); if (TAG_PAGE_ID(tag) == (dev->attr->pages_per_block - 1) && TAG_DATA_LEN(tag) == dev->com.pg_data_size) { return U_TRUE; } return U_FALSE; }
/* * mm_malloc - Allocate a block by incrementing the brk pointer. * Always allocate a block whose size is a multiple of the alignment. * * Role : * 1. The mm_malloc routine returns a pointer to an allocated block payload. * 2. The entire allocated block should lie within the heap region. * 3. The entire allocated block should overlap with any other chunk. * * Return value : Always return the payload pointers that are alligned to 8 bytes. */ void *mm_malloc(size_t size) { size_t asize; /* Adjusted block size */ size_t extendsize; /* Amount to extend heap if no fit */ void *ptr = NULL; /* Pointer */ // Ignore size 0 cases if (size == 0) return NULL; // Align block size if (size <= DSIZE) { asize = 2 * DSIZE; } else { asize = ALIGN(size+DSIZE); } int list = 0; size_t searchsize = asize; // Search for free block in segregated list while (list < LISTLIMIT) { if ((list == LISTLIMIT - 1) || ((searchsize <= 1) && (segregated_free_lists[list] != NULL))) { ptr = segregated_free_lists[list]; // Ignore blocks that are too small or marked with the reallocation bit while ((ptr != NULL) && ((asize > GET_SIZE(HDRP(ptr))) || (GET_TAG(HDRP(ptr))))) { ptr = PRED(ptr); } if (ptr != NULL) break; } searchsize >>= 1; list++; } // if free block is not found, extend the heap if (ptr == NULL) { extendsize = MAX(asize, CHUNKSIZE); if ((ptr = extend_heap(extendsize)) == NULL) return NULL; } // Place and divide block ptr = place(ptr, asize); // Return pointer to newly allocated block return ptr; }
/** * \brief Is the block erased ? * \param[in] dev uffs device * \param[in] bc block info * \param[in] page page number to be check * \retval U_TRUE block is erased, ready to use * \retval U_FALSE block is dirty, maybe use by file */ UBOOL uffs_IsPageErased(uffs_Device *dev, uffs_BlockInfo *bc, u16 page) { uffs_Tags *tag; uffs_BlockInfoLoad(dev, bc, page); tag = GET_TAG(bc, page); if (!TAG_IS_DIRTY(tag) && !TAG_IS_VALID(tag)) { return U_TRUE; } return U_FALSE; }
//デバッグ用 void cellprint(int addr){ switch(GET_TAG(addr)){ case EMP: printf("EMP "); break; case NUM: printf("NUM "); break; case SYM: printf("SYM "); break; case LIS: printf("LIS "); break; case FUN: printf("FUN "); break; } printf("name=%s ", GET_NAME(addr)); printf("car=%d ", GET_CAR(addr)); printf("cdr=%d ", GET_CDR(addr)); printf("num=%d ", GET_NUMBER(addr)); printf("bind=&d ", GET_BIND(addr)); printf("subr=%d\n", heap[addr].subr); }
static URET _ScanAndFixUnCleanPage(uffs_Device *dev, uffs_BlockInfo *bc) { int page; uffs_Tags *tag; struct uffs_MiniHeaderSt header; /* in most case, the valid block contents fewer free page, so it's better scan from the last page ... to page 1. note: scanning page 0 is not necessary, will check it later. The worse case: read (pages_per_block - 1) * (mini header + spares) ! most case: read one spare. */ for (page = dev->attr->pages_per_block - 1; page > 0; page--) { uffs_BlockInfoLoad(dev, bc, page); tag = GET_TAG(bc, page); if (TAG_IS_SEALED(tag)) break; // tag sealed, no unclean page in this block. if (TAG_IS_DIRTY(tag) || TAG_IS_VALID(tag)) { // tag not sealed but dirty/valid ? uffs_Perror(UFFS_MSG_NORMAL, "unclean page found, block %d page %d", bc->block, page); // ok, an unclean page found. // This unclean page can be identified by tag. // We can leave it as it is, but performing a block recover would be good ? // There won't be another unclean page in this block ... stop here. break; } // now we have a clean tag (all 0xFF ?). Need to check mini header to see if it's an unclean page. if (uffs_LoadMiniHeader(dev, bc->block, page, &header) == U_FAIL) return U_FAIL; if (header.status != 0xFF) { // page data is dirty? this is an unclean page and we should explicitly mark tag as 'dirty and invalid'. // This writing does not violate "no partial program" claim, because we are writing to a clean page spare. uffs_Perror(UFFS_MSG_NORMAL, "unclean page found, block %d page %d, mark it.", bc->block, page); uffs_FlashMarkDirtyPage(dev, bc, page); } } return U_SUCC; }
void Stage1_6Layer::PlayerWithPropsBeginContactCallback( GameObject* player, CCSprite *ob, b2Contact* contact, b2Vec2 localNormalToPlayer ) { int obType = GET_TYPE(ob); int obTag = GET_TAG(ob); if(obType == kGameObjectUnkownBrick) { if(obTag == UNKNOWN_1 && localNormalToPlayer.y > 0) { UnknownBrick* brick = (UnknownBrick*)ob; ++m_nKnockOn1; if(m_nKnockOn1 <= TOTAL_COUNT - 2) { m_needToDo.push_back(callfunc_selector(Stage1_6Layer::refresh)); } if(m_nKnockOn1 == TOTAL_COUNT - 2) { m_needToDo.push_back(callfunc_selector(Stage1_6Layer::showAnother)); } else if(m_nKnockOn1 > TOTAL_COUNT - 2) { m_needToDo.push_back(callfunc_selector(Stage1_6Layer::tooYoungTooSimple)); } } if(obTag == UNKNOWN_2 && localNormalToPlayer.y > 0) { m_nKnockOn2 = 1; m_needToDo.push_back(callfunc_selector(Stage1_6Layer::refresh)); if(!m_bHasShowMonster) { m_bHasShowMonster = true; m_needToDo.push_back(callfunc_selector(Stage1_6Layer::showMonster)); } } if (obTag == UNKNOWN_3 && localNormalToPlayer.y > 0) { m_nKnockOn3 = 1; m_needToDo.push_back(callfunc_selector(Stage1_6Layer::refresh)); } } else if(obType == kGameObjectMonster) { gotoDead(); } // 这一句要写最后 PlatformStageLayer::PlayerWithPropsBeginContactCallback(player, ob, contact, localNormalToPlayer); }
/** * \brief Is the block erased ? * \param[in] dev uffs device * \param[in] bc block info * \param[in] page page number to be check * \retval U_TRUE block is erased, ready to use * \retval U_FALSE block is dirty, maybe use by file */ UBOOL uffs_IsPageErased(uffs_Device *dev, uffs_BlockInfo *bc, u16 page) { uffs_Tags *tag; URET ret; ret = uffs_BlockInfoLoad(dev, bc, page); if (ret == U_SUCC) { tag = GET_TAG(bc, page); if (!TAG_IS_SEALED(tag) && !TAG_IS_DIRTY(tag) && !TAG_IS_VALID(tag)) { return U_TRUE; } } return U_FALSE; }
//--------eval--------------- int eval(int addr){ int res; //ctrl+cによる割り込みがあった場合 if(exit_flag == 1){ exit_flag = 0; P = addr; //後で調べられるように退避 printf("exit eval by CTRL_C_EVENT\n"); fflush(stdout); longjmp(buf,1); } if(atomp(addr)){ if(numberp(addr)) return(addr); if(symbolp(addr)){ res = findsym(addr); if(res == 0) error(CANT_FIND_ERR, "eval", addr); else switch(GET_TAG(res)){ case NUM: return(res); case SYM: return(res); case LIS: return(res); case SUBR: return(res); case FSUBR: return(res); case LAMBDA:return(GET_BIND(res)); } } } else if(listp(addr)){ if((symbolp(car(addr))) &&(HAS_NAME(car(addr),"quote"))) return(cadr(addr)); if(numberp(car(addr))) error(ARG_SYM_ERR, "eval", addr); if(subrp(car(addr))) return(apply(car(addr),evlis(cdr(addr)))); if(fsubrp(car(addr))) return(apply(car(addr),cdr(addr))); if(lambdap(car(addr))) return(apply(car(addr),evlis(cdr(addr)))); } error(CANT_FIND_ERR, "eval", addr); }
/* * coalesce - Coalesce adjacent free blocks. Sort the new free block into the * appropriate list. */ static void *coalesce(void *ptr) { size_t prev_alloc = GET_ALLOC(HEAD(PREV(ptr))); size_t next_alloc = GET_ALLOC(HEAD(NEXT(ptr))); size_t size = GET_SIZE(HEAD(ptr)); /* Return if previous and next blocks are allocated */ if (prev_alloc && next_alloc) { return ptr; } /* Do not coalesce with previous block if it is tagged */ if (GET_TAG(HEAD(PREV(ptr)))) prev_alloc = 1; /* Remove old block from list */ delete_node(ptr); /* Detect free blocks and merge, if possible */ if (prev_alloc && !next_alloc) { delete_node(NEXT(ptr)); size += GET_SIZE(HEAD(NEXT(ptr))); PUT(HEAD(ptr), PACK(size, 0)); PUT(FOOT(ptr), PACK(size, 0)); } else if (!prev_alloc && next_alloc) { delete_node(PREV(ptr)); size += GET_SIZE(HEAD(PREV(ptr))); PUT(FOOT(ptr), PACK(size, 0)); PUT(HEAD(PREV(ptr)), PACK(size, 0)); ptr = PREV(ptr); } else { delete_node(PREV(ptr)); delete_node(NEXT(ptr)); size += GET_SIZE(HEAD(PREV(ptr))) + GET_SIZE(HEAD(NEXT(ptr))); PUT(HEAD(PREV(ptr)), PACK(size, 0)); PUT(FOOT(NEXT(ptr)), PACK(size, 0)); ptr = PREV(ptr); } /* Adjust segregated linked lists */ insert_node(ptr, size); return ptr; }
/** * get free pages number * \param[in] dev uffs device * \param[in] bc block info */ int uffs_GetFreePagesCount(uffs_Device *dev, uffs_BlockInfo *bc) { int count = 0; int i; // search from the last page ... to first page for (i = dev->attr->pages_per_block - 1; i >= 0; i--) { uffs_BlockInfoLoad(dev, bc, i); if (uffs_IsPageErased(dev, bc, (u16)i) == U_TRUE) { count++; } else { if (TAG_IS_GOOD(GET_TAG(bc, i))) // it won't be any free page if we see a good tag. break; } } return count; }
//-------デバッグ用------------------ void cellprint(int addr){ switch(GET_FLAG(addr)){ case FRE: printf("FRE "); break; case USE: printf("USE "); break; } switch(GET_TAG(addr)){ case EMP: printf("EMP "); break; case NUM: printf("NUM "); break; case SYM: printf("SYM "); break; case LIS: printf("LIS "); break; case SUBR: printf("SUBR "); break; case FSUBR: printf("FSUBR "); break; case FUNC: printf("FUNC "); break; } printf("%07d ", GET_CAR(addr)); printf("%07d ", GET_CDR(addr)); printf("%07d ", GET_BIND(addr)); printf("%s \n", GET_NAME(addr)); }