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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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,21 +106,39 @@ 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) {
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);
out[0] = 0;
strcat(out, s_int);
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) {
int win_w = 400;
@ -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++;