diff --git a/code/linux_platform.cpp b/code/linux_platform.cpp index 48fe698..fb8eb93 100644 --- a/code/linux_platform.cpp +++ b/code/linux_platform.cpp @@ -221,9 +221,12 @@ void p_free(void *ptr) bool p_file_init(p_file *file, const char *filename, b32 flags) { bool create_flag_set = flags & P_FILE_CREATE_IF_NOT_EXISTS; + bool readonly = flags & P_FILE_READONLY; - - file->handle = fopen(filename, "rb+"); + const char *mode = "rb+"; + if(readonly) + mode = "rb"; + file->handle = fopen(filename, mode); if(create_flag_set && file->handle == NULL) // @Robustness: check errno { file->handle = fopen(filename, "wb+"); diff --git a/code/main.cpp b/code/main.cpp index e71d5d7..d18ff09 100644 --- a/code/main.cpp +++ b/code/main.cpp @@ -683,6 +683,64 @@ void collect_static_data() snprintf(system_info.kernel, 128, "%s %s", host_info.sysname, host_info.release); } +// key and value are views into buffer. Copy them if you need them for a longer lifetime +size_t meminfo_extract_next_entry(String *buffer, size_t start, String *key, String *value) +{ + size_t separator = 0; + size_t end = 0; + for(int i = start; i < buffer->size; i++) + { + if(buffer->text[i] == ':') + { + separator = i; + } + else if(buffer->text[i] == '\n') + { + end = i; + break; + } + } + + if(end == 0) // no newline found + end = buffer->size; + + if(key) + { + key->text = buffer->text + start; + key->size = separator - start; + } + if(value) + { + // TODO: Check if seaparator is actually found. This will return the wrong data if separator is 0 + value->text = buffer->text + separator + 1; + value->size = end - (separator + 1); + } + + return end + 1 - start; +} + +String String_trim(String s) +{ + String result; + + result.text = s.text; + result.size = s.size; + + // Trim front + while(result.size > 0 && result.text[0] == ' ') + { + result.text++; + result.size--; + } + // Trim back + while(result.size > 0 && result.text[result.size-1] == ' ') + { + result.size--; + } + + return result; +} + void collect_new_data_if_needed() { if(engine.time - app_data.glib_iteration_t >= app_data.glib_iteration_delta) @@ -715,9 +773,56 @@ void collect_new_data_if_needed() system_info.load[i] = round((f32)sys_info.loads[i] / (1 << SI_LOAD_SHIFT) * 100) / 100; // Memory - system_info.ram_total = sys_info.totalram * sys_info.mem_unit; - system_info.ram_available = (sys_info.freeram + sys_info.bufferram) * sys_info.mem_unit; - system_info.ram_used = sys_info.totalram * sys_info.mem_unit - system_info.ram_available; + { + p_file file; + if(p_file_init(&file, "/proc/meminfo", P_FILE_READONLY)) + { + u64 size = p_file_size(&file); + if(size == 0) + size = 1024; + u8 backing_buff[size + 1]; + Buffer buffer = { .size = size + 1, .data = backing_buff }; + if(p_file_read(&file, &buffer, size + 1)) + { + String s = { .size = buffer.size, .text = buffer.data }; + // Parse meminfo data + size_t parsed = 0; + while(1) + { + String key, value; + size_t read = meminfo_extract_next_entry(&s, parsed, &key, &value); + parsed += read; + if(read == 0) + break; + + key = String_trim(key); + value = String_trim(value); + + if(strncmp((const char *)key.text, "MemTotal", key.size) == 0) + { + // LOG(LOG_INFO, "MemTotal: %.*s\n", value.size, value.text); + u64 converted = 0; + sscanf((const char *)value.text, "%lu", &converted); + system_info.ram_total = converted * 1024; + } + else if(strncmp((const char *)key.text, "MemAvailable", key.size) == 0) + { + // LOG(LOG_INFO, "MemAvailable: %.*s\n", value.size, value.text); + u64 converted = 0; + sscanf((const char *)value.text, "%lu", &converted); + system_info.ram_available = converted * 1024; + } + } + } + + p_file_deinit(&file); + } + } + + // system_info.ram_total = sys_info.totalram * sys_info.mem_unit; + // system_info.ram_available = (sys_info.freeram + sys_info.bufferram) * sys_info.mem_unit; + // system_info.ram_used = sys_info.totalram * sys_info.mem_unit - system_info.ram_available; + system_info.ram_used = system_info.ram_total - system_info.ram_available; // Status diff --git a/code/platform.h b/code/platform.h index 4f2c106..eac5b79 100644 --- a/code/platform.h +++ b/code/platform.h @@ -23,6 +23,7 @@ void p_free(void *ptr); // File IO #define P_FILE_CREATE_IF_NOT_EXISTS 1 +#define P_FILE_READONLY 2 struct p_file; // Defined by specific platform implementation