this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add vm.{page_purgeable_count,page_pageable_internal_count} sysctls

(for neofetch)

+163
+1
src/kernel/emulation/linux/CMakeLists.txt
··· 166 166 misc/sysctl_machdep.c 167 167 misc/sysctl_sysctl.c 168 168 misc/sysctl_net.c 169 + misc/sysctl_vm.c 169 170 misc/getrlimit.c 170 171 misc/setrlimit.c 171 172 misc/gethostuuid.c
+2
src/kernel/emulation/linux/misc/sysctl.c
··· 12 12 #include "sysctl_machdep.h" 13 13 #include "sysctl_sysctl.h" 14 14 #include "sysctl_net.h" 15 + #include "sysctl_vm.h" 15 16 16 17 extern char *strchr(const char *s, int c); 17 18 extern int strncmp(const char *s1, const char *s2, __SIZE_TYPE__ n); ··· 29 30 { .oid = CTL_MACHDEP, .type = CTLTYPE_NODE, .exttype = "", .name = "machdep", .subctls = sysctls_machdep }, 30 31 { .oid = _CTL_SYSCTL, .type = CTLTYPE_NODE, .exttype = "", .name = "sysctl", .subctls = sysctls_sysctl }, 31 32 { .oid = CTL_NET, .type = CTLTYPE_NODE, .exttype = "", .name = "net", .subctls = sysctls_net }, 33 + { .oid = CTL_VM, .type = CTLTYPE_NODE, .exttype = "", .name = "vm", .subctls = sysctls_vm }, 32 34 { .oid = -1 }, /* terminating entry */ 33 35 }; 34 36
+142
src/kernel/emulation/linux/misc/sysctl_vm.c
··· 1 + #include "sysctl_vm.h" 2 + #include "../readline.h" 3 + #include "../elfcalls_wrapper.h" 4 + #include "../unistd/close.h" 5 + #include "../fcntl/open.h" 6 + #include <errno.h> 7 + #include "../string.h" 8 + #include "../simple.h" 9 + 10 + #define LINUX_SC_PAGESIZE 30 11 + 12 + enum { 13 + // the OID for this sysctl is OID_AUTO, so we can assign anything to it 14 + _VM_PAGE_PURGEABLE_COUNT = 1000, 15 + _VM_PAGE_PAGEABLE_INTERNAL_COUNT, 16 + }; 17 + 18 + static sysctl_handler(handle_page_purgeable_count); 19 + static sysctl_handler(handle_page_pageable_internal_count); 20 + 21 + const struct known_sysctl sysctls_vm[] = { 22 + { .oid = _VM_PAGE_PURGEABLE_COUNT, .type = CTLTYPE_INT, .exttype = "I", .name = "page_purgeable_count", .handler = handle_page_purgeable_count }, 23 + { .oid = _VM_PAGE_PAGEABLE_INTERNAL_COUNT, .type = CTLTYPE_INT, .exttype = "IU", .name = "page_pageable_internal_count", .handler = handle_page_pageable_internal_count }, 24 + { .oid = -1 }, 25 + }; 26 + 27 + struct meminfo { 28 + // all of these fields are in KiB 29 + uint64_t total; 30 + uint64_t free; 31 + uint64_t available; 32 + uint64_t buffers; 33 + uint64_t cached; 34 + uint64_t slab_reclaimable; 35 + uint64_t shmem; 36 + }; 37 + 38 + static const char* find_first_not(const char* haystack, char needle) { 39 + // skip any characters matching `needle` 40 + for (; *haystack == needle; ++haystack); 41 + if (*haystack == '\0') { 42 + // if we reached the end of the string, we didn't find any characters other than `needle`; 43 + // return `NULL` to indicate this 44 + return NULL; 45 + } else { 46 + // otherwise, `haystack` points to a non-`needle` character 47 + return haystack; 48 + } 49 + }; 50 + 51 + static bool parse_meminfo_line(const char* line, const char* key, size_t key_length, uint64_t* value) { 52 + if (strncmp(line, key, key_length) == 0) { 53 + const char* value_string = find_first_not(line + key_length, ' '); 54 + if (value_string) { 55 + *value = __simple_atoi(value_string, NULL); 56 + return true; 57 + } 58 + } 59 + return false; 60 + }; 61 + 62 + static int read_meminfo(struct meminfo* out_info) { 63 + int infofd = sys_open_nocancel("/proc/meminfo", BSD_O_RDONLY, 0); 64 + struct rdline_buffer rbuf; 65 + const char* line; 66 + int status = 0; 67 + 68 + if (infofd < 0) { 69 + status = infofd; 70 + goto out; 71 + } 72 + 73 + memset(out_info, 0, sizeof(*out_info)); 74 + 75 + _readline_init(&rbuf); 76 + 77 + while ((line = _readline(infofd, &rbuf)) != NULL) { 78 + uint64_t value; 79 + 80 + #define PARSE(_key, _member) \ 81 + if (parse_meminfo_line(line, _key, sizeof(_key) - 1, &value)) { \ 82 + out_info->_member = value; \ 83 + } 84 + 85 + PARSE("MemTotal:", total) 86 + else PARSE("MemFree:", free) 87 + else PARSE("MemAvailable:", available) 88 + else PARSE("Buffers:", buffers) 89 + else PARSE("Cached:", cached) 90 + else PARSE("SReclaimable:", slab_reclaimable) 91 + else PARSE("Shmem:", shmem) 92 + ; 93 + 94 + #undef PARSE 95 + } 96 + 97 + out: 98 + if (infofd >= 0) { 99 + close_internal(infofd); 100 + } 101 + return status; 102 + }; 103 + 104 + static sysctl_handler(handle_page_purgeable_count) { 105 + if (old && oldlen && *oldlen >= sizeof(uint32_t)) { 106 + // pretend we have nothing purgeable 107 + *(uint32_t*)old = 0; 108 + } 109 + if (oldlen) { 110 + *oldlen = sizeof(uint32_t); 111 + } 112 + return 0; 113 + }; 114 + 115 + static sysctl_handler(handle_page_pageable_internal_count) { 116 + struct meminfo meminfo; 117 + uint32_t result = 0; 118 + 119 + if (read_meminfo(&meminfo) == 0) { 120 + uint64_t actual_used_kib; 121 + 122 + if (meminfo.available > 0) { 123 + actual_used_kib = meminfo.total - meminfo.available; 124 + } else { 125 + // see https://stackoverflow.com/a/41251290/6620880 126 + uint64_t used_kib = meminfo.total - meminfo.free; 127 + uint64_t cached_kib = meminfo.cached + meminfo.slab_reclaimable - meminfo.shmem; 128 + actual_used_kib = used_kib - (meminfo.buffers + cached_kib); 129 + } 130 + 131 + result = (actual_used_kib * 1024) / native_sysconf(LINUX_SC_PAGESIZE); 132 + } 133 + 134 + if (old && oldlen && *oldlen >= sizeof(uint32_t)) { 135 + *(uint32_t*)old = result; 136 + } 137 + if (oldlen) { 138 + *oldlen = sizeof(uint32_t); 139 + } 140 + 141 + return 0; 142 + };
+8
src/kernel/emulation/linux/misc/sysctl_vm.h
··· 1 + #ifndef _DARLING_EMULATION_LINUX_MISC_SYSCTL_VM_H_ 2 + #define _DARLING_EMULATION_LINUX_MISC_SYSCTL_VM_H_ 3 + 4 + #include "sysctl.h" 5 + 6 + extern const struct known_sysctl sysctls_vm[]; 7 + 8 + #endif // _DARLING_EMULATION_LINUX_MISC_SYSCTL_VM_H_
+10
src/kernel/emulation/linux/string.h
··· 1 + #ifndef _DARLING_EMULATION_LINUX_STRING_H_ 2 + #define _DARLING_EMULATION_LINUX_STRING_H_ 3 + 4 + #include <stddef.h> 5 + 6 + extern void* memset(void* s, int c, size_t n); 7 + extern char* strncpy(char* dest, const char* src, size_t n); 8 + extern int strncmp(const char* str1, const char* str2, size_t n); 9 + 10 + #endif // _DARLING_EMULATION_LINUX_STRING_H_