Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring: thread_await() #87

Merged
merged 2 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/kernel/domain/entities/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ void thread_run_first(thread_t *thread);

void thread_run(thread_t *thread);

void thread_yield_current(void);

void thread_terminate_current(void);

void thread_switch_to(thread_t *to);
Expand All @@ -58,7 +60,7 @@ void thread_switch_to_and_block(thread_t *to);

void thread_block_current_and_unlock(spinlock_t *lock);

void thread_yield_current(void);
int thread_await(thread_t *thread);

void thread_set_local_storage(thread_t *thread, addr_t addr, size_t size);

Expand Down
23 changes: 1 addition & 22 deletions kernel/application/syscalls/await_thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,28 +49,7 @@ static int with_thread(descriptor_t *thread_desc) {
return -JINUE_EPERM;
}

thread_t *current = get_current_thread();

if(thread == current) {
return -JINUE_EDEADLK;
}

spin_lock(&thread->await_lock);

if(thread->state == THREAD_STATE_CREATED || thread->awaiter != NULL) {
spin_unlock(&thread->await_lock);
return -JINUE_ESRCH;
}

thread->awaiter = current;

if(thread->state == THREAD_STATE_ZOMBIE) {
spin_unlock(&thread->await_lock);
} else {
thread_block_current_and_unlock(&thread->await_lock);
}

return 0;
return thread_await(thread);
}

int await_thread(int fd) {
Expand Down
61 changes: 47 additions & 14 deletions kernel/domain/entities/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <jinue/shared/asm/errno.h>
#include <kernel/domain/alloc/page_alloc.h>
#include <kernel/domain/entities/descriptor.h>
#include <kernel/domain/entities/object.h>
Expand Down Expand Up @@ -270,6 +271,33 @@ static thread_t *reschedule(bool current_can_run) {
return to;
}

/**
* Yield the current thread
*
* The current thread is added at the tail of the ready queue. It continues
* running if no other thread is ready to run.
*/
void thread_yield_current(void) {
thread_t *current = get_current_thread();
thread_t *to = reschedule(true);

if(to == current) {
return;
}

to->state = THREAD_STATE_RUNNING;

if(current->process != to->process) {
process_switch_to(to->process);
}

spin_lock(&ready_queue.lock);

thread_ready_locked(current);

machine_switch_thread_and_unlock(current, to, &ready_queue.lock);
}

/**
* Terminate the current thread
*
Expand Down Expand Up @@ -388,30 +416,35 @@ void thread_block_current_and_unlock(spinlock_t *lock) {
}

/**
* Yield the current thread
* Block until thread terminates
*
* The current thread is added at the tail of the ready queue. It continues
* running if no other thread is ready to run.
* @param thread awaited thread
* @return zero on success, negated error code on failure
*
*/
void thread_yield_current(void) {
thread_t *current = get_current_thread();
thread_t *to = reschedule(true);
int thread_await(thread_t *thread) {
thread_t *current = get_current_thread();

if(to == current) {
return;
if(thread == current) {
return -JINUE_EDEADLK;
}

to->state = THREAD_STATE_RUNNING;
spin_lock(&thread->await_lock);

if(current->process != to->process) {
process_switch_to(to->process);
if(thread->state == THREAD_STATE_CREATED || thread->awaiter != NULL) {
spin_unlock(&thread->await_lock);
return -JINUE_ESRCH;
}

spin_lock(&ready_queue.lock);
thread->awaiter = current;

thread_ready_locked(current);
if(thread->state == THREAD_STATE_ZOMBIE) {
spin_unlock(&thread->await_lock);
} else {
thread_block_current_and_unlock(&thread->await_lock);
}

machine_switch_thread_and_unlock(current, to, &ready_queue.lock);
return 0;
}

/**
Expand Down