diff --git a/kernel/trunk/core/heap.inc b/kernel/trunk/core/heap.inc index 24c7296738..26ff36ee65 100644 --- a/kernel/trunk/core/heap.inc +++ b/kernel/trunk/core/heap.inc @@ -752,6 +752,9 @@ proc user_free stdcall, base:dword test eax, 1 jz @F call free_page + mov eax, esi + shl eax, 12 + invlpg [eax] @@: inc esi dec ecx @@ -764,6 +767,18 @@ proc user_free stdcall, base:dword sub ebx, [edx+SLOT_BASE+APPDATA.mem_size] neg ebx call update_mem_size + call user_normalize + ret +.exit: + xor eax, eax + inc eax + ret +endp + +user_normalize: +; in: esi=heap_base, edi=heap_top +; out: eax=0 <=> OK +; destroys: ebx,edx,esi,edi add esi, new_app_base add edi, new_app_base shr esi, 12 @@ -808,7 +823,239 @@ proc user_free stdcall, base:dword .err: xor eax, eax ret -endp + +user_realloc: +; in: eax = pointer, ebx = new size +; out: eax = new pointer or NULL + test eax, eax + jnz @f +; realloc(NULL,sz) - same as malloc(sz) + push ebx + call user_alloc + ret +@@: + push ecx edx + lea ecx, [eax + new_app_base - 0x1000] + shr ecx, 12 + mov edx, [page_tabs+ecx*4] + test edx, USED_BLOCK + jnz @f +; attempt to realloc invalid pointer +.ret0: + pop edx ecx + xor eax, eax + ret +@@: + add ebx, 0x1FFF + shr edx, 12 + shr ebx, 12 +; edx = allocated size, ebx = new size + add edx, ecx + add ebx, ecx + cmp edx, ebx + jb .realloc_add +; release part of allocated memory +.loop: + cmp edx, ebx + jz .release_done + dec edx + xor eax, eax + xchg eax, [page_tabs+edx*4] + test al, 1 + jz .loop + call free_page + mov eax, edx + shl eax, 12 + invlpg [eax] + jmp .loop +.release_done: + sub ebx, ecx + cmp ebx, 1 + jnz .nofreeall + mov eax, [page_tabs+ecx*4] + and eax, not 0xFFF + mov edx, [CURRENT_TASK] + shl edx, 8 + mov ebx, [SLOT_BASE+APPDATA.mem_size+edx] + sub ebx, eax + add ebx, 0x1000 + or al, FREE_BLOCK + mov [page_tabs+ecx*4], eax + push esi edi + mov esi, [SLOT_BASE+APPDATA.heap_base+edx] + mov edi, [SLOT_BASE+APPDATA.heap_top+edx] + call update_mem_size + call user_normalize + pop edi esi + jmp .ret0 ; all freed +.nofreeall: + sub edx, ecx + shl ebx, 12 + or ebx, USED_BLOCK + xchg [page_tabs+ecx*4], ebx + shr ebx, 12 + sub ebx, edx + push ebx ecx edx + mov edx, [CURRENT_TASK] + shl edx, 8 + shl ebx, 12 + sub ebx, [SLOT_BASE+APPDATA.mem_size+edx] + neg ebx + call update_mem_size + pop edx ecx ebx + lea eax, [ecx+1-(new_app_base shr 12)] + shl eax, 12 + push eax + add ecx, ebx + add edx, ecx + shl ebx, 12 + jz .ret + push esi + mov esi, [CURRENT_TASK] + shl esi, 8 + mov esi, [SLOT_BASE+APPDATA.heap_top+esi] + shr esi, 12 +@@: + cmp edx, esi + jae .merge_done + mov eax, [page_tabs+edx*4] + test al, USED_BLOCK + jz .merge_done + and dword [page_tabs+edx*4], 0 + and eax, not 0xFFF + add ebx, eax + add edx, eax + jmp @b +.merge_done: + pop esi + or ebx, FREE_BLOCK + mov [page_tabs+ecx*4], ebx +.ret: + pop eax edx ecx + ret +.realloc_add: +; get some additional memory + mov eax, [CURRENT_TASK] + shl eax, 8 + mov eax, [SLOT_BASE+APPDATA.heap_top+eax] + add eax, new_app_base + shr eax, 12 + cmp edx, eax + jae .cant_inplace + mov eax, [page_tabs+edx*4] + shr eax, 12 + add eax, edx + cmp eax, ebx + jb .cant_inplace + sub eax, ebx + jz @f + shl eax, 12 + or al, FREE_BLOCK + mov [page_tabs+ebx*4], eax +@@: + mov eax, ebx + sub eax, ecx + shl eax, 12 + or al, USED_BLOCK + mov [page_tabs+ecx*4], eax + lea eax, [ecx+1-(new_app_base shr 12)] + shl eax, 12 + push eax + push edi + lea edi, [page_tabs+edx*4] + mov eax, 2 + sub ebx, edx + mov ecx, ebx + cld + rep stosd + pop edi + mov edx, [CURRENT_TASK] + shl edx, 8 + shl ebx, 12 + add ebx, [SLOT_BASE+APPDATA.mem_size+edx] + call update_mem_size + pop eax edx ecx + ret +.cant_inplace: + push esi edi + mov eax, [CURRENT_TASK] + shl eax, 8 + mov esi, [SLOT_BASE+APPDATA.heap_base+eax] + mov edi, [SLOT_BASE+APPDATA.heap_top+eax] + add esi, new_app_base + add edi, new_app_base + shr esi, 12 + shr edi, 12 + sub ebx, ecx +.find_place: + cmp esi, edi + jae .place_not_found + mov eax, [page_tabs+esi*4] + test al, FREE_BLOCK + jz .next_place + shr eax, 12 + cmp eax, ebx + jae .place_found + add esi, eax + jmp .find_place +.next_place: + shr eax, 12 + add esi, eax + jmp .find_place +.place_not_found: + pop edi esi + jmp .ret0 +.place_found: + sub eax, ebx + jz @f + push esi + add esi, eax + shl eax, 12 + or al, FREE_BLOCK + mov [page_tabs+esi*4], eax + pop esi +@@: + mov eax, ebx + shl eax, 12 + or al, USED_BLOCK + mov [page_tabs+esi*4], eax + inc esi + mov eax, esi + shl eax, 12 + sub eax, new_app_base + push eax + mov eax, [page_tabs+ecx*4] + and eax, not 0xFFF + or al, FREE_BLOCK + sub edx, ecx + mov [page_tabs+ecx*4], eax + inc ecx +@@: + xor eax, eax + xchg eax, [page_tabs+ecx*4] + mov [page_tabs+esi*4], eax + mov eax, ecx + shl eax, 12 + invlpg [eax] + inc ecx + inc esi + dec ebx + dec edx + jnz @b + push ebx + mov edx, [CURRENT_TASK] + shl edx, 8 + shl ebx, 12 + add ebx, [SLOT_BASE+APPDATA.mem_size+edx] + call update_mem_size + pop ebx +@@: + mov dword [page_tabs+esi*4], 2 + inc esi + dec ebx + jnz @b + pop eax edi esi edx ecx + ret if 0 align 4 diff --git a/kernel/trunk/core/memory.inc b/kernel/trunk/core/memory.inc index 91ca2f2236..7399a102b0 100644 --- a/kernel/trunk/core/memory.inc +++ b/kernel/trunk/core/memory.inc @@ -267,13 +267,12 @@ proc free_page pushfd cli shr eax, 12 ;page index - mov ebx, sys_pgmap - bts [ebx], eax ;that's all! + bts dword [sys_pgmap], eax ;that's all! cmc adc [pg_data.pages_free], 0 shr eax, 3 and eax, not 3 ;dword offset from page_map - add eax, ebx + add eax, sys_pgmap cmp [page_start], eax ja @f popfd @@ -1082,7 +1081,7 @@ new_services: ret @@: cmp eax, 19 - ja .fail + ja @f add ebx, new_app_base cmp ebx, new_app_base jb .fail @@ -1090,6 +1089,14 @@ new_services: mov [esp+36], eax ret +@@: + cmp eax, 20 + ja .fail + mov eax, ecx + call user_realloc + mov [esp+36], eax + ret + .fail: xor eax, eax mov [esp+36], eax diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index 1609cec4b9..63e5e24592 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/kernel/trunk/docs/sysfuncr.txt @@ -3316,7 +3316,7 @@ IPC ====================================================================== ================ Функция 63 - работа с доской отладки. =============== ====================================================================== -Доска отладки представляет собой системный буфер (на 512 байт), +Доска отладки представляет собой системный буфер (на 4096 байт), в который любая программа может записать (вообще говоря, произвольные) данные и из которого другая программа может эти данные прочитать. Есть соглашение, в соответствии с которым записываемые данные - @@ -3644,7 +3644,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * eax = 1 - успешно * eax = 0 - неудача Замечания: - * Блок памяти должен быть ранее выделен подфункцией 12. + * Блок памяти должен быть ранее выделен подфункцией 12 + или подфункцией 20. ====================================================================== ===== Функция 68, подфункция 14 - ожидать извещения от драйвера. ===== @@ -3736,6 +3737,30 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); заканчивающийся нулём. Первый dword в структуре является указателем на имя функции, второй содержит адрес функции. +====================================================================== +====== Функция 68, подфункция 20 - перераспределить блок памяти. ===== +====================================================================== +Параметры: + * eax = 68 - номер функции + * ebx = 20 - номер подфункции + * ecx = новый размер в байтах + * edx = указатель на уже выделенный блок памяти +Возвращаемое значение: + * eax = указатель на перераспределённый блок, 0 при ошибке +Замечания: + * Предварительно следует инициализировать кучу процесса вызовом + подфункции 11. + * Функция выделяет целое число страниц (4 Кб) так, что фактический + размер выделенного блока больше или равен запрошенному. + * Если edx=0, то вызов функции эквивалентен выделению памяти + подфункцией 12. В противном случае блок памяти по адресу edx + должен быть ранее выделен подфункцией 12 или + описываемой подфункцией. + * Если ecx=0, то функция освобождает блок памяти по адресу edx и + возвращает 0. + * Содержимое памяти вплоть до наименьшего из старого и нового + размеров сохраняется. + ====================================================================== ======================== Функция 69 - отладка. ======================= ====================================================================== @@ -4480,9 +4505,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); 7, 8 функции 21) * 2 = функция не поддерживается для данной файловой системы * 3 = неизвестная файловая система - * 4 = возвращается только функцией rename при передаче сильно - неверного параметра и никак не соответствует описанию - в исходниках ядра "partition not defined at hd" + * 4 = зарезервировано, никогда не возвращается в текущей реализации * 5 = файл не найден * 6 = файл закончился * 7 = указатель вне памяти приложения diff --git a/kernel/trunk/docs/sysfuncs.txt b/kernel/trunk/docs/sysfuncs.txt index afec4891a1..d0deac7c2a 100644 --- a/kernel/trunk/docs/sysfuncs.txt +++ b/kernel/trunk/docs/sysfuncs.txt @@ -3285,7 +3285,7 @@ Remarks: ============== Function 63 - work with the debug board. ============== ====================================================================== The debug board is the global system buffer (with the size -512 bytes), to which any program can write (generally speaking, +4096 bytes), to which any program can write (generally speaking, arbitrary) data and from which other program can read these data. By the agreement written data are text strings interpreted as debug messages on a course of program execution. The kernel in @@ -3615,7 +3615,8 @@ Returned value: * eax = 1 - success * eax = 0 - failed Remarks: - * The memory block must have been allocated by subfunction 12. + * The memory block must have been allocated by subfunction 12 + or subfunction 20. ====================================================================== ======== Function 68, subfunction 14 - wait for driver notify. ======= @@ -3705,6 +3706,29 @@ Remarks: by zero. The first dword in structure points to function name, the second dword contains address of function. +====================================================================== +======= Function 68, subfunction 20 - reallocate memory block. ======= +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 20 - subfunction number + * ecx = new size in bytes + * edx = pointer to already allocated block +Returned value: + * eax = pointer to the reallocated block, 0 = error +Remarks: + * Before this call one must initialize process heap by call to + subfunction 11. + * The function allocates an integer number of pages (4 Kb) in such + way that the real size of allocated block is more than or equal to + requested size. + * If edx=0, the function call is equivalent to memory allocation + with subfunction 12. Otherwise the block at edx + must be allocated earlier with subfunction 12 or this subfunction. + * If ecx=0, the function frees memory block at edx and returns 0. + * The contents of the block are unchanged up to the shorter of + the new and old sizes. + ====================================================================== ====================== Fucntion 69 - debugging. ====================== ====================================================================== @@ -4435,10 +4459,7 @@ Codes of events: (by subfunctions 7, 8 of function 21) * 2 = function is not supported for the given file system * 3 = unknown file system - * 4 = is returned only from function 'rename' by transmission of - the strongly incorrect parameter and in any way does not - correspond to the description in the kernel sources - "partition not defined at hd" + * 4 = reserved, is never returned in the current implementation * 5 = file not found * 6 = end of file, EOF * 7 = pointer lies outside of application memory