[smart] fixup of lwp recycling and mm varea (#8206)

Signed-off-by: shell <wangxiaoyao@rt-thread.com>
Signed-off-by: Shell <smokewood@qq.com>
Co-authored-by: xqyjlj <xqyjlj@126.com>
This commit is contained in:
Shell
2023-11-02 20:23:11 +08:00
committed by GitHub
co-authored by xqyjlj
parent 1b6f0e88a3
commit c2036e769a
17 changed files with 464 additions and 297 deletions
-1
View File
@@ -35,7 +35,6 @@
#define PMUTEX_DESTROY 3
/* for sys/mman.h */
#define MAP_FAILED ((void *)-1)
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
+8 -2
View File
@@ -1157,6 +1157,10 @@ rt_err_t lwp_children_register(struct rt_lwp *parent, struct rt_lwp *child)
LWP_UNLOCK(parent);
LOG_D("%s(parent=%p, child=%p)", __func__, parent, child);
/* parent holds reference to child */
lwp_ref_inc(parent);
/* child holds reference to parent */
lwp_ref_inc(child);
return 0;
}
@@ -1178,6 +1182,8 @@ rt_err_t lwp_children_unregister(struct rt_lwp *parent, struct rt_lwp *child)
LWP_UNLOCK(parent);
LOG_D("%s(parent=%p, child=%p)", __func__, parent, child);
lwp_ref_dec(child);
lwp_ref_dec(parent);
return 0;
}
@@ -1195,7 +1201,7 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
if (filename == RT_NULL)
{
return -RT_ERROR;
return -EINVAL;
}
if (access(filename, X_OK) != 0)
@@ -1208,7 +1214,7 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
if (lwp == RT_NULL)
{
dbg_log(DBG_ERROR, "lwp struct out of memory!\n");
return -RT_ENOMEM;
return -ENOMEM;
}
LOG_D("lwp malloc : %p, size: %d!", lwp, sizeof(struct rt_lwp));
-1
View File
@@ -171,7 +171,6 @@ char *lwp_getcwd(void);
void lwp_request_thread_exit(rt_thread_t thread_to_exit);
int lwp_check_exit_request(void);
void lwp_terminate(struct rt_lwp *lwp);
void lwp_wait_subthread_exit(void);
int lwp_tid_init(void);
int lwp_tid_get(void);
+300 -113
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -85,6 +85,9 @@ rt_inline void lwp_from_pid_release_lock(struct rt_lwp *lwp)
lwp_ref_dec(lwp);
}
void lwp_thread_exit(rt_thread_t thread, rt_base_t status);
void lwp_exit(struct rt_lwp *lwp, rt_base_t status);
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -298,12 +298,12 @@ static int _pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout)
lwp_mutex_release_safe(&_pmutex_lock);
return -EDEADLK;
}
lwp_mutex_release_safe(&_pmutex_lock);
lock_ret = rt_mutex_take_interruptible(pmutex->lock.kmutex, time);
if (lock_ret == RT_EOK)
{
umutex_p->_m_lock = rt_thread_self()->tid;
}
lwp_mutex_release_safe(&_pmutex_lock);
break;
default: /* unknown type */
return -EINVAL;
-1
View File
@@ -764,7 +764,6 @@ rt_err_t lwp_signal_action(struct rt_lwp *lwp, int signo,
rt_list_t *thread_list;
rt_err_t ret = RT_EOK;
if (lwp)
{
/** acquire READ access to lwp */
+52 -95
View File
@@ -328,104 +328,35 @@ static void _crt_thread_entry(void *parameter)
/* exit group */
sysret_t sys_exit_group(int value)
{
rt_thread_t tid, main_thread;
struct rt_lwp *lwp;
sysret_t rc = 0;
struct rt_lwp *lwp = lwp_self();
tid = rt_thread_self();
lwp = (struct rt_lwp *)tid->lwp;
LOG_D("process(%p) exit.", lwp);
#ifdef ARCH_MM_MMU
if (tid->clear_child_tid)
if (lwp)
lwp_exit(lwp, value);
else
{
int t = 0;
int *clear_child_tid = tid->clear_child_tid;
tid->clear_child_tid = RT_NULL;
lwp_put_to_user(clear_child_tid, &t, sizeof t);
sys_futex(clear_child_tid, FUTEX_WAKE | FUTEX_PRIVATE, 1, RT_NULL, RT_NULL, 0);
LOG_E("Can't find matching process of current thread");
rc = -EINVAL;
}
lwp_terminate(lwp);
main_thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);
if (main_thread == tid)
{
lwp_wait_subthread_exit();
lwp->lwp_ret = LWP_CREATE_STAT(value);
}
#else
main_thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);
if (main_thread == tid)
{
rt_thread_t sub_thread;
rt_list_t *list;
lwp_terminate(lwp);
/* delete all subthread */
while ((list = tid->sibling.prev) != &lwp->t_grp)
{
sub_thread = rt_list_entry(list, struct rt_thread, sibling);
rt_list_remove(&sub_thread->sibling);
rt_thread_delete(sub_thread);
}
lwp->lwp_ret = value;
}
#endif /* ARCH_MM_MMU */
/**
* Note: the tid tree always hold a reference to thread, hence the tid must
* be release before cleanup of thread
*/
lwp_tid_put(tid->tid);
tid->tid = 0;
rt_list_remove(&tid->sibling);
rt_thread_delete(tid);
rt_schedule();
/* never reach here */
RT_ASSERT(0);
return 0;
return rc;
}
/* thread exit */
void sys_exit(int status)
sysret_t sys_exit(int status)
{
rt_thread_t tid, main_thread;
struct rt_lwp *lwp;
LOG_D("thread exit");
sysret_t rc = 0;
rt_thread_t tid;
tid = rt_thread_self();
lwp = (struct rt_lwp *)tid->lwp;
#ifdef ARCH_MM_MMU
if (tid->clear_child_tid)
if (tid && tid->lwp)
lwp_thread_exit(tid, status);
{
int t = 0;
int *clear_child_tid = tid->clear_child_tid;
tid->clear_child_tid = RT_NULL;
lwp_put_to_user(clear_child_tid, &t, sizeof t);
sys_futex(clear_child_tid, FUTEX_WAKE, 1, RT_NULL, RT_NULL, 0);
LOG_E("Can't find matching process of current thread");
rc = -EINVAL;
}
main_thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);
if (main_thread == tid && tid->sibling.prev == &lwp->t_grp)
{
lwp_terminate(lwp);
lwp_wait_subthread_exit();
lwp->lwp_ret = LWP_CREATE_STAT(status);
}
#endif /* ARCH_MM_MMU */
lwp_tid_put(tid->tid);
tid->tid = 0;
rt_list_remove(&tid->sibling);
rt_thread_delete(tid);
rt_schedule();
return;
return rc;
}
/* syscall: "read" ret: "ssize_t" args: "int" "void *" "size_t" */
@@ -1174,18 +1105,28 @@ sysret_t sys_getpid(void)
/* syscall: "getpriority" ret: "int" args: "int" "id_t" */
sysret_t sys_getpriority(int which, id_t who)
{
long prio = 0xff;
if (which == PRIO_PROCESS)
{
rt_thread_t tid;
struct rt_lwp *lwp = RT_NULL;
tid = rt_thread_self();
if (who == (id_t)(rt_size_t)tid || who == 0xff)
lwp_pid_lock_take();
if(who == 0)
lwp = lwp_self();
else
lwp = lwp_from_pid_locked(who);
if (lwp)
{
return tid->current_priority;
rt_thread_t thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);
prio = thread->current_priority;
}
lwp_pid_lock_release();
}
return 0xff;
return prio;
}
/* syscall: "setpriority" ret: "int" args: "int" "id_t" "int" */
@@ -1193,14 +1134,30 @@ sysret_t sys_setpriority(int which, id_t who, int prio)
{
if (which == PRIO_PROCESS)
{
rt_thread_t tid;
struct rt_lwp *lwp = RT_NULL;
tid = rt_thread_self();
if ((who == (id_t)(rt_size_t)tid || who == 0xff) && (prio >= 0 && prio < RT_THREAD_PRIORITY_MAX))
lwp_pid_lock_take();
if(who == 0)
lwp = lwp_self();
else
lwp = lwp_from_pid_locked(who);
if (lwp && prio >= 0 && prio < RT_THREAD_PRIORITY_MAX)
{
rt_thread_control(tid, RT_THREAD_CTRL_CHANGE_PRIORITY, &prio);
rt_list_t *list;
rt_thread_t thread;
for (list = lwp->t_grp.next; list != &lwp->t_grp; list = list->next)
{
thread = rt_list_entry(list, struct rt_thread, sibling);
rt_thread_control(thread, RT_THREAD_CTRL_CHANGE_PRIORITY, &prio);
}
lwp_pid_lock_release();
return 0;
}
else
{
lwp_pid_lock_release();
}
}
return -1;
@@ -2790,6 +2747,7 @@ sysret_t sys_execve(const char *path, char *const argv[], char *const envp[])
* Since no other threads can access the lwp field, it't uneccessary to
* take a lock here
*/
RT_ASSERT(rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling) == thread);
strncpy(thread->parent.name, run_name + last_backslash, RT_NAME_MAX);
strncpy(lwp->cmd, new_lwp->cmd, RT_NAME_MAX);
@@ -5560,7 +5518,6 @@ sysret_t sys_sched_getscheduler(int tid, int *policy, void *param)
struct sched_param *sched_param = RT_NULL;
rt_thread_t thread = RT_NULL;
if (!lwp_user_accessable(param, sizeof(struct sched_param)))
{
return -EFAULT;
+1 -1
View File
@@ -48,7 +48,7 @@ typedef uint32_t id_t; /* may contain pid, uid or gid */
const char *lwp_get_syscall_name(rt_uint32_t number);
const void *lwp_get_sys_api(rt_uint32_t number);
void sys_exit(int value);
sysret_t sys_exit(int value);
sysret_t sys_exit_group(int status);
ssize_t sys_read(int fd, void *buf, size_t nbyte);
ssize_t sys_write(int fd, const void *buf, size_t nbyte);