diff --git a/headers/posix/sys/mman.h b/headers/posix/sys/mman.h index 40c49c7b5d..8661ad6c9f 100644 --- a/headers/posix/sys/mman.h +++ b/headers/posix/sys/mman.h @@ -33,12 +33,20 @@ #define MS_SYNC 0x02 #define MS_INVALIDATE 0x04 +/* madvise() values */ +#define MADV_NORMAL 1 +#define MADV_SEQUENTIAL 2 +#define MADV_RANDOM 3 +#define MADV_WILLNEED 4 +#define MADV_DONTNEED 5 +#define MADV_FREE 6 + /* posix_madvise() values */ -#define POSIX_MADV_NORMAL 1 -#define POSIX_MADV_SEQUENTIAL 2 -#define POSIX_MADV_RANDOM 3 -#define POSIX_MADV_WILLNEED 4 -#define POSIX_MADV_DONTNEED 5 +#define POSIX_MADV_NORMAL MADV_NORMAL +#define POSIX_MADV_SEQUENTIAL MADV_SEQUENTIAL +#define POSIX_MADV_RANDOM MADV_RANDOM +#define POSIX_MADV_WILLNEED MADV_WILLNEED +#define POSIX_MADV_DONTNEED MADV_DONTNEED __BEGIN_DECLS @@ -50,6 +58,7 @@ int munmap(void* address, size_t length); int mprotect(void* address, size_t length, int protection); int msync(void* address, size_t length, int flags); +int madvise(void* address, size_t length, int advice); int posix_madvise(void* address, size_t length, int advice); int shm_open(const char* name, int openMode, mode_t permissions); diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 5048a69cd5..cc6aff51fb 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -6782,9 +6782,46 @@ _user_sync_memory(void* _address, size_t size, uint32 flags) status_t -_user_memory_advice(void* address, size_t size, uint32 advice) +_user_memory_advice(void* _address, size_t size, uint32 advice) { - // TODO: Implement! + addr_t address = (addr_t)_address; + if ((address % B_PAGE_SIZE) != 0) + return B_BAD_VALUE; + + size = PAGE_ALIGN(size); + if (address + size < address || !IS_USER_ADDRESS(address) + || !IS_USER_ADDRESS(address + size)) { + // weird error code required by POSIX + return B_NO_MEMORY; + } + + switch (advice) { + case MADV_NORMAL: + case MADV_SEQUENTIAL: + case MADV_RANDOM: + case MADV_WILLNEED: + case MADV_DONTNEED: + // TODO: Implement! + break; + + case MADV_FREE: + { + AddressSpaceWriteLocker locker; + do { + status_t status = locker.SetTo(team_get_current_team_id()); + if (status != B_OK) + return status; + } while (wait_if_address_range_is_wired(locker.AddressSpace(), + address, size, &locker)); + + discard_address_range(locker.AddressSpace(), address, size, false); + break; + } + + default: + return B_BAD_VALUE; + } + return B_OK; } diff --git a/src/system/libroot/posix/sys/mman.cpp b/src/system/libroot/posix/sys/mman.cpp index 3944538ef9..bb00ab00ef 100644 --- a/src/system/libroot/posix/sys/mman.cpp +++ b/src/system/libroot/posix/sys/mman.cpp @@ -181,12 +181,19 @@ msync(void* address, size_t length, int flags) int -posix_madvise(void* address, size_t length, int advice) +madvise(void* address, size_t length, int advice) { RETURN_AND_SET_ERRNO(_kern_memory_advice(address, length, advice)); } +int +posix_madvise(void* address, size_t length, int advice) +{ + return madvise(address, length, advice); +} + + int shm_open(const char* name, int openMode, mode_t permissions) { diff --git a/src/system/libroot/stubbed/libroot_stubs.c b/src/system/libroot/stubbed/libroot_stubs.c index f65dfa9e00..73d0c7dfd2 100644 --- a/src/system/libroot/stubbed/libroot_stubs.c +++ b/src/system/libroot/stubbed/libroot_stubs.c @@ -2336,6 +2336,7 @@ void lroundf() {} void lroundl() {} void lsearch() {} void lseek() {} +void madvise() {} void malloc() {} void malloc_usable_size() {} void matherr() {} diff --git a/src/system/libroot/stubbed/libroot_stubs_legacy.c b/src/system/libroot/stubbed/libroot_stubs_legacy.c index fc050f3d18..2de2f3aa35 100644 --- a/src/system/libroot/stubbed/libroot_stubs_legacy.c +++ b/src/system/libroot/stubbed/libroot_stubs_legacy.c @@ -2257,6 +2257,7 @@ void lroundf() {} void lroundl() {} void lsearch() {} void lseek() {} +void madvise() {} void makeSuperblock__Q28BPrivate10superblockiPQ28BPrivate11processHeap() {} void malloc() {} void malloc__Q28BPrivate10threadHeapUl() {}