summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorgeniusgogo <[email protected]>2023-05-23 22:43:38 +0800
committerGitHub <[email protected]>2023-05-23 22:43:38 +0800
commit0315c0dee76ce67e3659744d4d280659e0a13906 (patch)
tree1329fed384811bf8c22165cc3be597c48bf099af /components
parent17ce4a462bd388edfd9e7dd995084276a5ff8336 (diff)
add lstat&sysinfo....syscall. (#7555)
Diffstat (limited to 'components')
-rw-r--r--components/lwp/lwp_syscall.c203
-rw-r--r--components/mm/mm_page.c27
-rw-r--r--components/mm/mm_page.h2
3 files changed, 231 insertions, 1 deletions
diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c
index 8f65f606ef..e33ca0ea9e 100644
--- a/components/lwp/lwp_syscall.c
+++ b/components/lwp/lwp_syscall.c
@@ -76,6 +76,8 @@
#include "lwp_ipc_internal.h"
#include <sched.h>
+#include <sys/sysinfo.h>
+
#ifndef GRND_NONBLOCK
#define GRND_NONBLOCK 0x0001
#endif /* GRND_NONBLOCK */
@@ -2621,6 +2623,54 @@ sysret_t sys_stat(const char *file, struct stat *buf)
return ret;
}
+sysret_t sys_lstat(const char *file, struct stat *buf)
+{
+ int ret = 0;
+ int err;
+ size_t len;
+ size_t copy_len;
+ char *copy_path;
+ struct stat statbuff = {0};
+
+ if (!lwp_user_accessable((void *)buf, sizeof(struct stat)))
+ {
+ return -EFAULT;
+ }
+
+ len = lwp_user_strlen(file, &err);
+ if (err)
+ {
+ return -EFAULT;
+ }
+
+ copy_path = (char*)rt_malloc(len + 1);
+ if (!copy_path)
+ {
+ return -ENOMEM;
+ }
+
+ copy_len = lwp_get_from_user(copy_path, (void*)file, len);
+ if (copy_len == 0)
+ {
+ rt_free(copy_path);
+ return -EFAULT;
+ }
+ copy_path[copy_len] = '\0';
+#ifdef RT_USING_DFS_V2
+ ret = _SYS_WRAP(dfs_file_lstat(copy_path, &statbuff));
+#else
+ ret = _SYS_WRAP(stat(copy_path, &statbuff));
+#endif
+ rt_free(copy_path);
+
+ if (ret == 0)
+ {
+ lwp_put_to_user(buf, &statbuff, sizeof statbuff);
+ }
+
+ return ret;
+}
+
sysret_t sys_notimpl(void)
{
return -ENOSYS;
@@ -4292,6 +4342,99 @@ sysret_t sys_setaffinity(pid_t pid, size_t size, void *set)
return -1;
}
+sysret_t sys_getaffinity(pid_t pid, size_t size, void *set)
+{
+#ifdef ARCH_MM_MMU
+ cpu_set_t mask;
+ struct rt_lwp *lwp;
+
+ if (size <= 0 || size > sizeof(cpu_set_t))
+ {
+ return -EINVAL;
+ }
+ if (!lwp_user_accessable(set, size))
+ {
+ return -EFAULT;
+ }
+
+ if (pid == 0) lwp = lwp_self();
+ else lwp = lwp_from_pid(pid);
+ if (!lwp)
+ {
+ return -ESRCH;
+ }
+
+#ifdef RT_USING_SMP
+ if (lwp->bind_cpu == RT_CPUS_NR) /* not bind */
+ {
+ CPU_ZERO_S(size, &mask);
+ }
+ else /* set bind cpu */
+ {
+ /* TODO: only single-core bindings are now supported of rt-smart */
+ CPU_SET_S(lwp->bind_cpu, size, &mask);
+ }
+#else
+ CPU_SET_S(0, size, &mask);
+#endif
+
+ if (lwp_put_to_user(set, &mask, size) != size)
+ {
+ return -1;
+ }
+
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+sysret_t sys_sysinfo(void *info)
+{
+#ifdef ARCH_MM_MMU
+ struct sysinfo kinfo = {0};
+ rt_size_t total_pages = 0, free_pages = 0;
+
+ if (!lwp_user_accessable(info, sizeof(struct sysinfo)))
+ {
+ return -EFAULT;
+ }
+
+ kinfo.uptime = rt_tick_get_millisecond() / 1000;
+ /* TODO: 1, 5, and 15 minute load averages */
+ kinfo.loads[0] = kinfo.loads[1] = kinfo.loads[2] = rt_object_get_length(RT_Object_Class_Thread);
+ rt_page_get_info(&total_pages, &free_pages);
+ kinfo.totalram = total_pages;
+ kinfo.freeram = free_pages;
+
+ /* TODO: implementation procfs, here is counter the lwp number */
+ struct lwp_avl_struct *pids = lwp_get_pid_ary();
+ for (int index = 0; index < RT_LWP_MAX_NR; index++)
+ {
+ struct rt_lwp *lwp = (struct rt_lwp *)pids[index].data;
+
+ if (lwp)
+ {
+ kinfo.procs++;
+ }
+ }
+
+ rt_page_high_get_info(&total_pages, &free_pages);
+ kinfo.totalhigh = total_pages;
+ kinfo.freehigh = free_pages;
+ kinfo.mem_unit = ARCH_PAGE_SIZE;
+
+ if (lwp_put_to_user(info, &kinfo, sizeof(struct sysinfo)) != sizeof(struct sysinfo))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+#else
+ return -1;
+#endif
+}
+
sysret_t sys_sched_setparam(pid_t pid, void *param)
{
struct sched_param *sched_param = (struct sched_param *)param;
@@ -4901,6 +5044,60 @@ sysret_t sys_umount2(char *__special_file, int __flags)
return ret;
}
+sysret_t sys_link(const char *existing, const char *new)
+{
+ int ret = -1;
+
+#ifdef ARCH_MM_MMU
+ int err;
+
+ lwp_user_strlen(existing, &err);
+ if (err)
+ {
+ return -EFAULT;
+ }
+
+ lwp_user_strlen(new, &err);
+ if (err)
+ {
+ return -EFAULT;
+ }
+#endif
+#ifdef RT_USING_DFS_V2
+ ret = dfs_file_link(existing, new);
+#else
+ SET_ERRNO(EFAULT);
+#endif
+ return (ret < 0 ? GET_ERRNO() : ret);
+}
+
+sysret_t sys_symlink(const char *existing, const char *new)
+{
+ int ret = -1;
+
+#ifdef ARCH_MM_MMU
+ int err;
+
+ lwp_user_strlen(existing, &err);
+ if (err)
+ {
+ return -EFAULT;
+ }
+
+ lwp_user_strlen(new, &err);
+ if (err)
+ {
+ return -EFAULT;
+ }
+#endif
+#ifdef RT_USING_DFS_V2
+ ret = dfs_file_symlink(existing, new);
+#else
+ SET_ERRNO(EFAULT);
+#endif
+ return (ret < 0 ? GET_ERRNO() : ret);
+}
+
const static struct rt_syscall_def func_table[] =
{
SYSCALL_SIGN(sys_exit), /* 01 */
@@ -5110,7 +5307,7 @@ const static struct rt_syscall_def func_table[] =
SYSCALL_SIGN(sys_mq_notify),
SYSCALL_SIGN(sys_mq_getsetattr),
SYSCALL_SIGN(sys_mq_close),
- SYSCALL_SIGN(sys_stat), //TODO should be replaced by sys_lstat if symbolic link are implemented
+ SYSCALL_SIGN(sys_lstat),
SYSCALL_SIGN(sys_uname), /* 170 */
SYSCALL_SIGN(sys_statfs),
SYSCALL_SIGN(sys_statfs64),
@@ -5119,6 +5316,10 @@ const static struct rt_syscall_def func_table[] =
SYSCALL_SIGN(sys_openat), /* 175 */
SYSCALL_SIGN(sys_mount),
SYSCALL_SIGN(sys_umount2),
+ SYSCALL_SIGN(sys_link),
+ SYSCALL_SIGN(sys_symlink),
+ SYSCALL_SIGN(sys_getaffinity), /* 180 */
+ SYSCALL_SIGN(sys_sysinfo),
};
const void *lwp_get_sys_api(rt_uint32_t number)
diff --git a/components/mm/mm_page.c b/components/mm/mm_page.c
index 9b3fdf74e7..f72083a9d3 100644
--- a/components/mm/mm_page.c
+++ b/components/mm/mm_page.c
@@ -46,6 +46,7 @@ static struct rt_page *page_list_high[RT_PAGE_MAX_ORDER];
#define page_start ((rt_page_t)rt_mpr_start)
static rt_size_t page_nr;
+static rt_size_t _high_pages_nr;
static rt_size_t early_offset;
static const char *get_name(rt_varea_t varea)
@@ -672,6 +673,28 @@ void rt_page_get_info(rt_size_t *total_nr, rt_size_t *free_nr)
*free_nr = total_free;
}
+void rt_page_high_get_info(rt_size_t *total_nr, rt_size_t *free_nr)
+{
+ int i;
+ rt_size_t total_free = 0;
+ rt_base_t level;
+
+ level = rt_hw_interrupt_disable();
+ for (i = 0; i < RT_PAGE_MAX_ORDER; i++)
+ {
+ struct rt_page *p = page_list_high[i];
+
+ while (p)
+ {
+ total_free += (1UL << i);
+ p = p->next;
+ }
+ }
+ rt_hw_interrupt_enable(level);
+ *total_nr = _high_pages_nr;
+ *free_nr = total_free;
+}
+
static void _install_page(rt_page_t mpr_head, rt_region_t region, void *insert_handler)
{
void (*insert)(rt_page_t *page_list, rt_page_t page, int size_bits) = insert_handler;
@@ -723,6 +746,10 @@ static void _install_page(rt_page_t mpr_head, rt_region_t region, void *insert_h
/* insert to list */
rt_page_t *page_list = _get_page_list((void *)region.start);
+ if (page_list == page_list_high)
+ {
+ _high_pages_nr += 1 << (size_bits - ARCH_PAGE_SHIFT);
+ }
insert(page_list, (rt_page_t)((char *)p - early_offset), size_bits - ARCH_PAGE_SHIFT);
region.start += (1UL << size_bits);
}
diff --git a/components/mm/mm_page.h b/components/mm/mm_page.h
index 4ced90f9aa..e5386640dc 100644
--- a/components/mm/mm_page.h
+++ b/components/mm/mm_page.h
@@ -88,6 +88,8 @@ rt_size_t rt_page_bits(rt_size_t size);
void rt_page_get_info(rt_size_t *total_nr, rt_size_t *free_nr);
+void rt_page_high_get_info(rt_size_t *total_nr, rt_size_t *free_nr);
+
void *rt_page_page2addr(struct rt_page *p);
struct rt_page *rt_page_addr2page(void *addr);