diff --git a/kern/src/ec.cc b/kern/src/ec.cc index 7a5b1fa..899993e 100644 --- a/kern/src/ec.cc +++ b/kern/src/ec.cc @@ -284,8 +284,20 @@ void Ec::sys_call() printf("EC:%p SYS_CALL (PT=%u)\n", current, pt->id); - // TODO copy message if ready and switch - FAIL; + Ec *recv = pt->recv; + + if (recv->state == WAITING) { + current->cont = ret_user_sysexit; + current->state = BLOCKED; + recv->cont = recv_user; + recv->caller = current; + recv->state = READY; + recv->sys_regs()->set_ip(pt->rip); + recv->make_current(); + } + + current->cont = sys_call; + schedule(); } void Ec::sys_reply() @@ -295,8 +307,14 @@ void Ec::sys_reply() printf("EC:%p SYS_REPLY\n", current); - // TODO copy message and switch back - FAIL; + Ec *caller = current->caller; + + current->caller = nullptr; + current->state = WAITING; + memcpy(caller->utcb, current->utcb, PAGE_SIZE); + + caller->state = READY; + caller->make_current(); } void Ec::recv_user() diff --git a/user/src/user.cc b/user/src/user.cc index d4f247a..143782a 100644 --- a/user/src/user.cc +++ b/user/src/user.cc @@ -65,18 +65,21 @@ void sys_reply() [[noreturn]] void sender() { - // TODO perform sys_call() in a loop - // TODO use dump to print out values - while (1) - ; + unsigned long *words = UTCB_SENDER; + words[0] = 1; + words[1] = 2; + while (1) { + sys_call(0); + sys_dump(words[0], words[1]); + } } [[noreturn]] void portal() { - // TODO handle single request and reply - while (1) - sys_yield(); + unsigned long *words = UTCB_RECEIVER; + words[0] += words[1]; + sys_reply(); } extern "C" [[noreturn]] @@ -88,7 +91,7 @@ void main_func() sys_create_ec(sender, stack + 64 * 1, UTCB_SENDER); // receiver thread sys_create_ec(0, stack + 64 * 2, UTCB_RECEIVER); - // TODO create portal + sys_create_pt(0, portal, UTCB_RECEIVER); while (1) sys_yield();