From 39fbfd5eb7e45d73d38e8a2ce9437a3d7e1b8e91 Mon Sep 17 00:00:00 2001 From: pohly Date: Thu, 05 May 2005 14:39:33 +0000 Subject: new opie-reader sources with support for ArriereGo, Reb input and flite output plugins --- (limited to 'noncore/apps/opie-reader/SubAlloc.h') diff --git a/noncore/apps/opie-reader/SubAlloc.h b/noncore/apps/opie-reader/SubAlloc.h new file mode 100644 index 0000000..ded2b73 --- a/dev/null +++ b/noncore/apps/opie-reader/SubAlloc.h @@ -0,0 +1,201 @@ +/**************************************************************************** + * This file is part of PPMd project * + * Written and distributed to public domain by Dmitry Shkarin 1997, * + * 1999-2001 * + * Contents: memory allocation routines * + ****************************************************************************/ + +enum { UNIT_SIZE=12, N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4, + N_INDEXES=N1+N2+N3+N4 }; + +#pragma pack(1) +struct BLK_NODE { + DWORD Stamp; + BLK_NODE* next; + BOOL avail() const { return (next != NULL); } + void link(BLK_NODE* p) { p->next=next; next=p; } + void unlink() { next=next->next; } + void* remove() { + BLK_NODE* p=next; unlink(); + Stamp--; return p; + } + inline void insert(void* pv,int NU); +} BList[N_INDEXES]; +struct MEM_BLK: public BLK_NODE { DWORD NU; } _PACK_ATTR; +#pragma pack() + +static BYTE Indx2Units[N_INDEXES], Units2Indx[128]; // constants +static DWORD GlueCount, SubAllocatorSize=0; +static BYTE* HeapStart, * pText, * UnitsStart, * LoUnit, * HiUnit; + +inline void PrefetchData(void* Addr) +{ +#if defined(_USE_PREFETCHING) + BYTE PrefetchByte = *(volatile BYTE*) Addr; +#endif /* defined(_USE_PREFETCHING) */ +} +inline void BLK_NODE::insert(void* pv,int NU) { + MEM_BLK* p=(MEM_BLK*) pv; link(p); + p->Stamp=~0UL; p->NU=NU; + Stamp++; +} +inline UINT U2B(UINT NU) { return 8*NU+4*NU; } +inline void SplitBlock(void* pv,UINT OldIndx,UINT NewIndx) +{ + UINT i, k, UDiff=Indx2Units[OldIndx]-Indx2Units[NewIndx]; + BYTE* p=((BYTE*) pv)+U2B(Indx2Units[NewIndx]); + if (Indx2Units[i=Units2Indx[UDiff-1]] != UDiff) { + k=Indx2Units[--i]; BList[i].insert(p,k); + p += U2B(k); UDiff -= k; + } + BList[Units2Indx[UDiff-1]].insert(p,UDiff); +} +DWORD _STDCALL GetUsedMemory() +{ + DWORD i, RetVal=SubAllocatorSize-(HiUnit-LoUnit)-(UnitsStart-pText); + for (i=0;i < N_INDEXES;i++) + RetVal -= UNIT_SIZE*Indx2Units[i]*BList[i].Stamp; + return RetVal; +} +void _STDCALL StopSubAllocator() { + if ( SubAllocatorSize ) { + SubAllocatorSize=0; delete[] HeapStart; + } +} +BOOL _STDCALL StartSubAllocator(UINT SASize) +{ + DWORD t=SASize << 19U; + if (SubAllocatorSize == t) return TRUE; + StopSubAllocator(); + if ((HeapStart=new BYTE[t]) == NULL) return FALSE; + SubAllocatorSize=t; return TRUE; +} +static inline void InitSubAllocator() +{ + memset(BList,0,sizeof(BList)); + HiUnit=(pText=HeapStart)+SubAllocatorSize; + UINT Diff=UNIT_SIZE*(SubAllocatorSize/8/UNIT_SIZE*7); + LoUnit=UnitsStart=HiUnit-Diff; GlueCount=0; +} +static void GlueFreeBlocks() +{ + UINT i, k, sz; + MEM_BLK s0, * p, * p0, * p1; + if (LoUnit != HiUnit) *LoUnit=0; + for (i=0, (p0=&s0)->next=NULL;i < N_INDEXES;i++) + while ( BList[i].avail() ) { + p=(MEM_BLK*) BList[i].remove(); + if ( !p->NU ) continue; + while ((p1=p+p->NU)->Stamp == ~0UL) { + p->NU += p1->NU; p1->NU=0; + } + p0->link(p); p0=p; + } + while ( s0.avail() ) { + p=(MEM_BLK*) s0.remove(); sz=p->NU; + if ( !sz ) continue; + for ( ;sz > 128;sz -= 128, p += 128) + BList[N_INDEXES-1].insert(p,128); + if (Indx2Units[i=Units2Indx[sz-1]] != sz) { + k=sz-Indx2Units[--i]; BList[k-1].insert(p+(sz-k),k); + } + BList[i].insert(p,Indx2Units[i]); + } + GlueCount=1 << 13; +} +static void* _STDCALL AllocUnitsRare(UINT indx) +{ + UINT i=indx; + if ( !GlueCount ) { + GlueFreeBlocks(); + if ( BList[i].avail() ) return BList[i].remove(); + } + do { + if (++i == N_INDEXES) { + GlueCount--; i=U2B(Indx2Units[indx]); + return (UnitsStart-pText > i)?(UnitsStart -= i):(NULL); + } + } while ( !BList[i].avail() ); + void* RetVal=BList[i].remove(); SplitBlock(RetVal,i,indx); + return RetVal; +} +inline void* AllocUnits(UINT NU) +{ + UINT indx=Units2Indx[NU-1]; + if ( BList[indx].avail() ) return BList[indx].remove(); + void* RetVal=LoUnit; LoUnit += U2B(Indx2Units[indx]); + if (LoUnit <= HiUnit) return RetVal; + LoUnit -= U2B(Indx2Units[indx]); return AllocUnitsRare(indx); +} +inline void* AllocContext() +{ + if (HiUnit != LoUnit) return (HiUnit -= UNIT_SIZE); + else if ( BList->avail() ) return BList->remove(); + else return AllocUnitsRare(0); +} +inline void UnitsCpy(void* Dest,void* Src,UINT NU) +{ + DWORD* p1=(DWORD*) Dest, * p2=(DWORD*) Src; + do { + p1[0]=p2[0]; p1[1]=p2[1]; + p1[2]=p2[2]; + p1 += 3; p2 += 3; + } while ( --NU ); +} +inline void* ExpandUnits(void* OldPtr,UINT OldNU) +{ + UINT i0=Units2Indx[OldNU-1], i1=Units2Indx[OldNU-1+1]; + if (i0 == i1) return OldPtr; + void* ptr=AllocUnits(OldNU+1); + if ( ptr ) { + UnitsCpy(ptr,OldPtr,OldNU); BList[i0].insert(OldPtr,OldNU); + } + return ptr; +} +inline void* ShrinkUnits(void* OldPtr,UINT OldNU,UINT NewNU) +{ + UINT i0=Units2Indx[OldNU-1], i1=Units2Indx[NewNU-1]; + if (i0 == i1) return OldPtr; + if ( BList[i1].avail() ) { + void* ptr=BList[i1].remove(); UnitsCpy(ptr,OldPtr,NewNU); + BList[i0].insert(OldPtr,Indx2Units[i0]); + return ptr; + } else { + SplitBlock(OldPtr,i0,i1); return OldPtr; + } +} +inline void FreeUnits(void* ptr,UINT NU) { + UINT indx=Units2Indx[NU-1]; + BList[indx].insert(ptr,Indx2Units[indx]); +} +inline void SpecialFreeUnit(void* ptr) +{ + if ((BYTE*) ptr != UnitsStart) BList->insert(ptr,1); + else { *(DWORD*) ptr=~0UL; UnitsStart += UNIT_SIZE; } +} +inline void* MoveUnitsUp(void* OldPtr,UINT NU) +{ + UINT indx=Units2Indx[NU-1]; + if ((BYTE*) OldPtr > UnitsStart+16*1024 || (BLK_NODE*) OldPtr > BList[indx].next) + return OldPtr; + void* ptr=BList[indx].remove(); + UnitsCpy(ptr,OldPtr,NU); NU=Indx2Units[indx]; + if ((BYTE*) OldPtr != UnitsStart) BList[indx].insert(OldPtr,NU); + else UnitsStart += U2B(NU); + return ptr; +} +static inline void ExpandTextArea() +{ + BLK_NODE* p; + UINT Count[N_INDEXES]; memset(Count,0,sizeof(Count)); + while ((p=(BLK_NODE*) UnitsStart)->Stamp == ~0UL) { + MEM_BLK* pm=(MEM_BLK*) p; UnitsStart=(BYTE*) (pm+pm->NU); + Count[Units2Indx[pm->NU-1]]++; pm->Stamp=0; + } + for (UINT i=0;i < N_INDEXES;i++) + for (p=BList+i;Count[i] != 0;p=p->next) + while ( !p->next->Stamp ) { + p->unlink(); BList[i].Stamp--; + if ( !--Count[i] ) break; + } +} -- cgit v0.9.0.2