Merge branch 'feature/memory-allocation-optimization' into feature/wasm
continuous-integration/drone/push Build is failing

# Conflicts:
#	src/kernel.pas
#	src/lmemorymanager.pas
#	src/progmanager.pas
This commit is contained in:
t3hn3rd committed 2026-03-04 11:29:00 +00:00
commit 7d518418c2
7 files changed
+892 -331

No files matched your search

+1 -1
View File
@@ -6,7 +6,7 @@ echo "Compiling FPC Sources..."
echo " "
# Build -Fu flags for all directories under src/ and wasuro/
FU_PATHS=""
FU_PATHS="-Fusrc -Fuwasuro"
for dir in $(find src wasuro -type d 2>/dev/null); do
FU_PATHS="$FU_PATHS -Fu$dir"
done
+11 -4
View File
@@ -211,11 +211,8 @@ begin
{ VFS Init }
vfs.init();
{ Let's test Wasuro! }
wasm.vm.io.io_set_writechar(@syslog.logchar);
{ Let's init Wasuro! }
wasm.wasm_init;
wasm.test.run_all_tests;
kernel.yield();
{ Management Interfaces }
tracer.push_trace('kmain.DRVMGMT');
@@ -285,6 +282,16 @@ begin
usbhub.UnitTest;
usb_keyboard.UnitTest;
usb_mouse.UnitTest;
syslog.logln('WASM', 'Unit tests starting...');
wasm.test.run_all_tests;
syslog.writestring('[WASM] ');
syslog.writeint(wasm.test.framework.PassedTests);
syslog.writestring(' passed, ');
syslog.writeint(wasm.test.framework.FailedTests);
syslog.writestringln(' failed.');
{ Set syslog IO hooks for Wasm }
wasm.vm.io.io_set_writechar(@syslog.logchar);
{ Register timer-driven tasks }
graphicsrefresh.init;
+520 -169
View File
File diff suppressed because it is too large. Load diff
+246 -106
View File
File diff suppressed because it is too large. Load diff
+83
View File
@@ -0,0 +1,83 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Prog->meminfo - Print memory statistics (PMM / LMM).
@author(Kieron Morris <[email protected]>)
}
unit meminfo;
interface
uses
stdio, multiboot, pmemorymanager, lmemorymanager, tracer;
procedure init();
implementation
procedure run(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
var
pmm_total, pmm_free, pmm_used : uint32;
lmm_pages, lmm_free : uint32;
begin
{ Multiboot memory info }
stdio.bufWriteStrLn(stdout_buf, '--- Multiboot ---');
stdio.bufWriteStr(stdout_buf, 'Lower Memory : ');
stdio.bufWriteInt(stdout_buf, multibootinfo^.mem_lower);
stdio.bufWriteStrLn(stdout_buf, ' KB');
stdio.bufWriteStr(stdout_buf, 'Upper Memory : ');
stdio.bufWriteInt(stdout_buf, multibootinfo^.mem_upper);
stdio.bufWriteStrLn(stdout_buf, ' KB');
stdio.bufWriteStr(stdout_buf, 'Total Memory : ');
stdio.bufWriteInt(stdout_buf, ((multibootinfo^.mem_upper + 1000) div 1024) + 1);
stdio.bufWriteStrLn(stdout_buf, ' MB');
{ PMM stats }
stdio.bufWriteStrLn(stdout_buf, '--- PMM (4 MB blocks) ---');
pmm_total := pmemorymanager.pmm_total_blocks;
pmm_free := pmemorymanager.pmm_free_blocks;
pmm_used := pmm_total - pmm_free;
stdio.bufWriteStr(stdout_buf, 'Total Blocks : ');
stdio.bufWriteIntLn(stdout_buf, pmm_total);
stdio.bufWriteStr(stdout_buf, 'Free Blocks : ');
stdio.bufWriteIntLn(stdout_buf, pmm_free);
stdio.bufWriteStr(stdout_buf, 'Used Blocks : ');
stdio.bufWriteIntLn(stdout_buf, pmm_used);
stdio.bufWriteStr(stdout_buf, 'Free Physical : ');
stdio.bufWriteInt(stdout_buf, pmm_free * 4);
stdio.bufWriteStrLn(stdout_buf, ' MB');
{ LMM heap stats }
stdio.bufWriteStrLn(stdout_buf, '--- LMM (Heap) ---');
lmm_pages := lmemorymanager.lmm_page_count;
lmm_free := lmemorymanager.lmm_total_free;
stdio.bufWriteStr(stdout_buf, 'Heap Pages : ');
stdio.bufWriteIntLn(stdout_buf, lmm_pages);
stdio.bufWriteStr(stdout_buf, 'Heap Size : ');
stdio.bufWriteInt(stdout_buf, lmm_pages * 4);
stdio.bufWriteStrLn(stdout_buf, ' MB');
stdio.bufWriteStr(stdout_buf, 'Heap Free : ');
stdio.bufWriteInt(stdout_buf, lmm_free div 1024);
stdio.bufWriteStrLn(stdout_buf, ' KB');
end;
procedure init();
begin
tracer.push_trace('meminfo.init');
stdio.registerCommand('MEMINFO', @Run, 'Print memory statistics (PMM/LMM).');
end;
end.
+5 -29
View File
@@ -24,47 +24,23 @@ interface
uses
tracer,
//progs
base64_prog, md5sum, dhclient, vbeinfo, testcmd, ping;
base64_prog, md5sum, dhclient, vbeinfo, meminfo;
{ Initialize all baked-in programs }
procedure init();
implementation
uses
stdio,
//command provider units
kernel, cpu, drivermanagement, processmanager,
arp, ipv4, tcp,
storagemanagement, usbcore;
procedure init();
begin
tracer.push_trace('progmanager.init');
{ Register commands from provider units }
stdio.registerCommand('MEMINFO', @kernel.terminal_command_meminfo, 'Print Simple Memory Information.');
stdio.registerCommand('BSOD', @kernel.terminal_command_bsod, 'Force a Panic Screen.');
stdio.registerCommand('CPU', @cpu.Terminal_Command_CPU, 'CPU Info.');
stdio.registerCommand('DEV', @drivermanagement.terminal_command_dev, 'Driver Management Interface.');
stdio.registerCommand('PS', @processmanager.terminal_command_ps, 'List running processes.');
stdio.registerCommand('KILL', @processmanager.terminal_command_kill, 'Force-kill a process by PID.');
stdio.registerCommand('TERMINATE', @processmanager.terminal_command_terminate, 'Gracefully terminate a process by PID.');
stdio.registerCommand('ARP', @arp.terminal_command_arp, 'Get ARP Table.');
stdio.registerCommand('IFCONFIG', @ipv4.terminal_command_ifconfig, 'Configure Network Settings.');
stdio.registerCommand('TCPCONNECT', @tcp.terminal_command_tcpconnect, 'Connect to a TCP host and send Hello World.');
stdio.registerCommand('TCPLISTEN', @tcp.terminal_command_tcplisten, 'Listen on a TCP port and log received data.');
stdio.registerCommand('TCPHTTP', @tcp.terminal_command_tcphttp, 'Send HTTP GET to a host IP (port 80 default).');
stdio.registerCommand('DISK', @storagemanagement.disk_command, 'Disk utility');
stdio.registerCommand('USB', @usbcore.terminal_command_usb, 'USB subsystem information.');
{ Initialize baked-in programs }
tracer.push_trace('progmanager.md5sum.init');
md5sum.init();
tracer.push_trace('progmanager.base64_prog.init');
base64_prog.init();
tracer.push_trace('progmanager.dhclient.init');
dhclient.init();
vbeinfo.init();
testcmd.init();
ping.init();
meminfo.init();
end;
end.
+26 -22
View File
@@ -159,20 +159,14 @@ end;
function map_page(page_number : uint16; block : uint16) : boolean;
var
addr : ubit20;
page : uint16;
rldpd : uint32;
begin
push_trace('vmemorymanager.map_page');
map_page:= false;
PageDirectory^[page_number].Present:= true;
addr:= block;
PageDirectory^[page_number].Address:= addr SHL 10;
PageDirectory^[page_number].PageSize:= true;
PageDirectory^[page_number].Writable:= true;
map_page:= map_page_ex(page_number, block, PageDirectory);
rldpd:= uint32(PageDirectory) - KERNEL_VIRTUAL_BASE;
{ Delegate to map_page_ex — no redundant direct PDE writes }
map_page := map_page_ex(page_number, block, PageDirectory);
{ Reload CR3 to flush TLB }
rldpd := uint32(PageDirectory) - KERNEL_VIRTUAL_BASE;
asm
mov eax, rldpd
mov CR3, eax
@@ -201,14 +195,15 @@ var
begin
push_trace('vmemorymanager.new_page');
new_page:= false;
new_page := false;
if not PageDirectory^[page_number].Present then begin
if not PageDirectory^[page_number].Reserved then begin
block:= pmemorymanager.new_block(uint32(PageDirectory));
if block < 2 then begin
GPF;
block := pmemorymanager.new_block(uint32(PageDirectory));
if block = 0 then begin
{ OOM — PMM has no free blocks. Return false gracefully. }
syslog.logln('VMM', 'ERROR: new_page failed — PMM OOM.');
end else begin
new_page:= map_page(page_number, block);
new_page := map_page(page_number, block);
end;
end;
end;
@@ -216,17 +211,15 @@ begin
end;
function page_mappable(page_number : uint16) : boolean;
var
block : uint16;
begin
push_trace('vmemorymanager.page_mappable');
page_mappable:= false;
page_mappable := false;
if not PageDirectory^[page_number].Present then begin
if not PageDirectory^[page_number].Reserved then begin
page_mappable:= true;
page_mappable := true;
end;
end;
pop_trace;
end;
function new_page_at_address(address : uint32) : boolean;
@@ -243,14 +236,25 @@ end;
procedure free_page(page_number : uint16);
var
block : uint16;
vaddr : uint32;
begin
push_trace('vmemorymanager.free_page');
if PageDirectory^[page_number].Present then begin
block:= PageDirectory^[page_number].Address;
{ Recover block index: Address stores (block SHL 10), so SHR 10 gives block }
block := PageDirectory^[page_number].Address SHR 10;
{ Clear the PDE before invalidating }
PageDirectory^[page_number].Present := false;
PageDirectory^[page_number].Writable := false;
PageDirectory^[page_number].PageSize := false;
PageDirectory^[page_number].Address := 0;
{ Invalidate TLB for this virtual address (invlpg needs a virtual addr) }
vaddr := uint32(page_number) SHL 22;
asm
invlpg [page_number]
mov eax, vaddr
invlpg [eax]
end;
{ Return physical block to PMM }
pmemorymanager.free_block(block, uint32(PageDirectory));
end else begin
GPF;