diff --git a/kernel/addralloc.cpp b/kernel/addralloc.cpp index 1100f306..027f70d6 100644 --- a/kernel/addralloc.cpp +++ b/kernel/addralloc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014 Jonas 'Sortie' Termansen. + * Copyright (c) 2013, 2014, 2022 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,6 +29,7 @@ namespace Sortix { size_t aux_allocated = 0; +size_t aux_leaked = 0; size_t heap_allocated = 0; kthread_mutex_t alloc_lock = KTHREAD_MUTEX_INITIALIZER; @@ -69,6 +70,8 @@ void FreeKernelAddress(addralloc_t* alloc) addr_t aux_reached = kmem_from + kmem_size - aux_allocated; if ( alloc->from == aux_reached ) aux_allocated -= alloc->size; + else + aux_leaked += alloc->size; alloc->from = 0; alloc->size = 0; @@ -98,6 +101,17 @@ void ShrinkHeap(size_t decrease) heap_allocated -= decrease; } +void KernelAddressStatistics(size_t* heap, size_t* aux, size_t* leaked, + size_t* total) +{ + ScopedLock lock(&alloc_lock); + addr_t kmem_from; + Memory::GetKernelVirtualArea(&kmem_from, total); + *heap = heap_allocated; + *aux = aux_allocated - aux_leaked; + *leaked = aux_leaked; +} + // No need for locks in these three functions, since only the heap calls these // and it already uses an internal lock, and heap_allocated will not change // unless the heap calls ExpandHeap. diff --git a/kernel/include/sortix/kernel/addralloc.h b/kernel/include/sortix/kernel/addralloc.h index 573d70af..5608c238 100644 --- a/kernel/include/sortix/kernel/addralloc.h +++ b/kernel/include/sortix/kernel/addralloc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. + * Copyright (c) 2013, 2022 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -39,6 +39,7 @@ void ShrinkHeap(size_t decrease); addr_t GetHeapLower(); addr_t GetHeapUpper(); size_t GetHeapSize(); +void KernelAddressStatistics(size_t* heap, size_t* aux, size_t* leaked, size_t* total); } // namespace Sortix diff --git a/kernel/kernelinfo.cpp b/kernel/kernelinfo.cpp index 8f639dfc..857e67db 100644 --- a/kernel/kernelinfo.cpp +++ b/kernel/kernelinfo.cpp @@ -53,6 +53,26 @@ ssize_t sys_kernelinfo(const char* user_req, char* user_resp, size_t resplen) if ( !req ) return -1; // DEBUG + if ( !strcmp(req, "virtual-usage") ) + { + delete[] req; + size_t heap; + size_t aux; + size_t leaked; + size_t total; + KernelAddressStatistics(&heap, &aux, &leaked, &total); + char str[4 * (20 + 3 * sizeof(size_t) + 1 + 8)]; + snprintf(str, sizeof(str), + "%20zu B heap\n%20zu B aux\n%20zu B leaked\n%20zu B total", + heap, aux, leaked, total); + size_t stringlen = strlen(str); + if ( resplen < stringlen + 1 ) + return errno = ERANGE, (ssize_t) stringlen; + if ( !CopyToUser(user_resp, str, sizeof(char) * (stringlen + 1)) ) + return -1; + return 0; + } + // DEBUG if ( !strcmp(req, "tcp") ) { delete[] req;