mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Added memstat, a program for displaying memory usage.
This commit is contained in:
parent
f45def4a68
commit
9152443816
7 changed files with 111 additions and 2 deletions
|
@ -170,7 +170,9 @@ int usleep(useconds_t useconds);
|
|||
#endif
|
||||
int unlink(const char*);
|
||||
ssize_t write(int, const void*, size_t);
|
||||
|
||||
#ifdef SORTIX_EXTENSIONS
|
||||
int memstat(size_t* memused, size_t* memtotal);
|
||||
int writeall(int fd, const void* buffer, size_t len);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -34,6 +34,11 @@
|
|||
|
||||
#include <sortix/memorymanagement.h>
|
||||
#include <sortix/panic.h>
|
||||
|
||||
#else // !SORTIX_KERNEL
|
||||
|
||||
#include "syscall.h"
|
||||
|
||||
#endif
|
||||
|
||||
#define IsGoodChunkPosition(Chunk) ((uintptr_t) Wilderness + WildernessSize <= (uintptr_t) (Chunk) && (uintptr_t) (Chunk) <= (uintptr_t) HeapStart)
|
||||
|
@ -72,6 +77,15 @@ namespace Maxsi
|
|||
|
||||
namespace Memory
|
||||
{
|
||||
#ifndef SORTIX_KERNEL
|
||||
DEFN_SYSCALL2(int, SysMemStat, 32, size_t*, size_t*);
|
||||
|
||||
extern "C" int memstat(size_t* memused, size_t* memtotal)
|
||||
{
|
||||
return SysMemStat(memused, memtotal);
|
||||
}
|
||||
#endif
|
||||
|
||||
// This magic word is useful to see if the program has written into the
|
||||
// chunk's header or footer, which means the program has malfunctioned
|
||||
// and ought to be terminated.
|
||||
|
|
|
@ -57,6 +57,7 @@ namespace Sortix
|
|||
bool MapUser(addr_t physical, addr_t mapto);
|
||||
addr_t UnmapKernel(addr_t mapto);
|
||||
addr_t UnmapUser(addr_t mapto);
|
||||
void Statistics(size_t* amountused, size_t* totalmem);
|
||||
|
||||
#if defined(PLATFORM_X86)
|
||||
const addr_t HEAPLOWER = 0x80000000UL;
|
||||
|
|
|
@ -57,7 +57,8 @@
|
|||
#define SYSCALL_REGISTER_SIGNAL_HANDLER 29
|
||||
#define SYSCALL_SIGRETURN 30
|
||||
#define SYSCALL_KILL 31
|
||||
#define SYSCALL_MAX_NUM 32 /* index of highest constant + 1 */
|
||||
#define SYSCALL_MEMSTAT 32
|
||||
#define SYSCALL_MAX_NUM 33 /* index of highest constant + 1 */
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -28,10 +28,11 @@
|
|||
#include "panic.h"
|
||||
#include "../memorymanagement.h"
|
||||
#include "memorymanagement.h"
|
||||
#include "syscall.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
const addr_t KERNELEND = 0x200000UL;
|
||||
const addr_t KERNELEND = 0x400000UL;
|
||||
|
||||
namespace Page
|
||||
{
|
||||
|
@ -39,6 +40,8 @@ namespace Sortix
|
|||
size_t pagesnotonstack;
|
||||
size_t stackused;
|
||||
size_t stacklength;
|
||||
size_t totalmem;
|
||||
size_t pagesallocated;
|
||||
}
|
||||
|
||||
namespace Memory
|
||||
|
@ -47,10 +50,15 @@ namespace Sortix
|
|||
|
||||
void InitCPU();
|
||||
void AllocateKernelPMLs();
|
||||
int SysMemStat(size_t* memused, size_t* memtotal);
|
||||
|
||||
void Init(multiboot_info_t* bootinfo)
|
||||
{
|
||||
Page::pagesnotonstack = 0;
|
||||
Page::totalmem = 0;
|
||||
|
||||
// The first mebibytes are reserved for use by the kernel.
|
||||
Page::pagesallocated = KERNELEND >> 12UL;
|
||||
|
||||
if ( !( bootinfo->flags & MULTIBOOT_INFO_MEM_MAP ) )
|
||||
{
|
||||
|
@ -84,6 +92,9 @@ namespace Sortix
|
|||
if ( 0xFFFFFFFFULL < mmap->addr + mmap->len ) { length = 0x100000000ULL - mmap->addr; }
|
||||
#endif
|
||||
|
||||
// Count the amount of usable RAM (even if reserved for kernel).
|
||||
Page::totalmem += length;
|
||||
|
||||
// Detect if this memory is completely covered by the kernel.
|
||||
if ( base + length <= KERNELEND ) { continue; }
|
||||
|
||||
|
@ -95,6 +106,8 @@ namespace Sortix
|
|||
}
|
||||
|
||||
Page::InitPushRegion(base, length);
|
||||
|
||||
Syscall::Register(SYSCALL_MEMSTAT, (void*) SysMemStat);
|
||||
}
|
||||
|
||||
// If the physical allocator couldn't handle the vast amount of
|
||||
|
@ -110,6 +123,23 @@ namespace Sortix
|
|||
AllocateKernelPMLs();
|
||||
}
|
||||
|
||||
void Statistics(size_t* amountused, size_t* totalmem)
|
||||
{
|
||||
if ( amountused ) { *amountused = Page::pagesallocated << 12Ul; }
|
||||
if ( totalmem ) { *totalmem = Page::totalmem; }
|
||||
}
|
||||
|
||||
int SysMemStat(size_t* memused, size_t* memtotal)
|
||||
{
|
||||
size_t used;
|
||||
size_t total;
|
||||
Statistics(&used, &total);
|
||||
// TODO: Check if legal user-space buffers!
|
||||
*memused = used;
|
||||
*memtotal = total;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Prepare the non-forkable kernel PMLs such that forking the kernel
|
||||
// address space will always keep the kernel mapped.
|
||||
void AllocateKernelPMLs()
|
||||
|
@ -188,12 +218,15 @@ namespace Sortix
|
|||
// TODO: Set out of memory errno here!
|
||||
if ( unlikely(stackused == 0) ) { return 0; }
|
||||
|
||||
pagesallocated++;
|
||||
|
||||
return STACK[--stackused];
|
||||
}
|
||||
|
||||
void Put(addr_t page)
|
||||
{
|
||||
ASSERT(stackused < MAXSTACKLENGTH);
|
||||
pagesallocated--;
|
||||
STACK[stackused++] = page;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ mxsh \
|
|||
clear \
|
||||
ls \
|
||||
help \
|
||||
memstat \
|
||||
uname \
|
||||
idle \
|
||||
editor \
|
||||
|
|
57
utils/memstat.cpp
Normal file
57
utils/memstat.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
void printbytes(unsigned long long bytes)
|
||||
{
|
||||
const unsigned BYTES = 0;
|
||||
const unsigned KIBI = 1;
|
||||
const unsigned MEBI = 2;
|
||||
const unsigned GIBI = 3;
|
||||
const unsigned TEBI = 4;
|
||||
const unsigned PEBI = 5;
|
||||
const unsigned EXBI = 6;
|
||||
|
||||
unsigned unit = BYTES;
|
||||
if ( (bytes >> 10) & 1023 ) { unit = KIBI; }
|
||||
if ( (bytes >> 20) & 1023 ) { unit = MEBI; }
|
||||
if ( (bytes >> 30) & 1023 ) { unit = GIBI; }
|
||||
if ( (bytes >> 40) & 1023 ) { unit = TEBI; }
|
||||
if ( (bytes >> 50) & 1023 ) { unit = PEBI; }
|
||||
if ( (bytes >> 60) & 1023 ) { unit = EXBI; }
|
||||
|
||||
switch ( unit )
|
||||
{
|
||||
case EXBI:
|
||||
printf("%u ZiB ", (bytes >> 60) & 1023);
|
||||
case PEBI:
|
||||
printf("%u PiB ", (bytes >> 50) & 1023);
|
||||
case TEBI:
|
||||
printf("%u TiB ", (bytes >> 40) & 1023);
|
||||
case GIBI:
|
||||
printf("%u GiB ", (bytes >> 30) & 1023);
|
||||
case MEBI:
|
||||
printf("%u MiB ", (bytes >> 20) & 1023);
|
||||
case KIBI:
|
||||
printf("%u KiB", (bytes >> 10) & 1023);
|
||||
break;
|
||||
case BYTES:
|
||||
printf("%u B", (bytes >> 0) & 1023);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
size_t memused = 0;
|
||||
size_t memtotal = 0;
|
||||
if ( memstat(&memused, &memtotal) ) { perror("memstat"); return 1; }
|
||||
|
||||
printf("memory usage: ");
|
||||
printbytes(memused);
|
||||
printf(" free / ");
|
||||
printbytes(memtotal);
|
||||
unsigned percent = ((unsigned long long) memused * 100ULL ) / memtotal;
|
||||
printf(" total (%u%s)\n", percent, "%");
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue