1 /*
2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include <errno.h>
13 #include <string.h>
14 #include <sys/mman.h>
15 #include <chcore/ipc.h>
16 #include <chcore/proc.h>
17 #include <chcore/syscall.h>
18 #include <chcore-internal/procmgr_defs.h>
19 #include <chcore/ring_buffer.h>
20
21 #include "proc_node.h"
22 #include "procmgr_dbg.h"
23
24 pthread_mutex_t recycle_lock;
25
26 /* A recycle_msg is set by the kernel when one process needs to
27 * be recycled.
28 */
29 struct recycle_msg {
30 badge_t badge;
31 int exitcode;
32 int padding;
33 };
34
35 struct ring_buffer *recycle_msg_buffer = NULL;
36 #define MAX_MSG_NUM 100
37
38 int usys_cap_group_recycle(int);
39
recycle_routine(void * arg)40 void *recycle_routine(void *arg)
41 {
42 cap_t notific_cap;
43 int ret;
44
45 struct recycle_msg msg;
46 struct proc_node *proc_to_recycle;
47
48 /* Recycle_thread will wait on this notification */
49 notific_cap = usys_create_notifc();
50
51 /* The msg on recycling which process is in msg_buffer */
52 recycle_msg_buffer =
53 new_ringbuffer(MAX_MSG_NUM, sizeof(struct recycle_msg));
54 assert(recycle_msg_buffer);
55
56 ret =
57 usys_register_recycle_thread(notific_cap, (vaddr_t)recycle_msg_buffer);
58 assert(ret == 0);
59
60 usys_set_prio(-0, 2);
61 sched_yield();
62
63 while (1) {
64 usys_wait(notific_cap, 1 /* Block */, NULL /* No timeout */);
65 while (get_one_msg(recycle_msg_buffer, &msg)) {
66 proc_to_recycle = get_proc_node(msg.badge);
67 assert(proc_to_recycle != 0);
68
69 pthread_mutex_lock(&recycle_lock);
70 proc_to_recycle->exitstatus = msg.exitcode;
71 /*
72 * chcore_waitpid() will block until the state of
73 * corresponding process is set as PROC_STATE_EXIT.
74 */
75 pthread_mutex_lock(&proc_to_recycle->wait_lock);
76 proc_to_recycle->state = PROC_STATE_EXIT;
77 pthread_cond_broadcast(&proc_to_recycle->wait_cv);
78 pthread_mutex_unlock(&proc_to_recycle->wait_lock);
79
80 do {
81 ret = usys_cap_group_recycle(proc_to_recycle->proc_cap);
82 if (ret == -EAGAIN)
83 sched_yield();
84 } while (ret == -EAGAIN);
85
86 /*
87 * Since de_proc_node will free the pcid/asid,
88 * it is necessary to ensure the tlbs of the id
89 * has been flushed.
90 * Currently, this can be ensured when the recycle is done.
91 */
92
93 del_proc_node(proc_to_recycle);
94 pthread_mutex_unlock(&recycle_lock);
95 }
96 }
97 }
98