Add memusage(2).
Switch xz to memusage(2) and fix native self-cross issue. This is a compatible ABI change.
This commit is contained in:
parent
7963da689d
commit
2cd7361294
2
Makefile
2
Makefile
|
@ -225,7 +225,7 @@ sysroot-system: sysroot-fsh sysroot-base-headers
|
|||
echo 'ID=sortix' && \
|
||||
echo 'VERSION_ID="$(VERSION)"' && \
|
||||
echo 'PRETTY_NAME="Sortix $(VERSION)"' && \
|
||||
echo 'SORTIX_ABI=1.3' && \
|
||||
echo 'SORTIX_ABI=1.4' && \
|
||||
true) > "$(SYSROOT)/etc/sortix-release"
|
||||
echo /etc/sortix-release >> "$(SYSROOT)/tix/manifest/system"
|
||||
ln -sf sortix-release "$(SYSROOT)/etc/os-release"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2012, 2013, 2014, 2015, 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
|
||||
|
@ -90,7 +90,7 @@ int common_statvfs(ioctx_t* ctx, struct statvfs* stvfs, dev_t dev)
|
|||
{
|
||||
size_t memory_used;
|
||||
size_t memory_total;
|
||||
Memory::Statistics(&memory_used, &memory_total);
|
||||
Memory::Statistics(&memory_used, &memory_total, NULL);
|
||||
struct statvfs retstvfs;
|
||||
memset(&retstvfs, 0, sizeof(retstvfs));
|
||||
retstvfs.f_bsize = Page::Size();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2012, 2014, 2015, 2017 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011, 2012, 2014, 2015, 2017, 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
|
||||
|
@ -33,13 +33,12 @@ class Process;
|
|||
|
||||
enum page_usage
|
||||
{
|
||||
PAGE_USAGE_OTHER,
|
||||
PAGE_USAGE_PHYSICAL,
|
||||
PAGE_USAGE_PAGING_OVERHEAD,
|
||||
PAGE_USAGE_KERNEL_HEAP,
|
||||
PAGE_USAGE_FILESYSTEM_CACHE,
|
||||
PAGE_USAGE_USER_SPACE,
|
||||
PAGE_USAGE_EXECUTE,
|
||||
PAGE_USAGE_EXECVE,
|
||||
PAGE_USAGE_DRIVER,
|
||||
PAGE_USAGE_NETWORK_PACKET,
|
||||
PAGE_USAGE_NUM_KINDS,
|
||||
|
@ -110,7 +109,7 @@ void PageProtectAdd(addr_t mapto, int protection);
|
|||
void PageProtectSub(addr_t mapto, int protection);
|
||||
bool MapRange(addr_t where, size_t bytes, int protection, enum page_usage usage);
|
||||
bool UnmapRange(addr_t where, size_t bytes, enum page_usage usage);
|
||||
void Statistics(size_t* amountused, size_t* totalmem);
|
||||
void Statistics(size_t* used, size_t* total, size_t* purposes);
|
||||
addr_t GetKernelStack();
|
||||
size_t GetKernelStackSize();
|
||||
void GetKernelVirtualArea(addr_t* from, size_t* size);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2016, 2021 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011-2016, 2021, 2022, 2023 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
|
||||
|
@ -117,6 +117,7 @@ int sys_linkat(int, const char*, int, const char*, int);
|
|||
int sys_listen(int, int);
|
||||
off_t sys_lseek(int, off_t, int);
|
||||
int sys_memstat(size_t*, size_t*);
|
||||
int sys_memusage(const size_t*, size_t*, size_t);
|
||||
int sys_mkdirat(int, const char*, mode_t);
|
||||
int sys_mkpartition(int, off_t, off_t, int);
|
||||
int sys_mkpty(int*, int*, int);
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 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
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* sortix/memusage.h
|
||||
* Memory usage statistics.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SORTIX_MEMUSAGE_H
|
||||
#define _INCLUDE_SORTIX_MEMUSAGE_H
|
||||
|
||||
#define MEMUSAGE_TOTAL 0
|
||||
#define MEMUSAGE_USED 1
|
||||
|
||||
#define MEMUSAGE_PURPOSE_FIRST 16
|
||||
#define MEMUSAGE_PURPOSE_PHYSICAL (MEMUSAGE_PURPOSE_FIRST + 0)
|
||||
#define MEMUSAGE_PURPOSE_PAGING (MEMUSAGE_PURPOSE_FIRST + 1)
|
||||
#define MEMUSAGE_PURPOSE_KERNEL (MEMUSAGE_PURPOSE_FIRST + 2)
|
||||
#define MEMUSAGE_PURPOSE_FILESYSTEM (MEMUSAGE_PURPOSE_FIRST + 3)
|
||||
#define MEMUSAGE_PURPOSE_USERSPACE (MEMUSAGE_PURPOSE_FIRST + 4)
|
||||
#define MEMUSAGE_PURPOSE_EXECVE (MEMUSAGE_PURPOSE_FIRST + 5)
|
||||
#define MEMUSAGE_PURPOSE_DRIVER (MEMUSAGE_PURPOSE_FIRST + 6)
|
||||
#define MEMUSAGE_PURPOSE_NETWORK (MEMUSAGE_PURPOSE_FIRST + 7)
|
||||
#define MEMUSAGE_PURPOSE_LAST MEMUSAGE_PURPOSE_NETWORK
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2016, 2021 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011-2016, 2021, 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
|
||||
|
@ -189,6 +189,7 @@
|
|||
#define SYSCALL_GETDNSCONFIG 166
|
||||
#define SYSCALL_SETDNSCONFIG 167
|
||||
#define SYSCALL_FUTEX 168
|
||||
#define SYSCALL_MAX_NUM 169 /* index of highest constant + 1 */
|
||||
#define SYSCALL_MEMUSAGE 169
|
||||
#define SYSCALL_MAX_NUM 170 /* index of highest constant + 1 */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2012, 2013, 2015 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011, 2012, 2013, 2015, 2022, 2023 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
|
||||
|
@ -25,6 +25,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sortix/memusage.h>
|
||||
#include <sortix/mman.h>
|
||||
#include <sortix/seek.h>
|
||||
|
||||
|
@ -39,11 +40,13 @@
|
|||
|
||||
namespace Sortix {
|
||||
|
||||
// TODO: After releasing Sortix 1.1, remove this deprecated system call retained
|
||||
// for backwards ABI compatibility with Sortix 1.0's xz port.
|
||||
int sys_memstat(size_t* memused, size_t* memtotal)
|
||||
{
|
||||
size_t used;
|
||||
size_t total;
|
||||
Memory::Statistics(&used, &total);
|
||||
Memory::Statistics(&used, &total, NULL);
|
||||
if ( memused && !CopyToUser(memused, &used, sizeof(used)) )
|
||||
return -1;
|
||||
if ( memtotal && !CopyToUser(memtotal, &total, sizeof(total)) )
|
||||
|
@ -51,6 +54,47 @@ int sys_memstat(size_t* memused, size_t* memtotal)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sys_memusage(const size_t* user_statistics,
|
||||
size_t* user_values,
|
||||
size_t length)
|
||||
{
|
||||
size_t used;
|
||||
size_t total;
|
||||
size_t purposes[PAGE_USAGE_NUM_KINDS];
|
||||
Memory::Statistics(&used, &total, purposes);
|
||||
for ( size_t start = 0; start < length; )
|
||||
{
|
||||
const size_t BLOCK = 32;
|
||||
size_t statistics[BLOCK];
|
||||
size_t amount = length - start;
|
||||
if ( BLOCK < amount )
|
||||
amount = BLOCK;
|
||||
if ( !CopyFromUser(statistics, user_statistics + start,
|
||||
amount * sizeof(size_t)) )
|
||||
return -1;
|
||||
for ( size_t i = 0; i < amount; i++ )
|
||||
{
|
||||
size_t statistic = statistics[i];
|
||||
size_t value;
|
||||
if ( statistic == MEMUSAGE_TOTAL )
|
||||
value = total;
|
||||
else if ( statistic == MEMUSAGE_USED )
|
||||
value = used;
|
||||
else if ( MEMUSAGE_PURPOSE_FIRST <= statistic &&
|
||||
statistic <= MEMUSAGE_PURPOSE_LAST )
|
||||
value = purposes[statistic - MEMUSAGE_PURPOSE_FIRST];
|
||||
else
|
||||
return errno = EINVAL, -1;
|
||||
statistics[i] = value;
|
||||
}
|
||||
if ( !CopyToUser(user_values + start, statistics,
|
||||
amount * sizeof(size_t)) )
|
||||
return -1;
|
||||
start += amount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Sortix
|
||||
|
||||
namespace Sortix {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Meisaka Yukara.
|
||||
* Copyright (c) 2016, 2017 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
|
@ -84,7 +84,7 @@ Ref<Packet> GetPacket()
|
|||
else
|
||||
{
|
||||
size_t total_memory;
|
||||
Memory::Statistics(NULL, &total_memory);
|
||||
Memory::Statistics(NULL, &total_memory, NULL);
|
||||
size_t total_pages = total_memory / Page::Size();
|
||||
size_t max_packets = total_pages / MAX_PACKET_FRACTION;
|
||||
if ( max_packets <= packet_count )
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2016, 2021 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011-2016, 2021-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
|
||||
|
@ -1165,7 +1165,7 @@ static bool sys_execve_alloc(addralloc_t* alloc, size_t size)
|
|||
{
|
||||
if ( !AllocateKernelAddress(alloc, size) )
|
||||
return false;
|
||||
if ( !Memory::MapRange(alloc->from, alloc->size, PROT_KREAD | PROT_KWRITE, PAGE_USAGE_EXECUTE) )
|
||||
if ( !Memory::MapRange(alloc->from, alloc->size, PROT_KREAD | PROT_KWRITE, PAGE_USAGE_EXECVE) )
|
||||
return FreeKernelAddress(alloc), false;
|
||||
Memory::Flush();
|
||||
return true;
|
||||
|
@ -1173,7 +1173,7 @@ static bool sys_execve_alloc(addralloc_t* alloc, size_t size)
|
|||
|
||||
static void sys_execve_free(addralloc_t* alloc)
|
||||
{
|
||||
Memory::UnmapRange(alloc->from, alloc->size, PAGE_USAGE_EXECUTE);
|
||||
Memory::UnmapRange(alloc->from, alloc->size, PAGE_USAGE_EXECVE);
|
||||
Memory::Flush();
|
||||
FreeKernelAddress(alloc);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2016, 2021 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011-2016, 2021-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
|
||||
|
@ -203,6 +203,7 @@ void* syscall_list[SYSCALL_MAX_NUM + 1] =
|
|||
[SYSCALL_GETDNSCONFIG] = (void*) sys_getdnsconfig,
|
||||
[SYSCALL_SETDNSCONFIG] = (void*) sys_setdnsconfig,
|
||||
[SYSCALL_FUTEX] = (void*) sys_futex,
|
||||
[SYSCALL_MEMUSAGE] = (void*) sys_memusage,
|
||||
[SYSCALL_MAX_NUM] = (void*) sys_bad_syscall,
|
||||
};
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2012, 2014, 2015, 2017 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011, 2012, 2014, 2015, 2017, 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
|
||||
|
@ -220,14 +220,20 @@ void Init(multiboot_info_t* bootinfo)
|
|||
}
|
||||
}
|
||||
|
||||
void Statistics(size_t* amountused, size_t* totalmem)
|
||||
void Statistics(size_t* used, size_t* total, size_t* purposes)
|
||||
{
|
||||
ScopedLock lock(&Page::pagelock);
|
||||
size_t memfree = (Page::stackused - Page::stackreserved) << 12UL;
|
||||
size_t memused = Page::totalmem - memfree;
|
||||
if ( amountused )
|
||||
*amountused = memused;
|
||||
if ( totalmem )
|
||||
*totalmem = Page::totalmem;
|
||||
if ( used )
|
||||
*used = memused;
|
||||
if ( total )
|
||||
*total = Page::totalmem;
|
||||
if ( purposes )
|
||||
{
|
||||
for ( size_t i = 0; i < PAGE_USAGE_NUM_KINDS; i++ )
|
||||
purposes[i] = Page::page_usage_counts[i] << 12UL;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Memory
|
||||
|
|
|
@ -393,6 +393,7 @@ langinfo/nl_langinfo_l.o \
|
|||
langinfo/nl_langinfo.o \
|
||||
locale/localeconv.o \
|
||||
locale/setlocale.o \
|
||||
memusage/memusage.o \
|
||||
msr/rdmsr.o \
|
||||
msr/wrmsr.o \
|
||||
netdb/endnetent.o \
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 2023 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
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* memusage.h
|
||||
* Memory usage statistics.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_MEMUSAGE_H
|
||||
#define _INCLUDE_MEMUSAGE_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <sortix/memusage.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int memusage(const size_t*, size_t*, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 2023 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
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* memsage/memusage.c
|
||||
* Memory usage statistics.
|
||||
*/
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <memusage.h>
|
||||
|
||||
DEFN_SYSCALL3(int, sys_memusage, SYSCALL_MEMUSAGE, const size_t*, size_t*,
|
||||
size_t);
|
||||
|
||||
int memusage(const size_t* statistics, size_t* values, size_t length)
|
||||
{
|
||||
return sys_memusage(statistics, values, length);
|
||||
}
|
|
@ -1,6 +1,60 @@
|
|||
diff -Paur --no-dereference -- xz.upstream/configure xz/configure
|
||||
--- xz.upstream/configure
|
||||
+++ xz/configure
|
||||
@@ -16829,7 +16829,7 @@
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_includedir"; then
|
||||
- INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir"
|
||||
+ INCICONV="${INCICONV}${INCICONV:+ }"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -16876,7 +16876,7 @@
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
- LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir"
|
||||
+ LIBICONV="${LIBICONV}${LIBICONV:+ }"
|
||||
fi
|
||||
fi
|
||||
haveit=
|
||||
@@ -16897,7 +16897,7 @@
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir"
|
||||
+ LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -17772,7 +17772,7 @@
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_includedir"; then
|
||||
- INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir"
|
||||
+ INCINTL="${INCINTL}${INCINTL:+ }"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -17819,7 +17819,7 @@
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
- LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir"
|
||||
+ LIBINTL="${LIBINTL}${LIBINTL:+ }"
|
||||
fi
|
||||
fi
|
||||
haveit=
|
||||
@@ -17840,7 +17840,7 @@
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
- LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir"
|
||||
+ LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -19269,6 +19269,7 @@
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__OS2__) \
|
||||
|
@ -19,7 +73,7 @@ diff -Paur --no-dereference -- xz.upstream/src/common/tuklib_physmem.c xz/src/co
|
|||
+
|
||||
+// Sortix
|
||||
+#elif defined(__sortix__)
|
||||
+# include <unistd.h>
|
||||
+# include <memusage.h>
|
||||
+
|
||||
#endif
|
||||
|
||||
|
@ -29,9 +83,9 @@ diff -Paur --no-dereference -- xz.upstream/src/common/tuklib_physmem.c xz/src/co
|
|||
if (sysinfo(&si) == 0)
|
||||
ret = (uint64_t)si.totalram * si.mem_unit;
|
||||
+#elif defined(__sortix__)
|
||||
+ size_t ret_size_t;
|
||||
+ memstat(NULL, &ret_size_t);
|
||||
+ ret = ret_size_t;
|
||||
+ size_t statistic = MEMUSAGE_TOTAL;
|
||||
+ memusage(&statistic, &statistic, 1);
|
||||
+ ret = statistic;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -69,6 +69,11 @@ releasing Sortix x.y, foo." to allow the maintainer to easily
|
|||
.Xr grep 1
|
||||
for it after a release.
|
||||
.Sh CHANGES
|
||||
.Ss Add memusage(2)
|
||||
The
|
||||
.Xr memusage 2
|
||||
system call has been added, which provides detailed system memory statistics.
|
||||
This is a minor compatible ABI change.
|
||||
.Ss Add networking stack
|
||||
The network stack has been implemented in the kernel and exposed through
|
||||
additions to the system call interface.
|
||||
|
|
|
@ -1,19 +1,94 @@
|
|||
.Dd October 6, 2016
|
||||
.Dd March 8, 2023
|
||||
.Dt MEMSTAT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm memstat
|
||||
.Nd print system memory usage information
|
||||
.Nd system memory statistics
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl abegkmprt
|
||||
.Op Ar statistic ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
prints the amount of memory in use, the total amount of memory, and the
|
||||
percentage of memory used.
|
||||
writes the requested system memory
|
||||
.Ar statistics ,
|
||||
or the
|
||||
.Sy total
|
||||
system memory and
|
||||
.Sy used
|
||||
system memory by default.
|
||||
Each statistic is written as a line with three columns aligned with spaces,
|
||||
where the first column is the human readable value, the second column is the
|
||||
name of the statistic, and the third column is how many percent the value is out
|
||||
of total system memory.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width "12345678"
|
||||
.It Fl a
|
||||
Write all statistics.
|
||||
.It Fl b
|
||||
Format values as bytes.
|
||||
.It Fl e
|
||||
Format values as exabytes (1024^6 bytes).
|
||||
.It Fl g
|
||||
Format values as gigabytes (1024^3 bytes).
|
||||
.It Fl k
|
||||
Format values as kilobytes (1024 bytes).
|
||||
.It Fl m
|
||||
Format values as megabytes (1024^2 bytes).
|
||||
.It Fl p
|
||||
Format values as petabytes (1024^5 bytes).
|
||||
.It Fl r
|
||||
Write statistics in the raw machine readable format consisting of the value in
|
||||
the requested unit (bytes by default) with no unit suffix followed by a space
|
||||
and then the statistic name.
|
||||
.It Fl t
|
||||
Format values as terabytes (1024^4 bytes).
|
||||
.El
|
||||
.Pp
|
||||
The statistics are as follows:
|
||||
.Pp
|
||||
.Bl -tag -width filesystem -compact
|
||||
.It Sy total
|
||||
amount of total memory.
|
||||
.It Sy used
|
||||
amount of memory currently used for any purpose.
|
||||
.It Sy userspace
|
||||
amount of memory purposed for normal user-space pages.
|
||||
.It Sy kernel
|
||||
amount of memory purposed for normal kernel-space pages.
|
||||
.It Sy filesystem
|
||||
amount of memory purposed for kernel filesystem buffers.
|
||||
.It Sy network
|
||||
amount of memory purposed for kernel network buffers.
|
||||
.It Sy paging
|
||||
amount of memory purposed for paging overhead.
|
||||
.It Sy driver
|
||||
amount of memory purposed for kernel driver buffers.
|
||||
.It Sy physical
|
||||
amount of memory purposed for keep track of unused physical memory.
|
||||
.It Sy execve
|
||||
amount of memory purposed for the
|
||||
.Xr execve 2
|
||||
system call.
|
||||
.El
|
||||
.Pp
|
||||
.Nm
|
||||
measures an instantaneous consistent snapshot of all the system memory
|
||||
statistics using
|
||||
.Xr memusage 2 .
|
||||
Each page of memory is used for exactly one purpose and the purpose statistics
|
||||
add up to the
|
||||
.Sy used
|
||||
statistic.
|
||||
.Sh EXIT STATUS
|
||||
.Nm
|
||||
will exit 0 on success and non-zero otherwise.
|
||||
.Sh SEE ALSO
|
||||
.Xr ps 1 ,
|
||||
.Xr pstree 1 ,
|
||||
.Xr memstat 2
|
||||
.Xr memusage 2
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
originally appeared in Sortix 0.5.
|
||||
The output was changed to the current table format in Sortix 1.1.
|
||||
|
|
205
utils/memstat.c
205
utils/memstat.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011, 2022, 2023 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
|
||||
|
@ -14,13 +14,16 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* memstat.c
|
||||
* Prints system memory usage information.
|
||||
* System memory statistics.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <memusage.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BYTES 0
|
||||
#define KIBI 1
|
||||
|
@ -30,49 +33,173 @@
|
|||
#define PEBI 5
|
||||
#define EXBI 6
|
||||
|
||||
void printbytes(unsigned long long bytes)
|
||||
static char* format_bytes_amount(uintmax_t num_bytes, int unit, bool raw)
|
||||
{
|
||||
unsigned unit = BYTES;
|
||||
if ( (bytes >> 10ULL) & 1023ULL ) { unit = KIBI; }
|
||||
if ( (bytes >> 20ULL) & 1023ULL ) { unit = MEBI; }
|
||||
if ( (bytes >> 30ULL) & 1023ULL ) { unit = GIBI; }
|
||||
if ( (bytes >> 40ULL) & 1023ULL ) { unit = TEBI; }
|
||||
if ( (bytes >> 50ULL) & 1023ULL ) { unit = PEBI; }
|
||||
if ( (bytes >> 60ULL) & 1023ULL ) { unit = EXBI; }
|
||||
|
||||
switch ( unit )
|
||||
uintmax_t value = num_bytes;
|
||||
uintmax_t value_fraction = 0;
|
||||
uintmax_t exponent = 1024;
|
||||
char suffixes[] = { 'B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
|
||||
size_t num_suffixes = sizeof(suffixes) / sizeof(suffixes[0]);
|
||||
size_t suffix_index = 0;
|
||||
while ( (unit < 0 ? exponent <= value : (int) suffix_index < unit) &&
|
||||
suffix_index + 1 < num_suffixes )
|
||||
{
|
||||
case EXBI:
|
||||
printf("%llu ZiB ", (bytes >> 60ULL) & 1023ULL);
|
||||
case PEBI:
|
||||
printf("%llu PiB ", (bytes >> 50ULL) & 1023ULL);
|
||||
case TEBI:
|
||||
printf("%llu TiB ", (bytes >> 40ULL) & 1023ULL);
|
||||
case GIBI:
|
||||
printf("%llu GiB ", (bytes >> 30ULL) & 1023ULL);
|
||||
case MEBI:
|
||||
printf("%llu MiB ", (bytes >> 20ULL) & 1023ULL);
|
||||
case KIBI:
|
||||
printf("%llu KiB", (bytes >> 10ULL) & 1023ULL);
|
||||
break;
|
||||
case BYTES:
|
||||
printf("%llu B", (bytes >> 0ULL) & 1023ULL);
|
||||
value_fraction = value % exponent;
|
||||
value /= exponent;
|
||||
suffix_index++;
|
||||
}
|
||||
char suffix_char = raw ? 0 : suffixes[suffix_index];
|
||||
char value_fraction_char = '0' + (value_fraction / (1024 / 10 + 1)) % 10;
|
||||
char decimals[3] = {suffix_index ? '.' : 0, value_fraction_char, 0};
|
||||
char* result;
|
||||
if ( asprintf(&result, "%ju%s%c", value, decimals, suffix_char) < 0 )
|
||||
return NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
struct memusage
|
||||
{
|
||||
size_t memused = 0;
|
||||
size_t memtotal = 0;
|
||||
if ( memstat(&memused, &memtotal) )
|
||||
err(1, "memstat");
|
||||
size_t counter;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
printf("memory usage: ");
|
||||
printbytes(memused);
|
||||
printf(" used / ");
|
||||
printbytes(memtotal);
|
||||
unsigned percent = ((unsigned long long) memused * 100ULL ) / memtotal;
|
||||
printf(" total (%u%s)\n", percent, "%");
|
||||
static const struct memusage memusages[] =
|
||||
{
|
||||
{MEMUSAGE_TOTAL, "total"},
|
||||
{MEMUSAGE_USED, "used"},
|
||||
{MEMUSAGE_PURPOSE_USERSPACE, "userspace"},
|
||||
{MEMUSAGE_PURPOSE_KERNEL, "kernel"},
|
||||
{MEMUSAGE_PURPOSE_FILESYSTEM, "filesystem"},
|
||||
{MEMUSAGE_PURPOSE_NETWORK, "network"},
|
||||
{MEMUSAGE_PURPOSE_PAGING, "paging"},
|
||||
{MEMUSAGE_PURPOSE_DRIVER, "driver"},
|
||||
{MEMUSAGE_PURPOSE_PHYSICAL, "physical"},
|
||||
{MEMUSAGE_PURPOSE_EXECVE, "execve"},
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
bool all = false;
|
||||
bool raw = false;
|
||||
int unit = -1;
|
||||
|
||||
int opt;
|
||||
while ( (opt = getopt(argc, argv, "abegkmprt")) != -1 )
|
||||
{
|
||||
switch ( opt )
|
||||
{
|
||||
case 'a': all = true; break;
|
||||
case 'b': unit = BYTES; break;
|
||||
case 'e': unit = EXBI; break;
|
||||
case 'g': unit = GIBI; break;
|
||||
case 'k': unit = KIBI; break;
|
||||
case 'm': unit = MEBI; break;
|
||||
case 'p': unit = PEBI; break;
|
||||
case 'r': raw = true; break;
|
||||
case 't': unit = TEBI; break;
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t MAX_COUNTERS = sizeof(memusages) / sizeof(memusages[0]);
|
||||
const struct memusage* usages[MAX_COUNTERS];
|
||||
size_t num_counters;
|
||||
size_t start_counter = 0;
|
||||
|
||||
if ( all )
|
||||
{
|
||||
if ( optind < argc )
|
||||
errx(1, "extra operand: %s", argv[optind]);
|
||||
num_counters = MAX_COUNTERS;
|
||||
for ( size_t i = 0; i < num_counters; i++ )
|
||||
usages[i] = &memusages[i];
|
||||
}
|
||||
else if ( optind < argc )
|
||||
{
|
||||
num_counters = 1;
|
||||
start_counter = 1;
|
||||
usages[0] = &memusages[0];
|
||||
for ( int i = optind; i < argc; i++ )
|
||||
{
|
||||
if ( num_counters == MAX_COUNTERS )
|
||||
errx(1, "too many counters");
|
||||
bool found = false;
|
||||
for ( size_t n = 0; n < MAX_COUNTERS; n++ )
|
||||
{
|
||||
if ( strcmp(argv[i], memusages[n].name) != 0 )
|
||||
continue;
|
||||
usages[num_counters++] = &memusages[n];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if ( !found )
|
||||
errx(1, "unknown statistic: %s", argv[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
num_counters = 2;
|
||||
usages[0] = &memusages[0];
|
||||
usages[1] = &memusages[1];
|
||||
}
|
||||
|
||||
size_t counts[MAX_COUNTERS];
|
||||
for ( size_t i = 0; i < num_counters; i++ )
|
||||
counts[i] = usages[i]->counter;
|
||||
|
||||
size_t values[MAX_COUNTERS];
|
||||
if ( memusage(counts, values, num_counters) )
|
||||
err(1, "memusage");
|
||||
|
||||
if ( raw && unit == -1 )
|
||||
unit = BYTES;
|
||||
|
||||
size_t total = values[0];
|
||||
|
||||
size_t usage_width = 0;
|
||||
size_t name_width = 0;
|
||||
for ( size_t i = start_counter; i < num_counters; i++ )
|
||||
{
|
||||
size_t count = values[i];
|
||||
const char* name = usages[i]->name;
|
||||
char* usage = format_bytes_amount(count, unit, raw);
|
||||
if ( !usage )
|
||||
err(1, "malloc");
|
||||
size_t usage_len = strlen(usage);
|
||||
if ( usage_width < usage_len )
|
||||
usage_width = usage_len;
|
||||
size_t name_len = strlen(name);
|
||||
if ( name_width < name_len )
|
||||
name_width = name_len;
|
||||
free(usage);
|
||||
}
|
||||
|
||||
for ( size_t i = start_counter; i < num_counters; i++ )
|
||||
{
|
||||
size_t count = values[i];
|
||||
const char* name = usages[i]->name;
|
||||
char* usage = format_bytes_amount(count, unit, raw);
|
||||
if ( !usage )
|
||||
err(1, "malloc");
|
||||
if ( raw )
|
||||
{
|
||||
if ( num_counters - start_counter == 1 )
|
||||
printf("%s\n", usage);
|
||||
else
|
||||
printf("%s %s\n", usage, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%*s", (int) usage_width, usage);
|
||||
printf(" %-*s", (int) name_width, name);
|
||||
unsigned percent = ((uintmax_t) count * 100) / total;
|
||||
printf(" %3u%%\n", percent);
|
||||
}
|
||||
free(usage);
|
||||
}
|
||||
|
||||
if ( ferror(stdout) || fflush(stdout) == EOF )
|
||||
err(1, "stdout");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue