Compare commits
7 Commits
c11d55d675
...
08a9627548
| Author | SHA1 | Date | |
|---|---|---|---|
| 08a9627548 | |||
| 844f6d50eb | |||
| 863be171c1 | |||
| 0471838f30 | |||
| cf70352caa | |||
| 342b588b38 | |||
| cdf828be2d |
2
kernel
2
kernel
Submodule kernel updated: a2e918c428...4551e7b2e6
@@ -28,3 +28,5 @@ bsp_add_library(
|
|||||||
|
|
||||||
target_link_libraries(libc libmango libxpc-static interface::fs)
|
target_link_libraries(libc libmango libxpc-static interface::fs)
|
||||||
target_compile_definitions(libc PRIVATE ENABLE_GLOBAL_HEAP=1)
|
target_compile_definitions(libc PRIVATE ENABLE_GLOBAL_HEAP=1)
|
||||||
|
|
||||||
|
add_subdirectory(pthread)
|
||||||
|
|||||||
@@ -41,5 +41,6 @@ extern void *mmap(
|
|||||||
int flags,
|
int flags,
|
||||||
int fd,
|
int fd,
|
||||||
off_t offset);
|
off_t offset);
|
||||||
|
extern int munmap(void *addr, size_t length);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
34
lib/libc/io/unistd/munmap.c
Normal file
34
lib/libc/io/unistd/munmap.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <mango/handle.h>
|
||||||
|
#include <mango/task.h>
|
||||||
|
#include <mango/vm.h>
|
||||||
|
#include <rosetta/fs.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
int munmap(void *addr, size_t length)
|
||||||
|
{
|
||||||
|
kern_status_t status = KERN_OK;
|
||||||
|
kern_handle_t self = KERN_HANDLE_INVALID,
|
||||||
|
address_space = KERN_HANDLE_INVALID;
|
||||||
|
|
||||||
|
status = task_self(&self);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
return __set_errno(EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = task_get_address_space(self, &address_space);
|
||||||
|
kern_handle_close(self);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
return __set_errno(EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = address_space_unmap(address_space, (virt_addr_t)addr, length);
|
||||||
|
|
||||||
|
kern_handle_close(address_space);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
return __set_errno(__errno_from_kern_status(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
return __set_errno(SUCCESS);
|
||||||
|
}
|
||||||
42
lib/libc/pthread/CMakeLists.txt
Normal file
42
lib/libc/pthread/CMakeLists.txt
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
set(source_dirs thread)
|
||||||
|
|
||||||
|
foreach (dir ${source_dirs})
|
||||||
|
file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.c)
|
||||||
|
file(GLOB dir_headers ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.h)
|
||||||
|
|
||||||
|
set(sources ${sources} ${dir_sources})
|
||||||
|
set(headers ${headers} ${dir_headers})
|
||||||
|
endforeach (dir)
|
||||||
|
|
||||||
|
file(GLOB sys_sources
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/sys/${CMAKE_SYSTEM_PROCESSOR}/*.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/sys/${CMAKE_SYSTEM_PROCESSOR}/*.S)
|
||||||
|
set_property(SOURCE ${sys_sources} PROPERTY LANGUAGE C)
|
||||||
|
|
||||||
|
set(sources ${sources} ${sys_sources})
|
||||||
|
|
||||||
|
set(headers ${headers} ${CMAKE_CURRENT_SOURCE_DIR}/include/pthread.h)
|
||||||
|
set(public_include_dir ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
|
rosetta_add_library(STATIC
|
||||||
|
NAME libc-pthread
|
||||||
|
PUBLIC_INCLUDE_DIRS ${public_include_dir}
|
||||||
|
SOURCES ${sources}
|
||||||
|
HEADERS ${headers})
|
||||||
|
rosetta_add_library(SHARED
|
||||||
|
NAME libpthread
|
||||||
|
PUBLIC_INCLUDE_DIRS ${public_include_dir}
|
||||||
|
SOURCES ${sources}
|
||||||
|
HEADERS ${headers})
|
||||||
|
|
||||||
|
sysroot_add_library(
|
||||||
|
NAME libc-pthread
|
||||||
|
HEADER_DIR /usr/include
|
||||||
|
LIB_DIR /usr/lib)
|
||||||
|
sysroot_add_library(
|
||||||
|
NAME libpthread
|
||||||
|
HEADER_DIR /usr/include
|
||||||
|
LIB_DIR /usr/lib)
|
||||||
|
|
||||||
|
target_link_libraries(libc-pthread libc-io libmango)
|
||||||
|
target_link_libraries(libpthread libmango libc)
|
||||||
25
lib/libc/pthread/include/pthread.h
Normal file
25
lib/libc/pthread/include/pthread.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef PTHREAD_H_
|
||||||
|
#define PTHREAD_H_
|
||||||
|
|
||||||
|
#define __PTHREAD_ATTR_SIZE__ 32
|
||||||
|
|
||||||
|
typedef struct __pthread *pthread_t;
|
||||||
|
|
||||||
|
typedef struct __pthread_attr {
|
||||||
|
long __sig;
|
||||||
|
char __opaque[__PTHREAD_ATTR_SIZE__];
|
||||||
|
} pthread_attr_t;
|
||||||
|
|
||||||
|
extern int __pthread_init(void);
|
||||||
|
|
||||||
|
extern int pthread_create(
|
||||||
|
pthread_t *thread,
|
||||||
|
const pthread_attr_t *attr,
|
||||||
|
void *(*start_func)(void *),
|
||||||
|
void *arg);
|
||||||
|
extern pthread_t pthread_self(void);
|
||||||
|
extern int pthread_join(pthread_t thread, void **retval);
|
||||||
|
extern int pthread_detach(pthread_t thread);
|
||||||
|
extern void pthread_exit(void *retval);
|
||||||
|
|
||||||
|
#endif
|
||||||
0
lib/libc/pthread/init.c
Normal file
0
lib/libc/pthread/init.c
Normal file
13
lib/libc/pthread/sys/x86_64/pthread_self.S
Normal file
13
lib/libc/pthread/sys/x86_64/pthread_self.S
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.code64
|
||||||
|
|
||||||
|
.global pthread_self
|
||||||
|
.type pthread_self, @function
|
||||||
|
|
||||||
|
pthread_self:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp, %rbp
|
||||||
|
|
||||||
|
mov %gs:0, %rax
|
||||||
|
|
||||||
|
pop %rbp
|
||||||
|
ret
|
||||||
35
lib/libc/pthread/sys/x86_64/pthread_unmap_exit.S
Normal file
35
lib/libc/pthread/sys/x86_64/pthread_unmap_exit.S
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
.code64
|
||||||
|
|
||||||
|
#include "mango/syscall.h"
|
||||||
|
|
||||||
|
.global __pthread_unmap_exit
|
||||||
|
.type __pthread_unmap_exit, @function
|
||||||
|
|
||||||
|
/*
|
||||||
|
%rdi = (kern_handle_t)address_space
|
||||||
|
%rsi = (void *)unmap_base
|
||||||
|
%rdx = (size_t)unmap_length
|
||||||
|
*/
|
||||||
|
__pthread_unmap_exit:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp, %rbp
|
||||||
|
|
||||||
|
/* save the address space handle for later */
|
||||||
|
mov %rdi, %rbx
|
||||||
|
|
||||||
|
/* first, unmap the specified region */
|
||||||
|
mov $SYS_ADDRESS_SPACE_UNMAP, %rax
|
||||||
|
/* args are already in the correct registers */
|
||||||
|
syscall
|
||||||
|
|
||||||
|
/* next, close the handle to the address space */
|
||||||
|
mov $SYS_THREAD_EXIT, %rax
|
||||||
|
mov %rbx, %rdi
|
||||||
|
syscall
|
||||||
|
|
||||||
|
/* finally, stop the current thread */
|
||||||
|
mov $SYS_THREAD_EXIT, %rax
|
||||||
|
syscall
|
||||||
|
|
||||||
|
/* unreachable */
|
||||||
|
ret
|
||||||
24
lib/libc/pthread/thread/pthread.h
Normal file
24
lib/libc/pthread/thread/pthread.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _THREAD_PTHREAD_H_
|
||||||
|
#define _THREAD_PTHREAD_H_
|
||||||
|
|
||||||
|
#include <mango/types.h>
|
||||||
|
|
||||||
|
enum pthread_flags {
|
||||||
|
THREAD_DETACHED = 0x01u,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __pthread {
|
||||||
|
struct __pthread *thr_self;
|
||||||
|
enum pthread_flags thr_flags;
|
||||||
|
kern_handle_t thr_handle;
|
||||||
|
void *thr_map_base;
|
||||||
|
size_t thr_map_size;
|
||||||
|
void *thr_result;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void __pthread_unmap_exit(
|
||||||
|
kern_handle_t address_space,
|
||||||
|
void *unmap_base,
|
||||||
|
size_t unmap_length);
|
||||||
|
|
||||||
|
#endif
|
||||||
0
lib/libc/pthread/thread/pthread_attr.h
Normal file
0
lib/libc/pthread/thread/pthread_attr.h
Normal file
89
lib/libc/pthread/thread/pthread_create.c
Normal file
89
lib/libc/pthread/thread/pthread_create.c
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
#include "pthread.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <mango/status.h>
|
||||||
|
#include <mango/task.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#define DEFAULT_STACK_SIZE 0x40000
|
||||||
|
|
||||||
|
static void thread_launchpad(uintptr_t thread, uintptr_t func, uintptr_t arg)
|
||||||
|
{
|
||||||
|
struct __pthread *self = (struct __pthread *)thread;
|
||||||
|
void *(*start_func)(void *) = (void *(*)(void *))func;
|
||||||
|
|
||||||
|
void *result = start_func((void *)arg);
|
||||||
|
|
||||||
|
pthread_exit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_create(
|
||||||
|
pthread_t *thread,
|
||||||
|
const pthread_attr_t *attr,
|
||||||
|
void *(*start_func)(void *),
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
kern_status_t status = KERN_OK;
|
||||||
|
kern_handle_t task;
|
||||||
|
|
||||||
|
status = task_self(&task);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
return __set_errno(EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t stack_size = DEFAULT_STACK_SIZE;
|
||||||
|
|
||||||
|
void *base
|
||||||
|
= mmap(NULL,
|
||||||
|
stack_size,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE | MAP_ANONYMOUS,
|
||||||
|
-1,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (!base) {
|
||||||
|
return __set_errno(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
virt_addr_t sp = (virt_addr_t)base + DEFAULT_STACK_SIZE;
|
||||||
|
|
||||||
|
sp -= sizeof(struct __pthread);
|
||||||
|
struct __pthread *new = (struct __pthread *)sp;
|
||||||
|
sp &= ~(virt_addr_t)0x10;
|
||||||
|
|
||||||
|
memset(new, 0x0, sizeof *new);
|
||||||
|
new->thr_self = new;
|
||||||
|
new->thr_map_base = base;
|
||||||
|
new->thr_map_size = stack_size;
|
||||||
|
|
||||||
|
uintptr_t args[] = {
|
||||||
|
(uintptr_t)new,
|
||||||
|
(uintptr_t)start_func,
|
||||||
|
(uintptr_t)arg,
|
||||||
|
};
|
||||||
|
size_t nr_args = sizeof args / sizeof args[0];
|
||||||
|
|
||||||
|
status = task_create_thread(
|
||||||
|
task,
|
||||||
|
(virt_addr_t)thread_launchpad,
|
||||||
|
sp,
|
||||||
|
args,
|
||||||
|
nr_args,
|
||||||
|
&new->thr_handle);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
munmap(base, stack_size);
|
||||||
|
return __set_errno(__errno_from_kern_status(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_config_set(
|
||||||
|
new->thr_handle,
|
||||||
|
THREAD_CFG_GSBASE,
|
||||||
|
&new,
|
||||||
|
sizeof(void *));
|
||||||
|
thread_start(new->thr_handle);
|
||||||
|
|
||||||
|
*thread = new;
|
||||||
|
return __set_errno(SUCCESS);
|
||||||
|
}
|
||||||
17
lib/libc/pthread/thread/pthread_detach.c
Normal file
17
lib/libc/pthread/thread/pthread_detach.c
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include "pthread.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <mango/handle.h>
|
||||||
|
#include <mango/object.h>
|
||||||
|
#include <mango/signal.h>
|
||||||
|
#include <mango/task.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
int pthread_detach(struct __pthread *thread)
|
||||||
|
{
|
||||||
|
thread->thr_flags |= THREAD_DETACHED;
|
||||||
|
kern_handle_close(thread->thr_handle);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
31
lib/libc/pthread/thread/pthread_exit.c
Normal file
31
lib/libc/pthread/thread/pthread_exit.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include "pthread.h"
|
||||||
|
|
||||||
|
#include <mango/handle.h>
|
||||||
|
#include <mango/task.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern void pthread_exit(void *retval)
|
||||||
|
{
|
||||||
|
struct __pthread *self = pthread_self();
|
||||||
|
if (!self) {
|
||||||
|
/* TODO: abort(); */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->thr_flags & THREAD_DETACHED) {
|
||||||
|
kern_handle_t task;
|
||||||
|
kern_handle_t address_space;
|
||||||
|
task_self(&task);
|
||||||
|
task_get_address_space(task, &address_space);
|
||||||
|
kern_handle_close(task);
|
||||||
|
|
||||||
|
__pthread_unmap_exit(
|
||||||
|
address_space,
|
||||||
|
self->thr_map_base,
|
||||||
|
self->thr_map_size);
|
||||||
|
} else {
|
||||||
|
self->thr_result = retval;
|
||||||
|
thread_exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
31
lib/libc/pthread/thread/pthread_join.c
Normal file
31
lib/libc/pthread/thread/pthread_join.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include "pthread.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <mango/handle.h>
|
||||||
|
#include <mango/object.h>
|
||||||
|
#include <mango/signal.h>
|
||||||
|
#include <mango/task.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
int pthread_join(struct __pthread *thread, void **retval)
|
||||||
|
{
|
||||||
|
kern_wait_item_t wait;
|
||||||
|
wait.w_handle = thread->thr_handle;
|
||||||
|
wait.w_waitfor = THREAD_SIGNAL_STOPPED;
|
||||||
|
wait.w_observed = 0;
|
||||||
|
|
||||||
|
kern_status_t status = kern_object_wait(&wait, 1);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
return __set_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval) {
|
||||||
|
*retval = thread->thr_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_handle_close(thread->thr_handle);
|
||||||
|
munmap(thread->thr_map_base, thread->thr_map_size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
0
lib/libc/pthread/thread/pthread_self.c
Normal file
0
lib/libc/pthread/thread/pthread_self.c
Normal file
@@ -75,6 +75,7 @@ struct fs_context *fs_context_create(struct fs_allocator *alloc)
|
|||||||
TEMP_OBJECT_SIZE,
|
TEMP_OBJECT_SIZE,
|
||||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER,
|
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER,
|
||||||
&temp_buffer);
|
&temp_buffer);
|
||||||
|
kern_handle_close(address_space);
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
kern_handle_close(ctx->ctx_temp_object);
|
kern_handle_close(ctx->ctx_temp_object);
|
||||||
kern_handle_close(ctx->ctx_vm_controller);
|
kern_handle_close(ctx->ctx_vm_controller);
|
||||||
|
|||||||
@@ -208,7 +208,10 @@ enum launch_status launch_ctx_execute(
|
|||||||
|
|
||||||
thread_start(thread);
|
thread_start(thread);
|
||||||
|
|
||||||
kern_handle_close(thread);
|
result->r_task = remote_task;
|
||||||
|
result->r_thread = thread;
|
||||||
|
result->r_address_space = remote_address_space;
|
||||||
|
|
||||||
elf_image_cleanup(&image);
|
elf_image_cleanup(&image);
|
||||||
|
|
||||||
return LAUNCH_OK;
|
return LAUNCH_OK;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ set_property(SOURCE ${arch_sources} PROPERTY LANGUAGE C)
|
|||||||
add_executable(bootstrap ${c_sources} ${arch_sources})
|
add_executable(bootstrap ${c_sources} ${arch_sources})
|
||||||
|
|
||||||
target_link_libraries(bootstrap
|
target_link_libraries(bootstrap
|
||||||
libmango libc-core libc-malloc libfs-static liblaunch libxpc-static
|
libmango libc-core libc-malloc libc-pthread libfs-static liblaunch libxpc-static
|
||||||
interface::fs)
|
interface::fs)
|
||||||
|
|
||||||
target_compile_options(bootstrap PRIVATE
|
target_compile_options(bootstrap PRIVATE
|
||||||
|
|||||||
@@ -7,10 +7,12 @@
|
|||||||
#include <fs/context.h>
|
#include <fs/context.h>
|
||||||
#include <heap/heap.h>
|
#include <heap/heap.h>
|
||||||
#include <launch.h>
|
#include <launch.h>
|
||||||
|
#include <mango/handle.h>
|
||||||
#include <mango/log.h>
|
#include <mango/log.h>
|
||||||
#include <mango/msg.h>
|
#include <mango/msg.h>
|
||||||
#include <mango/task.h>
|
#include <mango/task.h>
|
||||||
#include <mango/types.h>
|
#include <mango/types.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <rosetta/bootstrap.h>
|
#include <rosetta/bootstrap.h>
|
||||||
#include <rosetta/fs.h>
|
#include <rosetta/fs.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -90,6 +92,13 @@ static void _fs_free(struct fs_allocator *alloc, void *p)
|
|||||||
heap_free(alloc->fs_arg, p);
|
heap_free(alloc->fs_arg, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *thread_func(void *arg)
|
||||||
|
{
|
||||||
|
kern_logf("a thread! (%p)", pthread_self());
|
||||||
|
// kern_logf("a thread!");
|
||||||
|
return (void *)0x123;
|
||||||
|
}
|
||||||
|
|
||||||
int main(
|
int main(
|
||||||
int argc,
|
int argc,
|
||||||
const char **argv,
|
const char **argv,
|
||||||
@@ -159,6 +168,11 @@ int main(
|
|||||||
kern_handle_t channel;
|
kern_handle_t channel;
|
||||||
channel_create(0, &channel);
|
channel_create(0, &channel);
|
||||||
|
|
||||||
|
pthread_t thread;
|
||||||
|
pthread_create(&thread, NULL, thread_func, NULL);
|
||||||
|
pthread_detach(thread);
|
||||||
|
kern_logf("created new thread %p", thread);
|
||||||
|
|
||||||
launch_ctx_init(&launch);
|
launch_ctx_init(&launch);
|
||||||
launch.ctx_resolve_library = resolve_dependency;
|
launch.ctx_resolve_library = resolve_dependency;
|
||||||
|
|
||||||
@@ -169,6 +183,10 @@ int main(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kern_handle_close(result.r_task);
|
||||||
|
kern_handle_close(result.r_thread);
|
||||||
|
kern_handle_close(result.r_address_space);
|
||||||
|
|
||||||
heap_t heap = HEAP_INIT;
|
heap_t heap = HEAP_INIT;
|
||||||
|
|
||||||
struct fs_allocator fs_allocator = {
|
struct fs_allocator fs_allocator = {
|
||||||
|
|||||||
@@ -21,10 +21,6 @@ int main(const struct rosetta_bootstrap *bs)
|
|||||||
{
|
{
|
||||||
kern_logf("ld");
|
kern_logf("ld");
|
||||||
|
|
||||||
kern_handle_t task, address_space;
|
|
||||||
task_self(&task);
|
|
||||||
task_get_address_space(task, &address_space);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < bs->bs_argc; i++) {
|
for (size_t i = 0; i < bs->bs_argc; i++) {
|
||||||
kern_logf("argv[%zu]: %s", i, bs->bs_argv[i]);
|
kern_logf("argv[%zu]: %s", i, bs->bs_argv[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user