Skip to content

Commit 142d958

Browse files
committed
Make coroutine_finish private and never free any memory
The memory is going to be deallocated by the OS anyway. We already reuse the memory of dead coroutines anyway. Not care about deallocation greatly simplifies the code.
1 parent d75bcbd commit 142d958

File tree

8 files changed

+19
-47
lines changed

8 files changed

+19
-47
lines changed

coroutine.c

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -198,31 +198,18 @@ void coroutine_switch_context(void *rsp, Sleep_Mode sm, int fd)
198198
coroutine_restore_context(contexts.items[active.items[current]].rsp);
199199
}
200200

201+
// TODO: think how to get rid of coroutine_init() call at all
201202
void coroutine_init(void)
202203
{
203204
if (contexts.count != 0) return;
204205
da_append(&contexts, (Context){0});
205206
da_append(&active, 0);
206207
}
207208

208-
void coroutine_finish(void)
209+
void coroutine__finish_current(void)
209210
{
210-
if (contexts.count == 0) return;
211211
if (active.items[current] == 0) {
212-
for (size_t i = 1; i < contexts.count; ++i) {
213-
munmap(contexts.items[i].stack_base, STACK_CAPACITY);
214-
}
215-
free(contexts.items);
216-
free(active.items);
217-
free(dead.items);
218-
free(polls.items);
219-
free(asleep.items);
220-
memset(&contexts, 0, sizeof(contexts));
221-
memset(&active, 0, sizeof(active));
222-
memset(&dead, 0, sizeof(dead));
223-
memset(&polls, 0, sizeof(polls));
224-
memset(&asleep, 0, sizeof(asleep));
225-
return;
212+
UNREACHABLE("Main Coroutine with id == 0 should never reach this place");
226213
}
227214

228215
da_append(&dead, active.items[current]);
@@ -264,7 +251,7 @@ void coroutine_go(void (*f)(void*), void *arg)
264251

265252
void **rsp = (void**)((char*)contexts.items[id].stack_base + STACK_CAPACITY);
266253
// @arch
267-
*(--rsp) = coroutine_finish;
254+
*(--rsp) = coroutine__finish_current;
268255
*(--rsp) = f;
269256
*(--rsp) = arg; // push rdi
270257
*(--rsp) = 0; // push rbx

coroutine.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@ extern "C" {
3737
// TODO: Allow calling it twice, 'cause why not?!
3838
void coroutine_init(void);
3939

40-
// Finish the currently running coroutine. When called in the main coroutine
41-
// with id = 0 uninitializes the whole runtime of the library, deallocating all
42-
// the memory, and killing all the currently running coroutines.
43-
void coroutine_finish(void);
44-
4540
// Switch to the next coroutine. The execution will continue starting from
4641
// coroutine_yield() (or any other flavor of it like coroutine_sleep_read() or
4742
// coroutine_sleep_write) call of another coroutine.

examples/counter.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ void counter(void *arg)
1717
int main()
1818
{
1919
coroutine_init();
20-
coroutine_go(&counter, (void*)5);
21-
coroutine_go(&counter, (void*)10);
22-
while (coroutine_alive() > 1) coroutine_yield();
23-
coroutine_finish();
20+
coroutine_go(&counter, (void*)5);
21+
coroutine_go(&counter, (void*)10);
22+
while (coroutine_alive() > 1) coroutine_yield();
2423
return 0;
2524
}

examples/counter.c3

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ fn void counter(void* arg) {
1313

1414
fn void main() {
1515
coroutine::init();
16-
defer coroutine::finish();
1716
coroutine::go(fn void(void *arg) {
18-
io::printfn("[%d], Hello from C3 Lambda", coroutine::id());
17+
io::printfn("[%d] Hello from C3 Lambda", coroutine::id());
1918
});
2019
coroutine::go(&counter, (void*)5);
2120
coroutine::go(&counter, (void*)10);

examples/counter.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,5 @@ int main()
2020
coroutine_go(counter, reinterpret_cast<void*>(5));
2121
coroutine_go(counter, reinterpret_cast<void*>(10));
2222
while (coroutine_alive() > 1) coroutine_yield();
23-
coroutine_finish();
2423
return 0;
2524
}

examples/counter.jai

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ coroutine_sleep_read :: (fd: int) #foreign coroutine;
66
coroutine_sleep_write :: (fd: int) #foreign coroutine;
77
coroutine_wake_up :: (id: int) #foreign coroutine;
88
coroutine_init :: () #foreign coroutine;
9-
coroutine_finish :: () #foreign coroutine;
109
coroutine_yield :: () #foreign coroutine;
1110
coroutine_go :: (f: (*void) #c_call, arg: *void = null) #foreign coroutine;
1211
coroutine_id :: () -> int #foreign coroutine;
@@ -24,7 +23,6 @@ counter :: (arg: *void) #c_call {
2423

2524
main :: () {
2625
coroutine_init();
27-
defer coroutine_finish();
2826
coroutine_go((arg: *void) #c_call {
2927
push_context {
3028
print("[%] Hello from Jai Lambda\n", coroutine_id());
@@ -45,7 +43,6 @@ main :: () {
4543
});
4644

4745
coroutine_init();
48-
defer coroutine_finish();
4946
coroutine_go((arg: *void) #c_call {
5047
push_context {
5148
for 0..5 {

examples/echo.c3

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ usz server_id = 0;
99

1010
fn void main() {
1111
coroutine::init();
12-
defer coroutine::finish();
1312

1413
server_id = coroutine::id();
1514

examples/lexer.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,20 @@ int main(int argc, char* argv[]){
6363
}
6464

6565
coroutine_init();
66-
{
67-
coroutine_go(lex, argv[1]);
66+
coroutine_go(lex, argv[1]);
6867

69-
// Consume those tokens
70-
bool quit = false;
71-
while(!quit && coroutine_alive() > 1){
72-
// Yield control to the lexer.
73-
// It will lex and yield control back to here.
74-
coroutine_yield();
75-
switch(token_kind){
76-
case TK_INT: { printf("TK_INT: %d\n", token_value.tk_int); } break;
77-
case TK_OP: { printf("TK_OP: %c\n", token_value.tk_op); } break;
78-
default: { printf("Done!\n"); quit = true; } break;
79-
}
68+
// Consume those tokens
69+
bool quit = false;
70+
while(!quit && coroutine_alive() > 1){
71+
// Yield control to the lexer.
72+
// It will lex and yield control back to here.
73+
coroutine_yield();
74+
switch(token_kind){
75+
case TK_INT: { printf("TK_INT: %d\n", token_value.tk_int); } break;
76+
case TK_OP: { printf("TK_OP: %c\n", token_value.tk_op); } break;
77+
default: { printf("Done!\n"); quit = true; } break;
8078
}
8179
}
82-
coroutine_finish();
8380

8481
return 0;
8582
}

0 commit comments

Comments
 (0)