Implement thread_join

And use it for tinyc implementation
This commit is contained in:
Mathieu Maret 2024-02-16 00:40:48 +01:00 committed by Mathieu Maret
parent 454f0875f5
commit 4204087bd1
12 changed files with 84 additions and 8 deletions

View File

@ -191,3 +191,39 @@ pid_t processGetId(struct process *proc){
pid_t processGetNextTid(struct process *proc){
return proc->nextTid++;
}
//Should be called with IRQ disabled
struct thread *processGetThread(struct process *proc, pid_t tid)
{
int count;
struct thread *th;
struct thread *thFound = NULL;
list_foreach_named(proc->thList, th, count, prevInProcess, nextInProcess)
{
if (th->tid == tid) {
thFound = th;
break;
}
}
return thFound;
}
int processJoinThread(struct process *proc, pid_t tid)
{
uint32_t flags;
struct thread *th;
int ret = -1;
disable_IRQs(flags);
th = processGetThread(proc, tid);
if (th && th->wqExit) {
wait(th->wqExit);
ret = 0;
}
restore_IRQs(flags);
return ret;
}

View File

@ -22,3 +22,4 @@ struct uAddrSpace *processGetAddrSpace(struct process *proc);
int processInitHeap(struct process *proc, uaddr_t lastUserAddr);
pid_t processGetId(struct process *proc);
pid_t processGetNextTid(struct process *proc);
int processJoinThread(struct process *proc, pid_t tid);

View File

@ -172,11 +172,20 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
break;
}
case SYSCALL_ID_GETPID: {
ret = processGetId(getCurrentThread()->process);
ret = processGetId(getCurrentThread()->process);
break;
}
case SYSCALL_ID_GETTID: {
ret = threadGetId(getCurrentThread());
ret = threadGetId(getCurrentThread());
break;
}
case SYSCALL_ID_THREAD_JOIN: {
thread_id_t tid;
ret = syscallGet1arg(userCtx, (unsigned int *)&tid);
if (ret)
break;
ret = processJoinThread(getCurrentThread()->process, tid);
break;
}
default:

View File

@ -15,6 +15,7 @@
#define SYSCALL_ID_USLEEP 10
#define SYSCALL_ID_GETPID 11
#define SYSCALL_ID_GETTID 12
#define SYSCALL_ID_THREAD_JOIN 13
#ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -89,8 +89,9 @@ struct thread *threadCreate(const char *name, cpu_kstate_function_arg1_t func, v
(cpu_kstate_function_arg1_t *)threadExit, 0))
goto free_mem;
thread->state = READY;
thread->tid = nextTid++;
thread->state = READY;
thread->tid = nextTid++;
thread->wqExit = NULL;
uint32_t flags;
disable_IRQs(flags);
list_add_tail(currentThread, thread);
@ -117,6 +118,14 @@ struct thread *threadCreateUser(const char *name, struct process *proc, uaddr_t
}
thread->stackSize = THREAD_DEFAULT_STACK_SIZE;
thread->wqExit = (struct wait_queue * )malloc(sizeof(struct wait_queue));
if (!thread->wqExit) {
free((void *)thread->stackAddr);
free(thread);
return NULL;
}
waitQueueInit(thread->wqExit);
if (name)
strzcpy(thread->name, name, THREAD_NAME_MAX_LENGTH);
else
@ -151,6 +160,10 @@ void threadDelete(struct thread *thread)
restore_IRQs(flags);
assert(thread->state == EXITING);
if (thread->wqExit) {
waitUp(thread->wqExit);
}
if (thread->squattedContext) {
threadChangeCurrentContext(NULL);
}

View File

@ -4,6 +4,7 @@ struct thread;
#include "cpu_context.h"
#include "mem.h"
#include "process.h"
#include "wait.h"
#define THREAD_NAME_MAX_LENGTH 32
#define THREAD_DEFAULT_STACK_SIZE PAGE_SIZE
@ -35,6 +36,7 @@ struct thread {
// For User thread only
struct thread *nextInProcess, *prevInProcess;
struct process *process;
struct wait_queue *wqExit; // This will be signaled at thread exit (user only)
/**
* Address space currently "squatted" by the thread, or used to be

View File

@ -15,6 +15,7 @@
#define SYSCALL_ID_USLEEP 10
#define SYSCALL_ID_GETPID 11
#define SYSCALL_ID_GETTID 12
#define SYSCALL_ID_THREAD_JOIN 13
#ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -807,6 +807,12 @@ int thread_create(pthread_t *thread, start_routine *func, void *arg, size_t stac
(unsigned int)arg, stackSize);
}
int thread_join(pthread_t thread, void **retval){
(void)retval;
return syscall1(SYSCALL_ID_THREAD_JOIN, (unsigned int)thread);
}
int usleep(useconds_t usec) {
return syscall1(SYSCALL_ID_USLEEP, (unsigned int)usec);
}

View File

@ -124,14 +124,15 @@ int func_munmap()
static void *print_hello(void *arg) {
(void)arg;
printf("Hello World from thread %lu\n", gettid());
usleep(100);
return NULL;
}
int func_thread() {
pthread_t id;
void *retval;
thread_create(&id, print_hello, NULL, 4096);
thread_join(id, &retval);
return 0;
}
@ -163,7 +164,10 @@ int main(int argc, char *argv[]) {
continue;
}
if (strcmp(buf, "tiny") == 0) {
func_tiny();
pthread_t id;
void *retval;
thread_create(&id, func_tiny, NULL, 4096);
thread_join(id, &retval);
continue;
}
if (strcmp(buf, "mmap") == 0) {

View File

@ -4,3 +4,5 @@
typedef unsigned long int pthread_t;
typedef void *(start_routine)(void *);
int thread_create(pthread_t *thread, start_routine *func, void *arg, size_t stackSize);
/* retval is ignored ATM */
int thread_join(pthread_t thread, void **retval);

View File

@ -282,8 +282,9 @@ void run()
/* Main program. */
int func_tiny()
void * func_tiny(void *args)
{
(void)args;
printf("Enter your program then ESC\n\n");
printf("TinyC grammar\n");
printf("<program> ::= <statement>\n");

View File

@ -1,4 +1,4 @@
#pragma once
int func_tiny();
void * func_tiny(void *args);