task manager fix

This commit is contained in:
boreddevnl
2026-03-13 14:48:58 +01:00
parent 569adabf10
commit 95c465ca39
13 changed files with 171 additions and 64 deletions

View File

@@ -9,15 +9,9 @@
extern void serial_print(const char *s);
extern void serial_write(const char *str);
static void print_hex(uint64_t n) {
char buf[17];
char* x = "0123456789ABCDEF";
buf[16] = 0;
for (int i=15; i>=0; i--) { buf[i] = x[n & 0xF]; n >>= 4; }
serial_write(buf);
}
uint64_t elf_load(const char *path, uint64_t user_pml4) {
uint64_t elf_load(const char *path, uint64_t user_pml4, size_t *out_load_size) {
if (out_load_size) *out_load_size = 0;
FAT32_FileHandle *file = fat32_open(path, "r");
if (!file || !file->valid) {
serial_write("[ELF] Error: Failed to open file ");
@@ -113,6 +107,7 @@ uint64_t elf_load(const char *path, uint64_t user_pml4) {
uint64_t phys_addr = v2p((uint64_t)bulk_phys + (p * 4096));
paging_map_page(user_pml4, vaddr, phys_addr, 0x07);
}
if (out_load_size) *out_load_size += total_needed;
}
}

View File

@@ -69,9 +69,10 @@ typedef struct {
#define PF_R 4
#include <stdbool.h>
#include <stddef.h>
// Loads the ELF executable at 'path' using fat32 into the pagemap given by user_pml4.
// Returns entry point address on success, or 0 on failure.
uint64_t elf_load(const char *path, uint64_t user_pml4);
uint64_t elf_load(const char *path, uint64_t user_pml4, size_t *out_load_size);
#endif

View File

@@ -44,6 +44,7 @@ void process_init(void) {
extern void mem_memcpy(void *dest, const void *src, size_t len);
mem_memcpy(kernel_proc->name, "kernel", 7);
kernel_proc->ticks = 0;
kernel_proc->used_memory = 32768; // Kernel stack
kernel_proc->next = kernel_proc; // Circular linked list
current_process = kernel_proc;
@@ -168,7 +169,8 @@ process_t* process_create_elf(const char* filepath, const char* args_str) {
new_proc->is_terminal_proc = false;
// 2. Load ELF executable
uint64_t entry_point = elf_load(filepath, new_proc->pml4_phys);
size_t elf_load_size = 0;
uint64_t entry_point = elf_load(filepath, new_proc->pml4_phys, &elf_load_size);
if (entry_point == 0) {
serial_write("[PROCESS] Failed to load ELF: ");
serial_write(filepath);
@@ -307,6 +309,7 @@ process_t* process_create_elf(const char* filepath, const char* args_str) {
new_proc->kernel_stack_alloc = kernel_stack;
new_proc->user_stack_alloc = stack;
new_proc->rsp = (uint64_t)stack_ptr;
new_proc->used_memory = elf_load_size + user_stack_size + 65536;
// Initialize FPU state for new process
asm volatile("fninit");

View File

@@ -51,6 +51,7 @@ typedef struct process {
char name[64];
uint64_t ticks;
uint64_t sleep_until;
size_t used_memory;
} __attribute__((aligned(16))) process_t;
typedef struct {

View File

@@ -45,18 +45,12 @@ void syscall_init(void) {
efer |= 1; // SCE bit is bit 0
wrmsr(MSR_EFER, efer);
// STAR MSR setup:
// Bits 32-47: Syscall CS and SS. CS = STAR[47:32], SS = STAR[47:32] + 8 (Kernel CS = 0x08)
// Bits 48-63: Sysret CS and SS. CS = STAR[63:48] + 16, SS = STAR[63:48] + 8.
// User Data must be Base+8, User Code must be Base+16.
// Our GDT: User Data = 0x1B, User Code = 0x23.
// Therefore Base = 0x13.
uint64_t star = ((uint64_t)0x08 << 32) | ((uint64_t)0x13 << 48);
wrmsr(MSR_STAR, star);
wrmsr(MSR_LSTAR, (uint64_t)syscall_entry);
// Mask Interrupts on SYSCALL (Clear IF bit in RFLAGS during syscall execution)
wrmsr(MSR_FMASK, 0x200);
}
@@ -849,6 +843,7 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
paging_map_page(proc->pml4_phys, page, v2p(phys_addr), 0x07); // PT_PRESENT | PT_RW | PT_USER
phys_addr += 4096;
}
proc->used_memory += (end_page - start_page);
}
}
@@ -1120,7 +1115,19 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
if (!out) return 0;
extern process_t processes[];
extern int process_count;
// Dynamically calculate kernel usage as: Total System Used - User Process Sum
MemStats stats = memory_get_stats();
size_t total_used = stats.used_memory;
size_t user_used = 0;
for (int i = 0; i < 16; i++) {
if (processes[i].pid != 0xFFFFFFFF && processes[i].pid != 0) {
user_used += processes[i].used_memory;
}
}
if (total_used > user_used) processes[0].used_memory = total_used - user_used;
else processes[0].used_memory = 0;
int count = 0;
for (int i = 0; i < 16; i++) { // MAX_PROCESSES is 16
if (processes[i].pid != 0xFFFFFFFF) {
@@ -1129,19 +1136,7 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
mem_memcpy(out[count].name, processes[i].name, 64);
out[count].ticks = processes[i].ticks;
// Memory estimation: heap + stacks
size_t mem = 0;
if (processes[i].heap_end > processes[i].heap_start)
mem += (processes[i].heap_end - processes[i].heap_start);
if (processes[i].pid == 0) {
mem = 32768;
} else {
if (processes[i].is_user) mem += 262144; // User stack
mem += 32768; // Kernel stack
}
out[count].used_memory = mem;
out[count].used_memory = processes[i].used_memory;
count++;
if (count >= max_procs) break;

View File

@@ -601,6 +601,11 @@ static uint32_t parse_html_color(const char *str) {
if (str_istarts_with(str, "yellow")) return 0xFFFFFF00;
if (str_istarts_with(str, "gray")) return 0xFF808080;
if (str_istarts_with(str, "purple")) return 0xFF800080;
if (str_istarts_with(str, "silver")) return 0xFFC0C0C0;
if (str_istarts_with(str, "maroon")) return 0xFF800000;
if (str_istarts_with(str, "navy")) return 0xFF000080;
if (str_istarts_with(str, "teal")) return 0xFF008080;
if (str_istarts_with(str, "olive")) return 0xFF808000;
return COLOR_TEXT;
}
@@ -650,6 +655,27 @@ static void decode_html_entities(char *str) {
if (str_istarts_with(src, "&Aacute;")) { *dst++ = (char)193; src += 8; continue; }
if (str_istarts_with(src, "&times;")) { *dst++ = (char)215; src += 7; continue; }
if (str_istarts_with(src, "&divide;")) { *dst++ = (char)247; src += 8; continue; }
if (str_istarts_with(src, "&plusmn;")) { *dst++ = (char)177; src += 8; continue; }
if (str_istarts_with(src, "&micro;")) { *dst++ = (char)181; src += 7; continue; }
if (str_istarts_with(src, "&para;")) { *dst++ = (char)182; src += 6; continue; }
if (str_istarts_with(src, "&brvbar;")) { *dst++ = (char)166; src += 8; continue; }
if (str_istarts_with(src, "&sect;")) { *dst++ = (char)167; src += 6; continue; }
if (str_istarts_with(src, "&uml;")) { *dst++ = (char)168; src += 5; continue; }
if (str_istarts_with(src, "&ordf;")) { *dst++ = (char)170; src += 6; continue; }
if (str_istarts_with(src, "&laquo;")) { *dst++ = (char)171; src += 7; continue; }
if (str_istarts_with(src, "&not;")) { *dst++ = (char)172; src += 5; continue; }
if (str_istarts_with(src, "&shy;")) { src += 5; continue; } // Soft hyphen, ignore
if (str_istarts_with(src, "&macr;")) { *dst++ = (char)175; src += 6; continue; }
if (str_istarts_with(src, "&sup2;")) { *dst++ = (char)178; src += 6; continue; }
if (str_istarts_with(src, "&sup3;")) { *dst++ = (char)179; src += 6; continue; }
if (str_istarts_with(src, "&acute;")) { *dst++ = (char)180; src += 7; continue; }
if (str_istarts_with(src, "&cedil;")) { *dst++ = (char)184; src += 7; continue; }
if (str_istarts_with(src, "&sup1;")) { *dst++ = (char)185; src += 6; continue; }
if (str_istarts_with(src, "&ordm;")) { *dst++ = (char)186; src += 6; continue; }
if (str_istarts_with(src, "&raquo;")) { *dst++ = (char)187; src += 7; continue; }
if (str_istarts_with(src, "&frac14;")) { *dst++ = (char)188; src += 8; continue; }
if (str_istarts_with(src, "&frac12;")) { *dst++ = (char)189; src += 8; continue; }
if (str_istarts_with(src, "&frac34;")) { *dst++ = (char)190; src += 8; continue; }
if (src[1] == '#') {
int val = 0;
@@ -704,12 +730,14 @@ static void parse_html(const char *html) {
int list_type[16] = {0}; int list_index[16] = {0};
bool is_pre = false;
bool is_plaintext = false;
int table_col = 0;
next_form_id = 1;
bool inside_title = false;
char page_title[256] = "";
while (html[i] && element_count < MAX_ELEMENTS) {
if (html[i] == '<') {
if (html[i] == '<' && !is_plaintext) {
if (html[i+1] == '!' && html[i+2] == '-' && html[i+3] == '-') {
i += 4;
while (html[i] && !(html[i] == '-' && html[i+1] == '-' && html[i+2] == '>')) i++;
@@ -730,7 +758,28 @@ static void parse_html(const char *html) {
if (tag_name[0] == '/') {
if (str_iequals(tag_name+1, "center")) { emit_br(); if (center_depth > 0) center_depth--; }
else if (str_iequals(tag_name+1, "table")) { emit_br(); if (table_depth > 0) table_depth--; }
else if (str_iequals(tag_name+1, "table")) { emit_br(); if (table_depth > 0) table_depth--; table_col = 0; }
else if (str_iequals(tag_name+1, "tr")) { emit_br(); table_col = 0; }
else if (str_iequals(tag_name+1, "td") || str_iequals(tag_name+1, "th")) {
table_col++;
if (table_col == 1) {
// Add spacer to align second column
RenderElement *el = &elements[element_count++];
memset(el, 0, sizeof(RenderElement));
el->tag = TAG_NONE; el->content[0] = ' '; el->content[1] = 0;
int current_x = cur_line_x;
for (int k=0; k<line_element_count; k++) current_x += elements[line_elements[k]].w;
int target_x = 160 + (blockquote_depth * 20) + (list_depth * 20);
if (current_x < target_x) {
el->w = target_x - current_x;
} else {
el->w = 10;
}
el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
}
if (str_iequals(tag_name+1, "th")) is_bold = false;
}
else if (str_iequals(tag_name+1, "caption")) { emit_br(); is_bold = false; if (center_depth > 0) center_depth--; }
else if (str_iequals(tag_name+1, "blockquote")) { emit_br(); if (blockquote_depth > 0) blockquote_depth--; }
else if (str_iequals(tag_name+1, "ul") || str_iequals(tag_name+1, "ol") || str_iequals(tag_name+1, "dl") || str_iequals(tag_name+1, "dir") || str_iequals(tag_name+1, "menu")) { emit_br(); if (list_depth > 0) list_depth--; }
@@ -748,7 +797,7 @@ static void parse_html(const char *html) {
}
else if (str_iequals(tag_name+1, "a")) current_link[0] = 0;
else if (str_iequals(tag_name+1, "p") || str_iequals(tag_name+1, "li") || str_iequals(tag_name+1, "div") || str_iequals(tag_name+1, "address")) emit_br();
else if (str_iequals(tag_name+1, "pre")) { emit_br(); is_pre = false; }
else if (str_iequals(tag_name+1, "pre") || str_iequals(tag_name+1, "xmp") || str_iequals(tag_name+1, "listing")) { emit_br(); is_pre = false; }
else if (str_iequals(tag_name+1, "font") || str_iequals(tag_name+1, "tt") || str_iequals(tag_name+1, "code") || str_iequals(tag_name+1, "samp") || str_iequals(tag_name+1, "kbd")) {
if (font_ptr > 0) {
font_ptr--;
@@ -767,7 +816,19 @@ static void parse_html(const char *html) {
}
} else {
if (str_iequals(tag_name, "center")) { emit_br(); center_depth++; }
else if (str_iequals(tag_name, "table")) { emit_br(); table_depth++; }
else if (str_iequals(tag_name, "table")) { emit_br(); table_depth++; table_col = 0; }
else if (str_iequals(tag_name, "tr")) { emit_br(); table_col = 0; }
else if (str_iequals(tag_name, "td") || str_iequals(tag_name, "th")) {
if (table_col > 0) {
RenderElement *el = &elements[element_count++];
memset(el, 0, sizeof(RenderElement));
el->tag = TAG_NONE; el->content[0] = ' '; el->content[1] = 0; el->w = 10;
el->h = ui_get_font_height_scaled(current_scale);
el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
}
if (str_iequals(tag_name, "th")) is_bold = true;
}
else if (str_iequals(tag_name, "caption")) { emit_br(); center_depth++; is_bold = true; }
else if (str_iequals(tag_name, "blockquote")) { emit_br(); blockquote_depth++; } // Handle blockquote start
else if (str_iequals(tag_name, "ul") || str_iequals(tag_name, "dir") || str_iequals(tag_name, "menu")) { emit_br(); list_type[list_depth] = 0; list_depth++; }
@@ -787,16 +848,18 @@ static void parse_html(const char *html) {
}
else if (str_iequals(tag_name, "b") || str_iequals(tag_name, "strong")) is_bold = true;
else if (str_iequals(tag_name, "i") || str_iequals(tag_name, "em") || str_iequals(tag_name, "cite") || str_iequals(tag_name, "var")) is_italic = true;
else if (str_iequals(tag_name, "u")) is_underline = true;
else if (str_iequals(tag_name, "tt") || str_iequals(tag_name, "code") || str_iequals(tag_name, "samp") || str_iequals(tag_name, "kbd")) {
else if (str_iequals(tag_name, "i") || str_iequals(tag_name, "em") || str_iequals(tag_name, "cite") || str_iequals(tag_name, "var") || str_iequals(tag_name, "dfn")) is_italic = true;
else if (str_iequals(tag_name, "u") || str_iequals(tag_name, "s") || str_iequals(tag_name, "strike")) is_underline = true;
else if (str_iequals(tag_name, "tt") || str_iequals(tag_name, "code") || str_iequals(tag_name, "samp") || str_iequals(tag_name, "kbd") || str_iequals(tag_name, "xmp") || str_iequals(tag_name, "listing")) {
if (font_ptr < MAX_FONT_STACK) {
font_stack[font_ptr].color = current_color;
font_stack[font_ptr].scale = current_scale;
font_ptr++;
}
current_scale = 14.0f;
if (str_iequals(tag_name, "xmp") || str_iequals(tag_name, "listing")) { emit_br(); is_pre = true; }
}
else if (str_iequals(tag_name, "plaintext")) { emit_br(); is_plaintext = true; is_pre = true; current_scale = 14.0f; }
else if (str_iequals(tag_name, "address")) { emit_br(); }
else if (str_iequals(tag_name, "html") || str_iequals(tag_name, "body")) skip_content = false;
else if (str_iequals(tag_name, "head")) skip_content = true;
@@ -1114,6 +1177,8 @@ static void parse_html_incremental(const char *html, int safe_len) {
int current_form_id = inc_form_id;
bool skip_content = inc_skip_content;
bool is_pre = inc_is_pre;
bool is_plaintext = false; // We don't persist plaintext across incremental chunks easily
int table_col = 0;
bool inside_title = inc_inside_title;
char page_title[256]; { int k=0; while(current_page_title[k]) { page_title[k] = current_page_title[k]; k++; } page_title[k] = 0; }
@@ -1121,7 +1186,7 @@ static void parse_html_incremental(const char *html, int safe_len) {
#define EFF_CENTER ((center_depth > 0) && (table_depth == 0))
while (i < safe_len && html[i] && element_count < MAX_ELEMENTS) {
if (html[i] == '<') {
if (html[i] == '<' && !is_plaintext) {
if (i + 3 < safe_len && html[i+1] == '!' && html[i+2] == '-' && html[i+3] == '-') {
i += 4;
while (i < safe_len && html[i] && !(i + 2 < safe_len && html[i] == '-' && html[i+1] == '-' && html[i+2] == '>')) i++;
@@ -1142,7 +1207,23 @@ static void parse_html_incremental(const char *html, int safe_len) {
if (tag_name[0] == '/') {
if (str_iequals(tag_name+1, "center")) { emit_br(); if (center_depth > 0) center_depth--; }
else if (str_iequals(tag_name+1, "table")) { emit_br(); if (table_depth > 0) table_depth--; }
else if (str_iequals(tag_name+1, "table")) { emit_br(); if (table_depth > 0) table_depth--; table_col = 0; }
else if (str_iequals(tag_name+1, "tr")) { emit_br(); table_col = 0; }
else if (str_iequals(tag_name+1, "td") || str_iequals(tag_name+1, "th")) {
table_col++;
if (table_col == 1) {
RenderElement *el = &elements[element_count++];
memset(el, 0, sizeof(RenderElement));
el->tag = TAG_NONE; el->content[0] = ' '; el->content[1] = 0;
int current_x = cur_line_x;
for (int k=0; k<line_element_count; k++) current_x += elements[line_elements[k]].w;
int target_x = 160 + (blockquote_depth * 20) + (list_depth * 20);
if (current_x < target_x) el->w = target_x - current_x; else el->w = 10;
el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
}
if (str_iequals(tag_name+1, "th")) is_bold = false;
}
else if (str_iequals(tag_name+1, "caption")) { emit_br(); is_bold = false; if (center_depth > 0) center_depth--; }
else if (str_iequals(tag_name+1, "blockquote")) { emit_br(); if (blockquote_depth > 0) blockquote_depth--; }
else if (str_iequals(tag_name+1, "ul") || str_iequals(tag_name+1, "ol") || str_iequals(tag_name+1, "dl") || str_iequals(tag_name+1, "dir") || str_iequals(tag_name+1, "menu")) { emit_br(); if (list_depth > 0) list_depth--; }
else if (str_iequals(tag_name+1, "dt")) { emit_br(); is_bold = false; }
@@ -1155,7 +1236,7 @@ static void parse_html_incremental(const char *html, int safe_len) {
else if (str_iequals(tag_name+1, "form")) { emit_br(); current_form_id = 0; current_form_action[0] = 0; }
else if (str_iequals(tag_name+1, "a")) current_link[0] = 0;
else if (str_iequals(tag_name+1, "p") || str_iequals(tag_name+1, "li") || str_iequals(tag_name+1, "div")) emit_br();
else if (str_iequals(tag_name+1, "pre")) { emit_br(); is_pre = false; }
else if (str_iequals(tag_name+1, "pre") || str_iequals(tag_name+1, "xmp") || str_iequals(tag_name+1, "listing")) { emit_br(); is_pre = false; }
else if (str_iequals(tag_name+1, "font") || str_iequals(tag_name+1, "tt") || str_iequals(tag_name+1, "code") || str_iequals(tag_name+1, "samp") || str_iequals(tag_name+1, "kbd")) {
if (inc_font_ptr > 0) {
inc_font_ptr--;
@@ -1174,7 +1255,19 @@ static void parse_html_incremental(const char *html, int safe_len) {
}
} else {
if (str_iequals(tag_name, "center")) { emit_br(); center_depth++; }
else if (str_iequals(tag_name, "table")) { emit_br(); table_depth++; }
else if (str_iequals(tag_name, "table")) { emit_br(); table_depth++; table_col = 0; }
else if (str_iequals(tag_name, "tr")) { emit_br(); table_col = 0; }
else if (str_iequals(tag_name, "td") || str_iequals(tag_name, "th")) {
if (table_col > 0) {
RenderElement *el = &elements[element_count++];
memset(el, 0, sizeof(RenderElement));
el->tag = TAG_NONE; el->content[0] = ' '; el->content[1] = 0; el->w = 10;
el->h = ui_get_font_height_scaled(current_scale);
el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
}
if (str_iequals(tag_name, "th")) is_bold = true;
}
else if (str_iequals(tag_name, "caption")) { emit_br(); center_depth++; is_bold = true; }
else if (str_iequals(tag_name, "blockquote")) { emit_br(); blockquote_depth++; }
else if (str_iequals(tag_name, "ul") || str_iequals(tag_name, "dir") || str_iequals(tag_name, "menu")) { emit_br(); list_type[list_depth] = 0; list_depth++; }
else if (str_iequals(tag_name, "ol")) { emit_br(); list_type[list_depth] = 1; list_index[list_depth] = 1; list_depth++; }
@@ -1186,17 +1279,19 @@ static void parse_html_incremental(const char *html, int safe_len) {
el->w = ui_get_string_width_scaled(el->content, current_scale); el->h = ui_get_font_height_scaled(current_scale); el->color = current_color; el->centered = EFF_CENTER; el->bold = is_bold; el->italic = is_italic; el->underline = is_underline; el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
}
else if (str_iequals(tag_name, "b") || str_iequals(tag_name, "strong")) is_bold = true;
else if (str_iequals(tag_name, "i") || str_iequals(tag_name, "em") || str_iequals(tag_name, "cite") || str_iequals(tag_name, "var")) is_italic = true;
else if (str_iequals(tag_name, "u")) is_underline = true;
else if (str_iequals(tag_name, "i") || str_iequals(tag_name, "em") || str_iequals(tag_name, "cite") || str_iequals(tag_name, "var") || str_iequals(tag_name, "dfn")) is_italic = true;
else if (str_iequals(tag_name, "u") || str_iequals(tag_name, "s") || str_iequals(tag_name, "strike")) is_underline = true;
else if (str_iequals(tag_name, "address")) emit_br();
else if (str_iequals(tag_name, "tt") || str_iequals(tag_name, "code") || str_iequals(tag_name, "samp") || str_iequals(tag_name, "kbd")) {
else if (str_iequals(tag_name, "tt") || str_iequals(tag_name, "code") || str_iequals(tag_name, "samp") || str_iequals(tag_name, "kbd") || str_iequals(tag_name, "xmp") || str_iequals(tag_name, "listing")) {
if (inc_font_ptr < MAX_FONT_STACK) {
inc_font_stack[inc_font_ptr].color = current_color;
inc_font_stack[inc_font_ptr].scale = current_scale;
inc_font_ptr++;
}
current_scale = 14.0f;
if (str_iequals(tag_name, "xmp") || str_iequals(tag_name, "listing")) { emit_br(); is_pre = true; }
}
else if (str_iequals(tag_name, "plaintext")) { emit_br(); is_plaintext = true; is_pre = true; current_scale = 14.0f; }
else if (tag_name[0] == 'h' && tag_name[1] >= '1' && tag_name[1] <= '6') {
emit_br(); emit_br(); is_bold = true;
if (tag_name[1] == '1') base_scale = 32.0f; else if (tag_name[1] == '2') base_scale = 24.0f; else if (tag_name[1] == '3') base_scale = 20.0f; else base_scale = 18.0f;

View File

@@ -106,20 +106,38 @@ static void draw_graph(int x, int y, int w, int h, int *data, uint32_t color, in
}
}
static void format_gib(uint64_t bytes, char *out) {
uint64_t gib_int = bytes / (1024 * 1024 * 1024);
uint64_t gib_frac = ((bytes % (1024 * 1024 * 1024)) * 100) / (1024 * 1024 * 1024);
char s_int[16], s_frac[16];
itoa((int)gib_int, s_int);
itoa((int)gib_frac, s_frac);
out[0] = 0;
strcat(out, s_int);
strcat(out, ".");
if (gib_frac < 10) strcat(out, "0");
strcat(out, s_frac);
strcat(out, " GiB");
static void format_mem_smart(uint64_t bytes, char *out) {
if (bytes < 1024) {
itoa((int)bytes, out);
strcat(out, " B");
} else if (bytes < 1024 * 1024) {
itoa((int)(bytes / 1024), out);
strcat(out, " KB");
} else if (bytes < 1024 * 1024 * 1024) {
// Show MiB with two decimal places
uint64_t mib_int = bytes / (1024 * 1024);
uint64_t mib_frac = ((bytes % (1024 * 1024)) * 100) / (1024 * 1024);
char s_int[16], s_frac[16];
itoa((int)mib_int, s_int);
itoa((int)mib_frac, s_frac);
strcpy(out, s_int);
strcat(out, ".");
if (mib_frac < 10) strcat(out, "0");
strcat(out, s_frac);
strcat(out, " MiB");
} else {
// Show GiB with two decimal places
uint64_t gib_int = bytes / (1024 * 1024 * 1024);
uint64_t gib_frac = ((bytes % (1024 * 1024 * 1024)) * 100) / (1024 * 1024 * 1024);
char s_int[16], s_frac[16];
itoa((int)gib_int, s_int);
itoa((int)gib_frac, s_frac);
strcpy(out, s_int);
strcat(out, ".");
if (gib_frac < 10) strcat(out, "0");
strcat(out, s_frac);
strcat(out, " GiB");
}
}
static void draw_taskman(void) {
@@ -161,9 +179,9 @@ static void draw_taskman(void) {
draw_graph(205, 25, 185, 60, mem_history, COLOR_MEM, max_mem_kb);
// Memory GiB usage
char s_used[24], s_total[24], mem_text[64];
format_gib(used_mem_system, s_used);
format_gib(total_mem_system, s_total);
char s_used[32], s_total[32], mem_text[64];
format_mem_smart(used_mem_system, s_used);
format_mem_smart(total_mem_system, s_total);
mem_text[0] = 0;
strcat(mem_text, s_used);
strcat(mem_text, " / ");
@@ -200,8 +218,7 @@ static void draw_taskman(void) {
ui_draw_string(win_taskman, 65, ry + 6, name_disp, COLOR_DARK_TEXT);
char m_str[32];
itoa((int)(proc_list[i].used_memory / 1024), m_str);
strcat(m_str, " KB");
format_mem_smart(proc_list[i].used_memory, m_str);
ui_draw_string(win_taskman, 255, ry + 6, m_str, COLOR_DARK_TEXT);
row++;