📄 tinyalloc.nc
字号:
if (mStartByte >> 3 == mLast -1) { mStartByte += 8; } } mLast = (mStartByte >> 3); mStartByte = mLast << 3; //printf("\nlast = %d, startByte = %d\n", mLast, mStartByte); mContig = 0; } else if (!endFree) { //not compacting, move to next byte mStartByte += 8; mContig = 0; } } done_compact: //scanned the whole thing if (mLast >= FREE_SIZE) { mCompacting = 0; mLast = 0; mContig = 0; mNeedFree = 0; mStartByte = 0; if (mAllocing) { post allocTask(); } else { signal MemAlloc.compactComplete(); } } else { //call Leds.redToggle(); post compactTask(); //keep compacting } } void shiftUp(Handle hand, int bytes) { int16_t start = start_offset(deref(hand)); int16_t end = start + getSize(deref(hand)); int16_t newstart; int16_t newend; int8_t *p = deref(hand) - HEADER_SIZE; int8_t *startp= deref(hand) - HEADER_SIZE - bytes, *q; int cnt = getSize(deref(hand)); q = startp; while(cnt--) { *q++ = *p++; } remapAddr(*hand, startp + HEADER_SIZE); *hand = startp + HEADER_SIZE; newstart = start_offset(deref(hand)); newend = newstart + getSize(deref(hand)); //now, have to offset free bytes //do it by unsetting old bits, setting new ones setFreeBits(start,end,0); setFreeBits(newstart,newend,1); } command int16_t MemAlloc.free(Handle hand) { int8_t* startPtr; int16_t start; int16_t end; if (mAllocing) return FAIL; //don't do this if we're allocating right now if (!isValid(hand)) return FAIL; // 16 bit architecture (e.g. mote) if (sizeof(int8_t*) == sizeof(int16_t)) { startPtr = (deref(hand) - HEADER_SIZE); start = (int16_t)(startPtr - (int8_t*)&mFrame); end = start + getSize(deref(hand)); } // 32-bit architecture (e.g. x86 simulator) else if (sizeof(int8_t*) == sizeof(int32_t)) { startPtr = (deref(hand) - HEADER_SIZE); start = (int16_t)(startPtr - (int8_t*)&mFrame); end = start + getSize(deref(hand)); //printf ("freeing from %d to %d", (int16_t)start, (int16_t)end); } else { return FAIL; } //track free bytes mFreeBytes += getSize(deref(hand)); setFreeBits(start,end,0); markHandleFree(hand); return (end - start); } command result_t MemAlloc.reallocate(Handle hand, int16_t newSize) { int16_t neededBytes = newSize + HEADER_SIZE; int8_t *p = *hand; if (mAllocing) return FAIL; //don't do this if we're allocing if (neededBytes > MAX_SIZE) return FAIL; //error! mOldHandle = hand; if (neededBytes == getSize(*hand)) { post reallocDone(); return SUCCESS; //already the right size! } //adjust our counter of the number of free bytes if (neededBytes < getSize(*hand)) { int16_t oldSize = getSize(*hand); //change the size of the handle ((int16_t *)(p - HEADER_SIZE))[0] = neededBytes & 0x7FFF; //unset the used bits at the end setFreeBits(start_offset(p) + neededBytes , start_offset(p) + oldSize, 0); mFreeBytes -= neededBytes; mFreeBytes += getSize(*hand); post reallocDone(); //schedule completion event return SUCCESS; } else if (neededBytes > getSize(*hand) && !isLocked(*hand)) { //handle must be be bigger //printf("MREALLOCING\n"); //fflush(stdout); //for now, just allocate a new handle and copy the old handle over mReallocing = 1; mFreeBytes += getSize(*hand); return call MemAlloc.allocate(&mTmpHandle, newSize); } return FAIL; //failure } //task so that quick reallocations are split phase task void reallocDone() { signal MemAlloc.reallocComplete(mOldHandle, SUCCESS); } //second half of split phase reallocation int8_t finish_realloc(Handle *hand, int8_t success) { //printf ("realloced, success = %d!\n\n",success); //fflush(stdout); if (success) { int8_t *p = **hand; int8_t *q = *mOldHandle; int16_t cnt = getSize(*mOldHandle); //printf("cnt = %d\n", cnt);//fflush(stdout); while(cnt--) { *p++ = *q++; } //clear bits the old handle used setFreeBits(start_offset(*mOldHandle), start_offset(*mOldHandle) + getSize(*mOldHandle), 0); //remap old handle to the new handle remapAddr(*mOldHandle, **hand); //and finally free the new handle in the handles list, since // the user still has the pointer to the old handle markHandleFree(*hand); mReallocing = 0; signal MemAlloc.reallocComplete(mOldHandle, SUCCESS); } else { mReallocing = 0; signal MemAlloc.reallocComplete(mOldHandle, FAIL); return FAIL; } return SUCCESS; } // ------------------------- Lock / Unlock ----------------------------- // /* Lock the handle */ command result_t MemAlloc.lock(Handle handle) { // Would it be good to check previous lockedness? int8_t *ptr = deref(handle); ((int16_t *)(ptr - HEADER_SIZE))[0] |= 0x8000; return SUCCESS; } /* Unlock the handle */ command result_t MemAlloc.unlock(Handle handle) { // Would it be good to check whether it was locked? int8_t *ptr = deref(handle); ((int16_t *)(ptr - HEADER_SIZE))[0] &= 0x7FFF; return SUCCESS; } int8_t isLocked(int8_t* ptr); /* Return 1 iff h is locked, 0 o.w. */ command bool MemAlloc.isLocked(Handle h) { return isLocked(*h); } /* Return 1 iff the handle referencing ptr is locked */ int8_t isLocked(int8_t *ptr) { return (((int16_t *)(ptr - HEADER_SIZE))[0] & 0x8000) != 0; } // -------------------- Utility Functions ----------------------------- // /* Return the size of the handle h, excluding the header */ command int16_t MemAlloc.size(Handle h) { return (getSize(*h) - HEADER_SIZE); } /* Return the size of the handle referencing ptr including the header */ int16_t getSize(int8_t *ptr) { return (int16_t)(((int16_t *)(ptr - HEADER_SIZE))[0] & 0x7FFF); } /* Return the total number of free bytes (available after compaction) */ command uint16_t MemAlloc.freeBytes() { return mFreeBytes; } //return 1 iff the handle points to a valid loc, 0 o.w. int8_t isValid(Handle h) { //pointers on motes are different size than on PC if (sizeof(int8_t*) == sizeof(int32_t)) { // 32 bit arch return ((*h >= (int8_t*)(&mFrame)[0]) && (*h < (int8_t*)&(mFrame[FRAME_SIZE]))); } else if (sizeof(int8_t*) == sizeof(int16_t)) { // 16 bit arch return ((*h >= (int8_t*)(&mFrame)[0]) && (*h < (int8_t*)&(mFrame[FRAME_SIZE]))); } else { return 0; } } //move all handles that used to point to oldAddr to //point to newAddr void remapAddr(int8_t *oldAddr, int8_t *newAddr) { int16_t i; for (i = 0; i < MAX_HANDLES; i++) { if ((mHandles[i]) == oldAddr){ (mHandles[i]) = newAddr; } } } //return the handle with the address p Handle getH(int8_t *p) { int16_t i; for (i = 0; i < MAX_HANDLES;i++) { if ((mHandles[i]) == p) { return &mHandles[i]; } } return 0; } //find an unused handle slot int16_t getNewHandleIdx() { int16_t i; for (i = 0; i < MAX_HANDLES; i++) { if ((mHandles[i]) == 0) return i; } return -1; } //set the entry in mHandles to null for this handle //CAREFUL -- this is possibly a very dangerous thing to do //if someone external has a reference to hand... void markHandleFree(Handle hand) { int i; for (i = 0; i < MAX_HANDLES; i++) { if (&mHandles[i] == hand) { //note that setting to 0 here means we'll have to //walk the handle list looking for free slots later //we can't just keep a dense list of used handles //since the application maintains pointers into //the handle list mHandles[i] = 0; break; } } } /* Mark the free bits corresponding to the specified range of bytes in the allocation buffer.*/ void setFreeBits(int16_t startByte, int16_t endByte, int8_t on) { int16_t leadInBits = (startByte - ((startByte >> 3) << 3)); int16_t leadOutBits = endByte - ((endByte >> 3) << 3); int16_t i; int16_t startFree = startByte >> 3; int16_t endFree = endByte >> 3; dbg (DBG_USR1,"Setting bits from %d to %d to %d\n", startByte, endByte, on); if (startFree == endFree) { leadInBits = 8; //no leadin if both in same byte } //unroll this for efficiency, since it is called a lot if (on) { for (i = leadInBits; i < 8; i++) { mFree[startFree] |= (1 << i); } for (i = 0; i < leadOutBits; i++) { mFree[endFree] |= (1 << i); } startFree ++; for (i = startFree; i < endFree; i++) { mFree[i] = 0xFF; } } else { //! on for (i = leadInBits; i < 8; i++) { mFree[startFree] &= (0xFF ^ (1 << i)); } for (i = 0; i < leadOutBits; i++) { mFree[endFree] &= (0xFF ^ (1 << i)); } startFree ++; for (i = startFree; i < endFree; i++) { mFree[i] = 0x00; } } } //return the offset in bits into free where this starts //include the header byte int16_t start_offset(int8_t *ptr) { if (sizeof(int8_t*) == sizeof(int32_t)) { // 32 bit arch int16_t len = (int16_t)((ptr - (int8_t*)(&mFrame[0])) - HEADER_SIZE); return (int16_t)(len); } else if (sizeof(int8_t*) == sizeof(int16_t)) { // 16 bit arch int16_t len = (int16_t)((ptr - (int8_t*)(&mFrame[0])) - HEADER_SIZE); return len; } else { return -1; } }/* Print out the current free bitmap */command void allocDebug() {#ifdef kDEBUG short i,j; dbg(DBG_USR1,"Debugging:"); for (i = 0; i < FREE_SIZE; i++) { for (j = 0; j < 8; j++) { printf("%d:",(mFree[i]&1<<j) > 0?1:0); } printf(","); } dbg(DBG_USR1,"\n\n"); for (i = 0; i < FRAME_SIZE; i++) { printf("%c,",mFrame[i]); }#endif}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -