Add (pretty PoC) shared memory primitives
This commit is contained in:
@@ -5,5 +5,8 @@
|
||||
|
||||
struct thread;
|
||||
|
||||
int sys_shmget(size_t size, int flags);
|
||||
void *sys_shmat(int id, const void *hint, int flags);
|
||||
|
||||
void *sys_mmap(void *hint, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
int sys_munmap(void *addr, size_t length);
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
#define SYSCALL_NR_CHOWN 92
|
||||
#define SYSCALL_NR_MKNOD 133
|
||||
|
||||
#define SYSCALL_NR_SHMGET 113
|
||||
#define SYSCALL_NR_SHMAT 114
|
||||
#define SYSCALL_NR_SHMDT 115
|
||||
|
||||
#define SYSCALL_NR_NANOSLEEP 35
|
||||
#define SYSCALL_NR_UNAME 63
|
||||
#define SYSCALL_NR_GETTIMEOFDAY 96
|
||||
|
||||
@@ -15,6 +15,16 @@
|
||||
#include "fs/node.h"
|
||||
#include "sys/mm.h"
|
||||
|
||||
// TODO: access control and stuff
|
||||
struct shm_chunk {
|
||||
int id;
|
||||
struct list_head link;
|
||||
size_t page_count;
|
||||
uintptr_t pages[];
|
||||
};
|
||||
|
||||
static LIST_HEAD(g_shm_chunks);
|
||||
|
||||
static int sys_mmap_anon(mm_space_t space, uintptr_t base, size_t page_count, int prot, int flags) {
|
||||
uint64_t map_flags = MM_PAGE_USER;
|
||||
int map_usage = PU_PRIVATE;
|
||||
@@ -192,3 +202,57 @@ int sys_munmap(void *ptr, size_t len) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_shmget(size_t size, int flags) {
|
||||
static int shmid = 0;
|
||||
size = (size + MM_PAGE_SIZE - 1) / MM_PAGE_SIZE;
|
||||
|
||||
struct shm_chunk *chunk = kmalloc(sizeof(struct shm_chunk) + size * sizeof(uintptr_t));
|
||||
_assert(chunk);
|
||||
|
||||
chunk->page_count = size;
|
||||
chunk->id = ++shmid;
|
||||
list_head_init(&chunk->link);
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
chunk->pages[i] = mm_phys_alloc_page();
|
||||
_assert(chunk->pages[i] != MM_NADDR);
|
||||
}
|
||||
|
||||
list_add(&chunk->link, &g_shm_chunks);
|
||||
|
||||
return chunk->id;
|
||||
}
|
||||
|
||||
void *sys_shmat(int id, const void *hint, int flags) {
|
||||
uintptr_t virt_base;
|
||||
mm_space_t space;
|
||||
struct shm_chunk *chunk, *iter;
|
||||
|
||||
chunk = NULL;
|
||||
list_for_each_entry(iter, &g_shm_chunks, link) {
|
||||
if (iter->id == id) {
|
||||
chunk = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!chunk) {
|
||||
return (void *) -ENOENT;
|
||||
}
|
||||
|
||||
space = thread_self->proc->space;
|
||||
|
||||
// TODO: use hint
|
||||
virt_base = vmfind(space, 0x100000000, 0x400000000, chunk->page_count);
|
||||
_assert(virt_base != MM_NADDR);
|
||||
|
||||
for (size_t i = 0; i < chunk->page_count; ++i) {
|
||||
mm_map_single(space,
|
||||
virt_base + i * MM_PAGE_SIZE,
|
||||
chunk->pages[i],
|
||||
MM_PAGE_WRITE | MM_PAGE_USER,
|
||||
PU_SHARED);
|
||||
}
|
||||
|
||||
return (void *) virt_base;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user