• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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