1
0
Эх сурвалжийг харах

add lstat&sysinfo....syscall. (#7555)

geniusgogo 1 жил өмнө
parent
commit
0315c0dee7

+ 202 - 1
components/lwp/lwp_syscall.c

@@ -76,6 +76,8 @@
 #include "lwp_ipc_internal.h"
 #include "lwp_ipc_internal.h"
 #include <sched.h>
 #include <sched.h>
 
 
+#include <sys/sysinfo.h>
+
 #ifndef GRND_NONBLOCK
 #ifndef GRND_NONBLOCK
 #define GRND_NONBLOCK   0x0001
 #define GRND_NONBLOCK   0x0001
 #endif /* GRND_NONBLOCK */
 #endif /* GRND_NONBLOCK */
@@ -2621,6 +2623,54 @@ sysret_t sys_stat(const char *file, struct stat *buf)
     return ret;
     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)
 sysret_t sys_notimpl(void)
 {
 {
     return -ENOSYS;
     return -ENOSYS;
@@ -4292,6 +4342,99 @@ sysret_t sys_setaffinity(pid_t pid, size_t size, void *set)
     return -1;
     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)
 sysret_t sys_sched_setparam(pid_t pid, void *param)
 {
 {
     struct sched_param *sched_param = (struct sched_param *)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;
     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[] =
 const static struct rt_syscall_def func_table[] =
 {
 {
     SYSCALL_SIGN(sys_exit),            /* 01 */
     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_notify),
     SYSCALL_SIGN(sys_mq_getsetattr),
     SYSCALL_SIGN(sys_mq_getsetattr),
     SYSCALL_SIGN(sys_mq_close),
     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_uname),                            /* 170 */
     SYSCALL_SIGN(sys_statfs),
     SYSCALL_SIGN(sys_statfs),
     SYSCALL_SIGN(sys_statfs64),
     SYSCALL_SIGN(sys_statfs64),
@@ -5119,6 +5316,10 @@ const static struct rt_syscall_def func_table[] =
     SYSCALL_SIGN(sys_openat),                           /* 175 */
     SYSCALL_SIGN(sys_openat),                           /* 175 */
     SYSCALL_SIGN(sys_mount),
     SYSCALL_SIGN(sys_mount),
     SYSCALL_SIGN(sys_umount2),
     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)
 const void *lwp_get_sys_api(rt_uint32_t number)

+ 27 - 0
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)
 #define page_start ((rt_page_t)rt_mpr_start)
 
 
 static rt_size_t page_nr;
 static rt_size_t page_nr;
+static rt_size_t _high_pages_nr;
 static rt_size_t early_offset;
 static rt_size_t early_offset;
 
 
 static const char *get_name(rt_varea_t varea)
 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;
     *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)
 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;
     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 */
         /* insert to list */
         rt_page_t *page_list = _get_page_list((void *)region.start);
         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);
         insert(page_list, (rt_page_t)((char *)p - early_offset), size_bits - ARCH_PAGE_SHIFT);
         region.start += (1UL << size_bits);
         region.start += (1UL << size_bits);
     }
     }

+ 2 - 0
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_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);
 void *rt_page_page2addr(struct rt_page *p);
 
 
 struct rt_page *rt_page_addr2page(void *addr);
 struct rt_page *rt_page_addr2page(void *addr);