diff --git a/kernel/include/kernel/Memory/SharedMemoryObject.h b/kernel/include/kernel/Memory/SharedMemoryObject.h index e494d949..94e15eff 100644 --- a/kernel/include/kernel/Memory/SharedMemoryObject.h +++ b/kernel/include/kernel/Memory/SharedMemoryObject.h @@ -21,6 +21,7 @@ namespace Kernel static SharedMemoryObjectManager& get(); BAN::ErrorOr create_object(size_t size, PageTable::flags_t); + BAN::ErrorOr delete_object(Key); BAN::ErrorOr> map_object(Key, PageTable&, AddressRange); private: @@ -29,6 +30,8 @@ namespace Kernel private: struct Object : public BAN::RefCounted { + ~Object(); + size_t size; PageTable::flags_t flags; BAN::Vector paddrs; diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 31ec14fe..ac010ed3 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -159,6 +159,7 @@ namespace Kernel BAN::ErrorOr sys_msync(void* addr, size_t len, int flags); BAN::ErrorOr sys_smo_create(size_t len, int prot); + BAN::ErrorOr sys_smo_delete(SharedMemoryObjectManager::Key); BAN::ErrorOr sys_smo_map(SharedMemoryObjectManager::Key); BAN::ErrorOr sys_tty_ctrl(int fildes, int command, int flags); diff --git a/kernel/kernel/Memory/SharedMemoryObject.cpp b/kernel/kernel/Memory/SharedMemoryObject.cpp index c36893c7..1a8425fc 100644 --- a/kernel/kernel/Memory/SharedMemoryObject.cpp +++ b/kernel/kernel/Memory/SharedMemoryObject.cpp @@ -21,6 +21,13 @@ namespace Kernel return *s_instance; } + SharedMemoryObjectManager::Object::~Object() + { + for (auto paddr : paddrs) + if (paddr) + Heap::get().release_page(paddr); + } + BAN::ErrorOr SharedMemoryObjectManager::create_object(size_t size, PageTable::flags_t flags) { ASSERT(size % PAGE_SIZE == 0); @@ -43,6 +50,18 @@ namespace Kernel return key; } + BAN::ErrorOr SharedMemoryObjectManager::delete_object(Key key) + { + LockGuard _(m_mutex); + + auto it = m_objects.find(key); + if (it == m_objects.end()) + return BAN::Error::from_errno(ENOENT); + + m_objects.remove(it); + return {}; + } + BAN::ErrorOr> SharedMemoryObjectManager::map_object(Key key, PageTable& page_table, AddressRange address_range) { LockGuard _(m_mutex); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 1bf38519..abc02a7d 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -1418,6 +1418,12 @@ namespace Kernel return TRY(SharedMemoryObjectManager::get().create_object(len, page_flags)); } + BAN::ErrorOr Process::sys_smo_delete(SharedMemoryObjectManager::Key key) + { + TRY(SharedMemoryObjectManager::get().delete_object(key)); + return 0; + } + BAN::ErrorOr Process::sys_smo_map(SharedMemoryObjectManager::Key key) { auto region = TRY(SharedMemoryObjectManager::get().map_object(key, page_table(), { .start = 0x400000, .end = KERNEL_OFFSET })); diff --git a/libc/include/sys/banan-os.h b/libc/include/sys/banan-os.h index e69d690a..30565c4b 100644 --- a/libc/include/sys/banan-os.h +++ b/libc/include/sys/banan-os.h @@ -38,7 +38,9 @@ int load_keymap(const char* path); // Create shared memory object and return its key or -1 on error long smo_create(size_t size, int prot); -// Map shared memory object defined by its key and return address or null on error +// Delete shared memory object such that it will be no longer accessible with smo_map(). Existing mappings are still valid +int smo_delete(long key); +// Map shared memory object defined by its key and return address or null on error. Mappings can be unmapped using munmap() void* smo_map(long key); __END_DECLS diff --git a/libc/include/sys/syscall.h b/libc/include/sys/syscall.h index 0ccab637..429e4351 100644 --- a/libc/include/sys/syscall.h +++ b/libc/include/sys/syscall.h @@ -75,6 +75,7 @@ __BEGIN_DECLS O(SYS_PSELECT, pselect) \ O(SYS_TRUNCATE, truncate) \ O(SYS_SMO_CREATE, smo_create) \ + O(SYS_SMO_DELETE, smo_delete) \ O(SYS_SMO_MAP, smo_map) \ enum Syscall diff --git a/libc/sys/banan-os.cpp b/libc/sys/banan-os.cpp index 66504751..67489aba 100644 --- a/libc/sys/banan-os.cpp +++ b/libc/sys/banan-os.cpp @@ -22,6 +22,11 @@ long smo_create(size_t size, int prot) return syscall(SYS_SMO_CREATE, size, prot); } +int smo_delete(long key) +{ + return syscall(SYS_SMO_DELETE, key); +} + void* smo_map(long key) { long ret = syscall(SYS_SMO_MAP, key);