diff --git a/programs/bcc32/include/kos_file.h b/programs/bcc32/include/kos_file.h index 0a7e3c79b8..31cb3e24ed 100644 --- a/programs/bcc32/include/kos_file.h +++ b/programs/bcc32/include/kos_file.h @@ -8,271 +8,88 @@ namespace Kolibri // All kolibri functions, types and data are nested in the (Kolibri) namespace. { - struct _FileDataStruct; - typedef _FileDataStruct *TFileData; - - TFileData FileOpen(const char *name, unsigned int buffer_length = 1024); - int FileClose(TFileData file_data); - bool FileEof(TFileData file_data); - unsigned int FileGetPosition(TFileData file_data); - void FileSetPosition(TFileData file_data, unsigned int pos); - void FileReset(TFileData file_data); - unsigned int FileGetLength(TFileData file_data); - int FileTestRead(TFileData file_data); - int FileRead(TFileData file_data, void *mem, int size); -} - -#ifdef __KOLIBRI__ - -namespace Kolibri -{ -// Define the file data structure. - - struct _FileDataStruct - { - unsigned int length; - unsigned int position; - unsigned int *buffer; - unsigned int access_param[5]; - - enum {PosName = (unsigned int)(((_FileDataStruct*)0)->access_param + 5)}; + struct FileDateTime{ + unsigned long int time; + unsigned long int date; }; - -// Inline functions. - - inline bool FileEof(TFileData file_data) + struct FileInfoBlock { - return file_data && file_data->position >= file_data->length; - } - - inline unsigned int FileGetPosition(TFileData file_data) + unsigned long int Function; + unsigned long int Position; + unsigned long int Flags; + unsigned long int Count; + char *Buffer; + char *FileName1; + char *FileName2; + }; + struct FileInfoA { - return file_data ? file_data->position : 0; - } - - inline void FileReset(TFileData file_data) - { - if (!file_data) return; - file_data->length = -1; - file_data->position = 0; - if (file_data->buffer) file_data->buffer[1] = 0; - } + unsigned long int Attributes; + unsigned long int Flags; + FileDateTime DateCreate; + FileDateTime DateAccess; + FileDateTime DateModify; + unsigned long int FileSizeLow; + unsigned long int FileSizeHigh; + char FileName[520]; + }; // Functions. - int _FileAccess(void *file_access_param); + int _FileAccess(FileInfoBlock *file_access); - TFileData FileOpen(const char *name, unsigned int buffer_length) + FileInfoBlock* FileOpen(const char *name) { - if (!name || !name[0]) return 0; - unsigned int name_len = StrLen(name) + 1; - unsigned int data_len = (_FileDataStruct::PosName + name_len + 3) & ~3; - buffer_length = (buffer_length / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE; - if (buffer_length) data_len += buffer_length + 2*sizeof(unsigned int); - TFileData file = (TFileData)Alloc(_FileDataStruct::PosName + data_len); - if (!file) return 0; - file->length = -1; - file->position = 0; - if (buffer_length) - { - file->buffer = (unsigned int*)((char*)file + data_len) - 2; - file->buffer[0] = buffer_length; - file->buffer[1] = 0; + if (!name || !name[0]){ + //DebugPutString("name is 0"); + return 0; } - MemCopy(file->access_param + 5, name, name_len); - unsigned int attr[40/4]; - file->access_param[0] = 5; - file->access_param[1] = 0; - file->access_param[2] = 0; - file->access_param[3] = 0; - file->access_param[4] = (int)attr; - _FileAccess(file->access_param); - file->length = attr[32/4]; + FileInfoBlock* file = (FileInfoBlock*)Alloc(sizeof(FileInfoBlock)+sizeof(FileInfoA)); + if (!file){ + //DebugPutString("mem_Alloc -> 0"); + return 0; + } + file->Function = 5; //SSF_GET_INFO + file->Position = 0; + file->Flags = 0; + file->Count = 0; + file->Buffer = (char*)file+sizeof(FileInfoBlock); + file->FileName1 = (char*)name; + file->FileName2 = (char*)name; + file->FileName1 = (char*)((long)file->FileName1 << 8); + file->FileName2 = (char*)((long)file->FileName2 >> 24); + + _FileAccess(file); return file; } - int FileClose(TFileData file_data) + int FileClose(FileInfoBlock* file_data) { if (!file_data) return -1; Free(file_data); return 0; } - void FileSetPosition(TFileData file_data, unsigned int pos) + unsigned long int FileRead(FileInfoBlock* file_data, void *mem, int size) { - if (!file_data) return; - if (file_data->buffer && file_data->buffer[1]) - { - if (pos >= file_data->position && pos < file_data->position + file_data->buffer[1]) - { - file_data->buffer[1] -= pos - file_data->position; - } - else file_data->buffer[1] = 0; - } - file_data->position = pos; - } + file_data->Function = 0; //SSF_READ_FILE + file_data->Position = 0; + file_data->Flags = 0; + file_data->Count = size; + file_data->Buffer = (char*)mem; - int _FileReadBuffer(TFileData file_data, void *mem, int size, void *temp_mem = 0) - { - unsigned int *buffer; - if (!file_data || !mem || size <= 0) return -1; - if (file_data->buffer) buffer = file_data->buffer; - else if (temp_mem) - { - buffer = (unsigned int*)((char*)temp_mem + KOLIBRI_FILE_BLOCK_SIZE); - } + if(!_FileAccess(file_data)) return file_data->Function; else return 0; - if (!buffer[1]) return 0; - if (file_data->position >= file_data->length) - { - buffer[1] = 0; - return 0; - } - unsigned int buf_size = file_data->length - file_data->position; - if (buf_size > buffer[1]) buf_size = buffer[1]; - if ((unsigned int)size >= buf_size) size = buf_size; - MemCopy(mem, (char*)buffer - buffer[1], size); - file_data->position += size; - if ((unsigned int)size >= buf_size) buffer[1] = 0; - else buffer[1] -= size; - return size; - } - - int _FileReadSystem(TFileData file_data, void *mem, int size) - { - int res; - unsigned int len0, len1; - size /= KOLIBRI_FILE_BLOCK_SIZE; - if (!file_data || !mem || size <= 0) return -1; - file_data->access_param[0] = 0; - file_data->access_param[1] = (file_data->position / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE; - file_data->access_param[2] = 0; - file_data->access_param[3] = size * KOLIBRI_FILE_BLOCK_SIZE; - file_data->access_param[4] = (unsigned int)mem; - res = _FileAccess(file_data->access_param); - if (res != 0 && res != 6) return (res & 255) - 1024; - if (file_data->length <= file_data->position) return 0; - len0 = file_data->length - file_data->position; - len1 = size * KOLIBRI_FILE_BLOCK_SIZE - (file_data->position % KOLIBRI_FILE_BLOCK_SIZE); - return (len0 <= len1) ? len0 : len1; - } - - int _FileBufferSystem(TFileData file_data, void *&temp_mem) - { - int res; - unsigned int *buffer; - if (!file_data) return -1; - if (file_data->buffer) buffer = file_data->buffer; - else - { - if (!temp_mem) - { - temp_mem = Alloc(KOLIBRI_FILE_BLOCK_SIZE + 2*sizeof(unsigned int)); - if (!temp_mem) return -10; - } - buffer = (unsigned int*)((char*)temp_mem + KOLIBRI_FILE_BLOCK_SIZE); - buffer[0] = KOLIBRI_FILE_BLOCK_SIZE; - } - buffer[1] = buffer[0]; - res = _FileReadSystem(file_data, (char*)buffer - buffer[1], buffer[1]); - if (res < 0) buffer[1] = 0; - else buffer[1] -= file_data->position % KOLIBRI_FILE_BLOCK_SIZE; - return res; - } - - int FileTestRead(TFileData file_data) - { - int res; - void *temp_mem = 0; - if (!file_data) return -1; - if (file_data->buffer && file_data->buffer[1]) return 0; - res = _FileBufferSystem(file_data, temp_mem); - if (temp_mem) Free(temp_mem); - return (res < 0) ? res : 0; - } - - int FileRead(TFileData file_data, void *mem, int size) - { - int tlen, res, read_len; - void *temp_mem = 0; - res = _FileReadBuffer(file_data, mem, size); - if (res < 0 || res >= size) return res; - read_len = res; - mem = (char*)mem + res; - size -= res; - tlen = file_data->position % KOLIBRI_FILE_BLOCK_SIZE; - if (tlen) - { - res = _FileBufferSystem(file_data, temp_mem); - if (res < 0) - { - if (temp_mem) Free(temp_mem); - return read_len ? read_len : res; - } - res = _FileReadBuffer(file_data, mem, size); - read_len += res; - if (res >= size || file_data->length <= file_data->position || - file_data->length - file_data->position <= res) - { - if (temp_mem) Free(temp_mem); - return read_len; - } - mem = (char*)mem + res; - size -= res; - } - if (size >= (file_data->buffer ? file_data->buffer[0] : KOLIBRI_FILE_BLOCK_SIZE)) - { - res = _FileReadSystem(file_data, mem, size); - if (res < 0) - { - if (temp_mem) Free(temp_mem); - return read_len ? read_len : res; - } - file_data->position += res; - read_len += res; - if (res < (size / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE) - { - if (temp_mem) Free(temp_mem); - return read_len; - } - mem = (char*)mem + res; - size -= res; - } - if (size) - { - res = _FileBufferSystem(file_data, temp_mem); - if (res < 0) - { - if (temp_mem) Free(temp_mem); - return read_len ? read_len : res; - } - read_len += _FileReadBuffer(file_data, mem, size, temp_mem); - } - if (temp_mem) Free(temp_mem); - return read_len; } // Inline functions. - inline unsigned int FileGetLength(TFileData file_data) + inline unsigned long int FileGetLength(FileInfoBlock* file_data) { if (!file_data) return -1; - if (file_data->length == -1) FileTestRead(file_data); - return file_data->length; + return (unsigned long int)*(long*)((char*)file_data+sizeof(FileInfoBlock)+32); } } -#else // def __KOLIBRI__ - -namespace Kolibri -{ - struct _FileDataStruct - { - unsigned int data; - }; -} - -#endif // else: def __KOLIBRI__ - #endif // ndef __KOLIBRI_FILE_H_INCLUDED_ diff --git a/programs/bcc32/include/kos_func.inc b/programs/bcc32/include/kos_func.inc index eb14c4502f..fd420deea1 100644 --- a/programs/bcc32/include/kos_func.inc +++ b/programs/bcc32/include/kos_func.inc @@ -41,12 +41,6 @@ KOLIBRI_THREAD_DATA_LEN = 16; ;const int KOLIBRI_MUTEX_MAX_TIME_WAIT = 20; -;const int -KOLIBRI_FILE_BLOCK_SIZE = 512; - -;const int -KOLIBRI_FILE_MEMORY_OS_NEED = 4096; - ;/*** macro segment name @@ -1093,7 +1087,7 @@ end if jmp .create_thread_fill_stack endp -proc @Kolibri@_FileAccess$qpv uses ebx +proc @Kolibri@_FileAccess$qp21Kolibri@FileInfoBlock uses ebx mov eax,SF_FILE mov ebx,[esp+8] int 0x40 diff --git a/programs/bcc32/include/kos_heap.h b/programs/bcc32/include/kos_heap.h index b5dff0950a..8696df8715 100644 --- a/programs/bcc32/include/kos_heap.h +++ b/programs/bcc32/include/kos_heap.h @@ -8,83 +8,25 @@ namespace Kolibri // All kolibri functions, types and data are nested in the (Kolibri) namespace. { - void *Alloc(unsigned int size); - void *ReAlloc(void *mem, unsigned int size); - void Free(void *mem); -} - -#ifdef __KOLIBRI__ - -namespace Kolibri -{ - -// Global variables - - MemoryHeap::TFreeSpace _KolibriFreeSpace; - MemoryHeap::TMemBlock _KolibriMemBlock; - TMutex _MemHeapMutex = KOLIBRI_MUTEX_INIT; - -// Functions - - void *_HeapInit(void *begin, void *use_end, void *end) + long _HeapInit() { - MemoryHeap::InitFreeSpace(_KolibriFreeSpace); - _KolibriMemBlock = MemoryHeap::CreateBlock(begin, end, _KolibriFreeSpace); - unsigned int use_beg = (unsigned int)MemoryHeap::BlockBegin(_KolibriMemBlock) + - MemoryHeap::BlockAddSize - MemoryHeap::BlockEndSize; - unsigned int use_size = (unsigned int)use_end; - if (use_size <= use_beg) return 0; - else use_size -= use_beg; - return MemoryHeap::Alloc(_KolibriFreeSpace, use_size); + return MemoryHeap::mem_Init(); } - bool _SetUseMemory(unsigned int use_mem); - - int _RecalculateUseMemory(unsigned int use_mem); - void *Alloc(unsigned int size) { - if (!size) return 0; - Lock(&_MemHeapMutex); - void *res = MemoryHeap::Alloc(_KolibriFreeSpace, size); - if (!res) - { - unsigned use_mem = (unsigned int)MemoryHeap::BlockEndFor(_KolibriMemBlock, size); - if (_SetUseMemory(_RecalculateUseMemory(use_mem))) - { - res = MemoryHeap::Alloc(_KolibriFreeSpace, size); - } - } - UnLock(&_MemHeapMutex); - return res; + return MemoryHeap::mem_Alloc(size); } void *ReAlloc(void *mem, unsigned int size) { - Lock(&_MemHeapMutex); - void *res = MemoryHeap::ReAlloc(_KolibriFreeSpace, mem, size); - if (!res && size) - { - unsigned use_mem = (unsigned int)MemoryHeap::BlockEndFor(_KolibriMemBlock, size); - if (_SetUseMemory(_RecalculateUseMemory(use_mem))) - { - res = MemoryHeap::ReAlloc(_KolibriFreeSpace, mem, size); - } - } - UnLock(&_MemHeapMutex); - return res; + return MemoryHeap::mem_ReAlloc(size, mem); } void Free(void *mem) { - Lock(&_MemHeapMutex); - MemoryHeap::Free(_KolibriFreeSpace, mem); - UnLock(&_MemHeapMutex); + MemoryHeap::mem_Free(mem); } - - void _FreeAndThreadFinish(void *mem, int *exit_proc_now); } -#endif // def __KOLIBRI__ - #endif // ndef __KOLIBRI_HEAP_H_INCLUDED_ diff --git a/programs/bcc32/include/kos_heap.inc b/programs/bcc32/include/kos_heap.inc index 89da5250b3..28a860adfc 100644 --- a/programs/bcc32/include/kos_heap.inc +++ b/programs/bcc32/include/kos_heap.inc @@ -1,6 +1,6 @@ ;/*** -KolibriHeapInit = @@Kolibri@_HeapInit$qpvt1t1 +KolibriHeapInit = @@Kolibri@_HeapInit$qv KolibriHeapAlloc = @@Kolibri@Alloc$qui @@ -8,90 +8,34 @@ KolibriHeapReAlloc = @@Kolibri@ReAlloc$qpvui KolibriHeapFree = @@Kolibri@Free$qpv -KolibriHeapFreeAndThreadFinish = @Kolibri@_FreeAndThreadFinish$qpvpi +proc @MemoryHeap@mem_Init$qv uses ebx + mov eax,SF_SYS_MISC + mov ebx,SSF_HEAP_INIT + int 0x40 + ret +endp -proc @Kolibri@_SetUseMemory$qui - push ebx - mov eax,64 - mov ebx,1 +proc @MemoryHeap@mem_Alloc$qul uses ebx + mov eax,SF_SYS_MISC + mov ebx,SSF_MEM_ALLOC + int 0x40 + ret +endp + +proc @MemoryHeap@mem_ReAlloc$qulpv uses ebx + mov eax,SF_SYS_MISC + mov ebx,SSF_MEM_REALLOC mov ecx,[esp+8] + mov edx,[esp+12] int 0x40 - pop ebx - test eax,eax - jnz .set_use_memory_nomem - push ecx - push dword [@Kolibri@_KolibriMemBlock] - call @@MemoryHeap@ResizeBlock$q20MemoryHeap@TMemBlockpv - add esp,8 - mov al,1 - ret -.set_use_memory_nomem: - xor al,al ret endp -proc @Kolibri@_RecalculateUseMemory$qui - mov eax,dword [esp+4] - mov ecx,(U_END + 3) and not 3 - cmp eax,ecx - jna .recalculate_use_memory_min - push ebx - sub eax,ecx - mov ebx,6 - mul ebx - dec ebx - div ebx - add eax,((U_END + 3) and not 3) + 3 - and eax,not 3 - pop ebx - ret -.recalculate_use_memory_min: - mov eax,ecx +proc @MemoryHeap@mem_Free$qpv uses ebx + mov eax,SF_SYS_MISC + mov ebx,SSF_MEM_FREE + int 0x40 ret endp -proc @Kolibri@_FreeAndThreadFinish$qpvpi - mov ebx,1 - mov ecx,[esp+8] - jmp .heap_free_tf_wait -.heap_free_tf_wait_loop: - mov eax,5 - int 0x40 - shl ebx,1 - cmp ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT - jna .heap_free_tf_wait - mov ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT -.heap_free_tf_wait: - cmp dword [ecx],0 - jnz @Kolibri@ExitProcess$qv - lock bts dword [@Kolibri@_MemHeapMutex],0 - jc .heap_free_tf_wait_loop - push dword [esp+4] - push @Kolibri@_KolibriFreeSpace - call @@MemoryHeap@Free$qr21MemoryHeap@TFreeSpacepv - add esp,8 - mov byte [@Kolibri@_MemHeapMutex],0x40 - or eax,-1 - int 0x40 -endp - -macro call func -{ - if func eq @MemoryHeap@_FirstNotZeroBit$qui - bsf eax,[esp] - else if func eq @MemoryHeap@_CopyMemItemArray$quiuiui - xchg edi,[esp] - xchg esi,[esp+4] - mov ecx,[esp+8] - cld - sub ecx,esi - shr ecx,2 - rep movs dword [edi],[esi] - xchg edi,[esp] - xchg esi,[esp+4] - else - call func - end if -} - ;/**/ diff --git a/programs/bcc32/include/memheap.h b/programs/bcc32/include/memheap.h index bf8aa101fc..52a06f887d 100644 --- a/programs/bcc32/include/memheap.h +++ b/programs/bcc32/include/memheap.h @@ -1,626 +1,13 @@ -#ifndef __MEMORY_HEAP_RBTREE_H_INCLUDED_ -#define __MEMORY_HEAP_RBTREE_H_INCLUDED_ +#ifndef __MEMORY_HEAP_H_INCLUDED_ +#define __MEMORY_HEAP_H_INCLUDED_ namespace MemoryHeap { - typedef unsigned int TMemItem; - - enum {NumTreeSmall = 8 * sizeof(TMemItem)}; - -// Memory heap interface. - - struct TFreeSpace - { - TMemItem Small[NumTreeSmall], Min, SmallMask; - }; - - struct TMemBlock - { - TMemItem *Begin; - }; - - bool BlockValid(const TMemBlock &block); // Is the given memory block valid? - void *BlockBegin(const TMemBlock &block); // Return the beginning address of the block. - void *BlockEnd(const TMemBlock &block); // Return the ending address of the block. - TFreeSpace &BlockFreeSpace(const TMemBlock &block); // Return the free space of the block. - - void InitFreeSpace(TFreeSpace &fs); // Initialize the free space. - TMemBlock NullBlock(); // Return null invalid block. - TMemBlock CreateBlock(void *begin, void *end, TFreeSpace &fs); - // Create a memory block with the given begin and end and add free space of it to (fs), - //_ give (BlockAddSize) bytes of the block for it's data. - //_ (Program can alloc (end - begin - BlockAddSize) bytes after it, - //_ that must be not less than (MemMinSize) ). - TMemBlock CreateBlock(void *begin, void *end); - // Create a memory block with the given begin and end and new free space for it, - //_ give (BlockAddSizeFS) bytes of the block for it's data. - //_ (Program can alloc (end - begin - BlockAddSizeFS) bytes after it, - //_ that must be not less than (MemMinSize) ). - void ResizeBlock(TMemBlock block, void *new_end); // Resize the memory block to the given new end. - void RemoveBlock(TMemBlock block); // Remove the given memory block. - - void *BlockEndFor(TMemBlock block, unsigned int size); - // Return the new end of the block needed for (ResizeBlock) to alloc the given size of memory. - unsigned int BlockSize(TMemBlock block); // Return the size of the given block. - unsigned int MemSize(void *mem); // Return the size of the allocced memory. - - void *Alloc(TFreeSpace &fs, unsigned int size); - // Alloc a memory in the given free space, give (MemAddSize) bytes for it's data. - void *ReAlloc(TFreeSpace &fs, unsigned int size, void *mem); - // ReAlloc the given memory, it must lie in the block with the given free space. - void Free(TFreeSpace &fs, void *mem); - // Free the given memory, it must lie in the block with the given free space. - -// Macro definitions. - -#define MEMORY_HEAP_ALIGN_DOWN(s) (MemoryHeap::TMemItem(s) & ~(MemoryHeap::MemAlign - 1)) -#define MEMORY_HEAP_ALIGN_UP(s) ((MemoryHeap::TMemItem(s) + (MemoryHeap::MemAlign - 1)) & ~(MemoryHeap::MemAlign - 1)) -#define MEMORY_HEAP_ITEM(s,k) ( ((MemoryHeap::TMemItem*)(s))[(k)] ) -#define MEMORY_HEAP_NEXT(s) (MEMORY_HEAP_ITEM((s),-1)) -#define MEMORY_HEAP_PREV(s) (MEMORY_HEAP_ITEM((s),-2)) -#define MEMORY_HEAP_FREE(s) (MEMORY_HEAP_ITEM((s),-1) & 1) - -// Constants. - - enum {MemAlign = sizeof(TMemItem)}; - enum {MemAddSize = MEMORY_HEAP_ALIGN_UP(2 * sizeof(TMemItem))}; - enum {BlockEndSize = MemAddSize}; - enum {BlockAddSize = MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem)) + BlockEndSize}; - enum {BlockAddSizeFS = BlockAddSize + BlockEndSize + MEMORY_HEAP_ALIGN_UP(sizeof(TFreeSpace))}; - enum {MemMinSize = MEMORY_HEAP_ALIGN_UP(2 * sizeof(TMemItem))}; - -// Inline functions. - - inline bool BlockValid(const TMemBlock &block) {return block.Begin != 0;} - - inline void *BlockBegin(const TMemBlock &block) {return (void*)block.Begin;} - - inline void *BlockEnd(const TMemBlock &block) {return block.Begin ? (void*)block.Begin[1] : 0;} - - inline TFreeSpace &BlockFreeSpace(const TMemBlock &block) {return *(TFreeSpace*)block.Begin[0];} - - inline TMemBlock NullBlock() {TMemBlock block; block.Begin = 0; return block;} - - inline void *BlockEndFor(TMemBlock block, unsigned int size) - { - TMemItem last = (TMemItem)block.Begin[1]; - TMemItem prevlast = MEMORY_HEAP_PREV(last); - return (void*)( (MEMORY_HEAP_FREE(prevlast) ? prevlast : last) + MemAddSize + - ((size <= MemMinSize) ? MemMinSize : MEMORY_HEAP_ALIGN_UP(size)) ); - } - - inline unsigned int BlockSize(TMemBlock block) - { - if (!block.Begin) return 0; - return (unsigned int)(block.Begin[1] - (TMemItem)block.Begin); - } - - inline unsigned int MemSize(void *mem) - { - if (!mem) return 0; - TMemItem c = (TMemItem)mem; - return MEMORY_HEAP_NEXT(c) - c - MemAddSize; - } - -// Free space item functions. - - TMemItem _FirstNotZeroBit(TMemItem i) - { - TMemItem r = 0; - while ((i >>= 1) != 0) r++; - return r; - } - - void _RBTreeRotate(TMemItem parent, TMemItem item, int side) - { - TMemItem temp = MEMORY_HEAP_ITEM(parent,0); - MEMORY_HEAP_ITEM(item,0) = temp; - if (temp) - { - if (MEMORY_HEAP_ITEM(temp,2) == parent) - { - MEMORY_HEAP_ITEM(temp,2) = item; - } - else MEMORY_HEAP_ITEM(temp,3) = item; - } - temp = MEMORY_HEAP_ITEM(item,side^1); - if (temp) MEMORY_HEAP_ITEM(temp,0) = parent; - MEMORY_HEAP_ITEM(parent,side) = temp; - MEMORY_HEAP_ITEM(parent,0) = item; - MEMORY_HEAP_ITEM(item,side^1) = parent; - temp = MEMORY_HEAP_ITEM(parent,1); - MEMORY_HEAP_ITEM(parent,1) = MEMORY_HEAP_ITEM(item,1); - MEMORY_HEAP_ITEM(item,1) = temp; - } - - void InitFreeSpace(TFreeSpace &fs) - { - TMemItem i; - for (i = 0; i <= NumTreeSmall; i++) fs.Small[i] = 0; - fs.Min = 0; fs.SmallMask = 0; - } - - void _FreeAdd(TFreeSpace &fs, TMemItem item) - { - TMemItem size = MEMORY_HEAP_NEXT(item) - item; - if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall) - { - TMemItem s = (size - (MemAddSize + MemMinSize)) / MemAlign; - TMemItem &addto = fs.Small[s]; - MEMORY_HEAP_ITEM(item,1) = (TMemItem)(&addto); - MEMORY_HEAP_ITEM(item,0) = (TMemItem)addto; - if (addto) MEMORY_HEAP_ITEM(addto,1) = item; - addto = item; - fs.SmallMask |= TMemItem(1) << s; - return; - } - TMemItem addto = fs.Min, parent, temp; - MEMORY_HEAP_ITEM(item,2) = 0; - MEMORY_HEAP_ITEM(item,3) = 0; - if (!addto) - { - MEMORY_HEAP_ITEM(item,0) = 0; - MEMORY_HEAP_ITEM(item,1) = 1; - fs.Min = item; - return; - } - MEMORY_HEAP_ITEM(item,1) = 0; - TMemItem side = 2; - if (MEMORY_HEAP_NEXT(addto) - addto >= size) fs.Min = item; - else - { - for (;;) - { - parent = MEMORY_HEAP_ITEM(addto,0); - if (!parent) break; - if (MEMORY_HEAP_NEXT(parent) - parent < size) addto = parent; - else break; - } - for (;;) - { - if (MEMORY_HEAP_NEXT(addto) - addto < size) - { - temp = MEMORY_HEAP_ITEM(addto,3); - if (!temp) {side = 3; break;} - addto = temp; - } - else - { - temp = MEMORY_HEAP_ITEM(addto,2); - if (!temp) break; - addto = temp; - } - } - } - MEMORY_HEAP_ITEM(item,0) = addto; - MEMORY_HEAP_ITEM(addto,side) = item; - for (;;) - { - if (MEMORY_HEAP_ITEM(addto,1) != 0) return; - parent = MEMORY_HEAP_ITEM(addto,0); - temp = MEMORY_HEAP_ITEM(parent,2); - if (temp == addto) - { - temp = MEMORY_HEAP_ITEM(parent,3); - side = 2; - } - else side = 3; - if (!temp || MEMORY_HEAP_ITEM(temp,1) != 0) break; - MEMORY_HEAP_ITEM(addto,1) = 1; - MEMORY_HEAP_ITEM(temp,1) = 1; - item = parent; - addto = MEMORY_HEAP_ITEM(item,0); - if (!addto) return; - MEMORY_HEAP_ITEM(item,1) = 0; - } - if (MEMORY_HEAP_ITEM(addto,side) != item) - { - temp = MEMORY_HEAP_ITEM(item,side); - if (temp) MEMORY_HEAP_ITEM(temp,0) = addto; - MEMORY_HEAP_ITEM(addto,side^1) = temp; - MEMORY_HEAP_ITEM(addto,0) = item; - MEMORY_HEAP_ITEM(item,side) = addto; - MEMORY_HEAP_ITEM(item,0) = parent; - MEMORY_HEAP_ITEM(parent,side) = item; - } - else item = addto; - _RBTreeRotate(parent, item, side); - } - - void _FreeDel(TFreeSpace &fs, TMemItem item) - { - TMemItem size = MEMORY_HEAP_NEXT(item) - item; - if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall) - { - TMemItem prev = MEMORY_HEAP_ITEM(item,1); - TMemItem next = MEMORY_HEAP_ITEM(item,0); - MEMORY_HEAP_ITEM(prev,0) = next; - if (next) MEMORY_HEAP_ITEM(next,1) = prev; - else - { - TMemItem s = (size - (MemAddSize + MemMinSize)) / MemAlign; - if (!fs.Small[s]) fs.SmallMask &= ~(TMemItem(1) << s); - } - return; - } - TMemItem parent, temp, second, add; - TMemItem side = 2; - temp = MEMORY_HEAP_ITEM(item,3); - if (temp) - { - for (;;) - { - second = temp; - temp = MEMORY_HEAP_ITEM(temp,2); - if (!temp) break; - } - if (fs.Min == item) fs.Min = second; - add = MEMORY_HEAP_ITEM(second,3); - parent = MEMORY_HEAP_ITEM(second,0); - if (parent == item) {parent = second; side = 3;} - else - { - temp = MEMORY_HEAP_ITEM(item,3); - MEMORY_HEAP_ITEM(second,3) = temp; - MEMORY_HEAP_ITEM(temp,0) = second; - } - temp = MEMORY_HEAP_ITEM(item,2); - MEMORY_HEAP_ITEM(second,2) = temp; - if (temp) MEMORY_HEAP_ITEM(temp,0) = second; - temp = MEMORY_HEAP_ITEM(item,0); - MEMORY_HEAP_ITEM(second,0) = temp; - if (temp) - { - if (MEMORY_HEAP_ITEM(temp,2) == item) - { - MEMORY_HEAP_ITEM(temp,2) = second; - } - else MEMORY_HEAP_ITEM(temp,3) = second; - } - MEMORY_HEAP_ITEM(parent,side) = add; - if (add) MEMORY_HEAP_ITEM(add,0) = parent; - bool color = MEMORY_HEAP_ITEM(second,1); - MEMORY_HEAP_ITEM(second,1) = MEMORY_HEAP_ITEM(item,1); - if (!color) return; - } - else - { - if (fs.Min == item) fs.Min = MEMORY_HEAP_ITEM(item,0); - add = MEMORY_HEAP_ITEM(item,2); - parent = MEMORY_HEAP_ITEM(item,0); - if (add) MEMORY_HEAP_ITEM(add,0) = parent; - if (parent) - { - if (MEMORY_HEAP_ITEM(parent,2) == item) - { - MEMORY_HEAP_ITEM(parent,2) = add; - } - else - { - MEMORY_HEAP_ITEM(parent,3) = add; - side = 3; - } - } - else - { - if (add) MEMORY_HEAP_ITEM(add,1) = 1; - return; - } - if (!MEMORY_HEAP_ITEM(item,1)) return; - } - if (add && !MEMORY_HEAP_ITEM(add,1)) - { - MEMORY_HEAP_ITEM(add,1) = 1; - return; - } - for (;;) - { - second = MEMORY_HEAP_ITEM(parent,side^1); - if (!MEMORY_HEAP_ITEM(second,1)) - { - _RBTreeRotate(parent, second, side^1); - second = MEMORY_HEAP_ITEM(parent,side^1); - } - temp = MEMORY_HEAP_ITEM(second,side^1); - if (temp && !MEMORY_HEAP_ITEM(temp,1)) - { - MEMORY_HEAP_ITEM(temp,1) = 1; - break; - } - temp = MEMORY_HEAP_ITEM(second,side); - if (temp && !MEMORY_HEAP_ITEM(temp,1)) - { - _RBTreeRotate(second, temp, side); - MEMORY_HEAP_ITEM(second,1) = 1; - second = temp; - break; - } - MEMORY_HEAP_ITEM(second,1) = 0; - if (!MEMORY_HEAP_ITEM(parent,1)) - { - MEMORY_HEAP_ITEM(parent,1) = 1; - return; - } - second = parent; - parent = MEMORY_HEAP_ITEM(second,0); - if (!parent) return; - if (MEMORY_HEAP_ITEM(parent,2) == second) side = 2; - else side = 3; - } - _RBTreeRotate(parent, second, side^1); - } - - TMemItem _FreeFindAfter(TMemItem item, TMemItem size) - { - if (!item) return 0; - TMemItem paritem, s; - if (MEMORY_HEAP_NEXT(item) - item >= size) return item; - for (;;) - { - paritem = MEMORY_HEAP_ITEM(item,0); - if (!paritem) break; - s = MEMORY_HEAP_NEXT(paritem) - paritem; - if (s == size) return paritem; - if (s < size) item = paritem; - else break; - } - MEMORY_HEAP_ITEM(item,3); - for (;;) - { - if (!item) return paritem; - s = MEMORY_HEAP_NEXT(item) - item; - if (s == size) return item; - if (s < size) item = MEMORY_HEAP_ITEM(item,3); - else - { - paritem = item; - item = MEMORY_HEAP_ITEM(item,2); - } - } - } - - TMemItem _FreeFind(TFreeSpace &fs, TMemItem size) - { - TMemItem item, nextitem, s; - if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall) - { - TMemItem m, t; - s = (size - (MemAddSize + MemMinSize)) / MemAlign; - item = fs.Small[s]; - if (item) return item; - if (size < MemAlign * NumTreeSmall) - { - t = size / MemAlign; - m = fs.SmallMask >> t; - if (m) return fs.Small[t + _FirstNotZeroBit(m)]; - else if (fs.Min) return fs.Min; - } - else - { - item = _FreeFindAfter(fs.Min, size + 1 + MemAddSize + MemMinSize); - if (item) return item; - } - m = fs.SmallMask >> s; - if (m) return fs.Small[s + _FirstNotZeroBit(m)]; - else return fs.Min; - } - item = _FreeFindAfter(fs.Min, ++size); - if (!item) return 0; - s = MEMORY_HEAP_NEXT(item) - item; - if (s == size) return item; - size += MemAddSize + MemMinSize; - if (s >= size) return item; - nextitem = _FreeFindAfter(item, size); - return nextitem ? nextitem : item; - } - -// Block functions. - - inline void _CreateBlockEnd(TMemBlock &block, TFreeSpace &fs, TMemItem c, TMemItem e) - { - block.Begin[0] = (TMemItem)(&fs); - if (e - c < TMemItem(MemAddSize + MemMinSize)) - { - MEMORY_HEAP_NEXT(c) = 0; - block.Begin[1] = c; - } - else - { - MEMORY_HEAP_NEXT(c) = e + 1; - _FreeAdd(fs, c); - MEMORY_HEAP_PREV(e) = c; - MEMORY_HEAP_NEXT(e) = 0; - block.Begin[1] = e; - } - } - - TMemBlock CreateBlock(void *begin, void *end, TFreeSpace &fs) - { - TMemBlock block = {0}; - TMemItem b = MEMORY_HEAP_ALIGN_UP(begin); - TMemItem e = MEMORY_HEAP_ALIGN_DOWN(end); - if (e <= b || e - b < TMemItem(BlockAddSize - MemAddSize)) return block; - block.Begin = (TMemItem*)b; - b += MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem)); - MEMORY_HEAP_PREV(b) = 0; - _CreateBlockEnd(block, fs, b, e); - return block; - } - - TMemBlock CreateBlock(void *begin, void *end) - { - TMemBlock block = {0}; - TMemItem b = MEMORY_HEAP_ALIGN_UP(begin); - TMemItem e = MEMORY_HEAP_ALIGN_DOWN(end); - if (e <= b || e - b < TMemItem(BlockAddSizeFS - MemAddSize)) return block; - block.Begin = (TMemItem*)b; - b += MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem)); - TMemItem c = b + MemAddSize + MEMORY_HEAP_ALIGN_UP(sizeof(TFreeSpace)); - MEMORY_HEAP_PREV(b) = 0; - MEMORY_HEAP_NEXT(b) = c; - MEMORY_HEAP_PREV(c) = b; - InitFreeSpace(*(TFreeSpace*)b); - _CreateBlockEnd(block, *(TFreeSpace*)b, c, e); - return block; - } - - void ResizeBlock(TMemBlock block, void *new_end) - { - if (!BlockValid(block)) return; - TMemItem e = MEMORY_HEAP_ALIGN_DOWN(new_end); - TMemItem c = block.Begin[1]; - TFreeSpace &fs = *(TFreeSpace*)block.Begin[0]; - do - { - if (c == e) return; - else if (c > e) - { - while ((c = MEMORY_HEAP_PREV(c)) > e) - { - if (MEMORY_HEAP_FREE(c)) _FreeDel(fs, c); - } - if (!c) {block.Begin = 0; return;} - if (MEMORY_HEAP_FREE(c)) - { - _FreeDel(fs, c); - if (e - c < TMemItem(MemAddSize + MemMinSize)) e = c; - else - { - MEMORY_HEAP_NEXT(c) = e + 1; - _FreeAdd(*(TFreeSpace*)block.Begin[0], c); - break; - } - } - else if (e - c >= TMemItem(MemAddSize + MemMinSize)) - { - MEMORY_HEAP_NEXT(c) = e; break; - } - MEMORY_HEAP_NEXT(c) = 0; - block.Begin[1] = c; - if (c == e) return; - } - TMemItem pc = MEMORY_HEAP_PREV(c); - if (pc && MEMORY_HEAP_FREE(pc)) _FreeDel(fs, c = pc); - else if (e - c < TMemItem(MemAddSize + MemMinSize)) return; - MEMORY_HEAP_NEXT(c) = e + 1; - _FreeAdd(fs, c); - } while(false); - MEMORY_HEAP_PREV(e) = c; - MEMORY_HEAP_NEXT(e) = 0; - block.Begin[1] = e; - } - - void RemoveBlock(TMemBlock block) - { - if (!BlockValid(block)) return; - TMemItem e = block.Begin[1]; - TFreeSpace &fs = *(TFreeSpace*)block.Begin[0]; - while ((e = MEMORY_HEAP_PREV(e)) != 0) - { - if (MEMORY_HEAP_FREE(e)) _FreeDel(fs, e); - } - block.Begin = 0; - } - -// Free space functions. - - void _CopyMemItemArray(TMemItem dest, TMemItem src, TMemItem end) - { - TMemItem k = (end - src) / sizeof(TMemItem); - TMemItem *d = (TMemItem*)dest; - TMemItem *s = (TMemItem*)src; - while (k--) *(d++) = *(s++); - } - - void *Alloc(TFreeSpace &fs, unsigned int size) - { - if (!size) return 0; - TMemItem s = MEMORY_HEAP_ALIGN_UP(size) + MemAddSize; - if (s < MemAddSize + MemMinSize) s = MemAddSize + MemMinSize; - TMemItem c = _FreeFind(fs, s); - if (!c) return 0; - _FreeDel(fs, c); - TMemItem nc = --MEMORY_HEAP_NEXT(c); - TMemItem mc = c + s; - if (nc - (MemAddSize + MemMinSize) >= mc) - { - MEMORY_HEAP_NEXT(c) = mc; - MEMORY_HEAP_PREV(mc) = c; - MEMORY_HEAP_NEXT(mc) = nc + 1; - MEMORY_HEAP_PREV(nc) = mc; - _FreeAdd(fs, mc); - } - return (void*)c; - } - - void *ReAlloc(TFreeSpace &fs, void *mem, unsigned int size) - { - if (!mem) return Alloc(fs, size); - if (!size) {Free(fs, mem); return 0;} - TMemItem s = MEMORY_HEAP_ALIGN_UP(size) + MemAddSize; - TMemItem c = (TMemItem)mem; - TMemItem mc = MEMORY_HEAP_NEXT(c); - TMemItem nc = MEMORY_HEAP_NEXT(mc); - if (--nc & 1) nc = mc; - if (s < MemAddSize + MemMinSize) s = MemAddSize + MemMinSize; - if (nc - c < s) - { - mem = Alloc(fs, size); - if (mem) - { - _CopyMemItemArray((TMemItem)mem, c, mc - MemAddSize); - Free(fs, (void*)c); - return mem; - } - else - { - TMemItem pc = MEMORY_HEAP_PREV(c); - if (pc && MEMORY_HEAP_FREE(pc) && nc - pc >= s) - { - _FreeDel(fs, pc); - _CopyMemItemArray(pc, c, mc - MemAddSize); - c = pc; - } - else return 0; - } - } - if (mc < nc) _FreeDel(fs, mc); - mc = c + s; - if (nc - (MemAddSize + MemMinSize) >= mc) - { - MEMORY_HEAP_NEXT(c) = mc; - MEMORY_HEAP_PREV(mc) = c; - MEMORY_HEAP_NEXT(mc) = nc + 1; - MEMORY_HEAP_PREV(nc) = mc; - _FreeAdd(fs, mc); - } - else - { - MEMORY_HEAP_NEXT(c) = nc; - MEMORY_HEAP_PREV(nc) = c; - } - return (void*)c; - } - - int free_a = 0; - - void Free(TFreeSpace &fs, void *mem) - { - TMemItem c = (TMemItem)mem; - if (!c) return; - TMemItem pc = MEMORY_HEAP_PREV(c); - TMemItem mc = MEMORY_HEAP_NEXT(c); - TMemItem nc = MEMORY_HEAP_NEXT(mc); - if (--nc & 1) nc = mc; - else _FreeDel(fs, mc); - if (free_a == 1) return; - if (pc && MEMORY_HEAP_FREE(pc)) _FreeDel(fs, c = pc); - MEMORY_HEAP_NEXT(c) = nc + 1; - MEMORY_HEAP_PREV(nc) = c; - if (free_a == 2) return; - _FreeAdd(fs, c); - } + long mem_Init(); + void *mem_Alloc(unsigned long size); + void *mem_ReAlloc(unsigned long size, void *mem); + bool mem_Free(void *mem); } -#endif // ndef __MEMORY_HEAP_RBTREE_H_INCLUDED_ +#endif // ndef __MEMORY_HEAP_H_INCLUDED_