Skip to content

Commit b53e21c

Browse files
committed
Improve await synchronization
1 parent 47df539 commit b53e21c

File tree

4 files changed

+33
-26
lines changed

4 files changed

+33
-26
lines changed

include/kernel/types.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,12 @@ typedef struct {
9696
} process_t;
9797

9898
typedef enum {
99-
THREAD_STATE_ZOMBIE,
99+
THREAD_STATE_CREATED,
100+
THREAD_STATE_STARTING,
100101
THREAD_STATE_READY,
101102
THREAD_STATE_RUNNING,
102-
THREAD_STATE_BLOCKED
103+
THREAD_STATE_BLOCKED,
104+
THREAD_STATE_ZOMBIE
103105
} thread_state_t;
104106

105107
struct thread_t {

kernel/application/syscalls/await_thread.c

+19-17
Original file line numberDiff line numberDiff line change
@@ -38,38 +38,27 @@
3838
#include <kernel/machine/spinlock.h>
3939
#include <kernel/machine/thread.h>
4040

41-
int await_thread(int fd) {
42-
descriptor_t desc;
43-
int status = dereference_object_descriptor(&desc, get_current_process(), fd);
44-
45-
if(status < 0) {
46-
return -JINUE_EBADF;
47-
}
48-
49-
thread_t *thread = get_thread_from_descriptor(&desc);
41+
static int with_thread_referenced(descriptor_t *thread_desc) {
42+
thread_t *thread = get_thread_from_descriptor(thread_desc);
5043

5144
if(thread == NULL) {
52-
unreference_descriptor_object(&desc);
5345
return -JINUE_EBADF;
5446
}
5547

56-
if(!descriptor_has_permissions(&desc, JINUE_PERM_AWAIT)) {
57-
unreference_descriptor_object(&desc);
48+
if(!descriptor_has_permissions(thread_desc, JINUE_PERM_AWAIT)) {
5849
return -JINUE_EPERM;
5950
}
6051

6152
thread_t *current = get_current_thread();
6253

6354
if(thread == current) {
64-
unreference_descriptor_object(&desc);
6555
return -JINUE_EDEADLK;
6656
}
6757

6858
spin_lock(&thread->await_lock);
6959

70-
if(thread->awaiter != NULL) {
60+
if(thread->state == THREAD_STATE_CREATED || thread->awaiter != NULL) {
7161
spin_unlock(&thread->await_lock);
72-
unreference_descriptor_object(&desc);
7362
return -JINUE_ESRCH;
7463
}
7564

@@ -81,7 +70,20 @@ int await_thread(int fd) {
8170
block_and_unlock(&thread->await_lock);
8271
}
8372

84-
unreference_descriptor_object(&desc);
85-
8673
return 0;
8774
}
75+
76+
int await_thread(int fd) {
77+
descriptor_t thread_desc;
78+
int status = dereference_object_descriptor(&thread_desc, get_current_process(), fd);
79+
80+
if(status < 0) {
81+
return -JINUE_EBADF;
82+
}
83+
84+
status = with_thread_referenced(&thread_desc);
85+
86+
unreference_descriptor_object(&thread_desc);
87+
88+
return status;
89+
}

kernel/application/syscalls/start_thread.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ int start_thread(int fd, const thread_params_t *params) {
5555
return -JINUE_EPERM;
5656
}
5757

58-
if(thread->state != THREAD_STATE_ZOMBIE) {
58+
if(thread->state != THREAD_STATE_CREATED && thread->state != THREAD_STATE_ZOMBIE) {
5959
unreference_descriptor_object(&desc);
6060
return -JINUE_EBUSY;
6161
}

kernel/domain/entities/thread.c

+9-6
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,9 @@ thread_t *construct_thread(process_t *process) {
8585
init_spinlock(&thread->await_lock);
8686
jinue_node_init(&thread->thread_list);
8787

88-
thread->state = THREAD_STATE_ZOMBIE;
88+
thread->state = THREAD_STATE_CREATED;
8989
thread->process = process;
90-
/* Arbitrary non-NULL value to signify the thread hasn't run yet and
91-
* shouldn't be awaited. This will fall in the condition in await_thread()
92-
* that detects an attempt to await a thread that has already been awaited,
93-
* so await_thread() will fail with JINUE_ESRCH. */
94-
thread->awaiter = thread;
90+
thread->awaiter = NULL;
9591
thread->local_storage_addr = NULL;
9692
thread->local_storage_size = 0;
9793

@@ -128,7 +124,14 @@ static void free_thread(object_header_t *object) {
128124
*/
129125
void prepare_thread(thread_t *thread, const thread_params_t *params) {
130126
thread->sender = NULL;
127+
128+
spin_lock(&thread->await_lock);
129+
131130
thread->awaiter = NULL;
131+
thread->state = THREAD_STATE_STARTING;
132+
133+
spin_unlock(&thread->await_lock);
134+
132135
machine_prepare_thread(thread, params);
133136
}
134137

0 commit comments

Comments
 (0)