summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorbernard <[email protected]>2026-08-23 07:44:06 +0800
committerRbb666 <[email protected]>2026-08-30 20:49:24 +0800
commit25cbe4abae05e9be46edff3966850af8a7f58515 (patch)
tree23b53221ea762371677ab70b64a6b8b8a02cc79b /components
parentf02a869318c9df28ec2eab41f1a58795dc8a3f1b (diff)
[dfs][procfs] Add Linux-compatible process and system files
补齐 procfs 中 cpuinfo、stat、uptime、loadavg、meminfo、mounts 和进程目录文件。 按架构和 SMP 配置隔离仅在对应平台有效的字段,避免非 AArch64/非 SMP 构建告警。
Diffstat (limited to 'components')
-rw-r--r--components/dfs/dfs_v2/filesystems/procfs/proc_cpuinfo.c76
-rw-r--r--components/dfs/dfs_v2/filesystems/procfs/proc_loadavg.c56
-rw-r--r--components/dfs/dfs_v2/filesystems/procfs/proc_meminfo.c23
-rw-r--r--components/dfs/dfs_v2/filesystems/procfs/proc_mounts.c75
-rw-r--r--components/dfs/dfs_v2/filesystems/procfs/proc_pid.c450
-rw-r--r--components/dfs/dfs_v2/filesystems/procfs/proc_stat.c80
-rw-r--r--components/dfs/dfs_v2/filesystems/procfs/proc_uptime.c23
7 files changed, 660 insertions, 123 deletions
diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_cpuinfo.c b/components/dfs/dfs_v2/filesystems/procfs/proc_cpuinfo.c
index 6f49832992..ca3a8dc48a 100644
--- a/components/dfs/dfs_v2/filesystems/procfs/proc_cpuinfo.c
+++ b/components/dfs/dfs_v2/filesystems/procfs/proc_cpuinfo.c
@@ -18,11 +18,19 @@
#include <dfs_dentry.h>
-static void *seq_start(struct dfs_seq_file *seq, off_t *index)
+#if defined(__aarch64__) || defined(__AARCH64EL__)
+static rt_uint64_t cpu_midr(void)
{
- off_t i = *index; // seq->index
+ rt_uint64_t value;
+
+ __asm__ volatile("mrs %0, midr_el1" : "=r"(value));
+ return value;
+}
+#endif
- return NULL + (i == 0);
+static void *seq_start(struct dfs_seq_file *seq, off_t *index)
+{
+ return (*index < RT_CPUS_NR) ? (void *)1 : RT_NULL;
}
static void seq_stop(struct dfs_seq_file *seq, void *data)
@@ -31,27 +39,57 @@ static void seq_stop(struct dfs_seq_file *seq, void *data)
static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
- /* data: The return value of the start or next*/
- off_t i = *index + 1; // seq->index
-
- *index = i;
-
- return NULL;
+ RT_UNUSED(seq);
+ RT_UNUSED(data);
+ *index += 1;
+ return (*index < RT_CPUS_NR) ? (void *)1 : RT_NULL;
}
static int seq_show(struct dfs_seq_file *seq, void *data)
{
- /* data: The return value of the start or next*/
- dfs_seq_puts(seq, "rt_weak const struct dfs_seq_ops *cpuinfo_get_seq_ops(void)\n--need your own function--\n");
+#if defined(__aarch64__) || defined(__AARCH64EL__)
+ rt_uint64_t midr;
+ rt_uint32_t implementer;
+ rt_uint32_t variant;
+ rt_uint32_t architecture;
+ rt_uint32_t part;
+ rt_uint32_t revision;
+#endif
+
+ RT_UNUSED(data);
+#if defined(__aarch64__) || defined(__AARCH64EL__)
+ midr = cpu_midr();
+ implementer = (rt_uint32_t)((midr >> 24) & 0xffU);
+ variant = (rt_uint32_t)((midr >> 20) & 0x0fU);
+ architecture = (rt_uint32_t)((midr >> 16) & 0x0fU);
+ part = (rt_uint32_t)((midr >> 4) & 0x0fffU);
+ revision = (rt_uint32_t)(midr & 0x0fU);
+#endif
+
+ dfs_seq_printf(seq, "processor\t: %lu\n", (unsigned long)seq->index);
+#if defined(__aarch64__) || defined(__AARCH64EL__)
+ dfs_seq_puts(seq, "model name\t: ARMv8 Generic\n");
+ dfs_seq_printf(seq, "CPU implementer\t: 0x%02lx\n", (unsigned long)implementer);
+ dfs_seq_printf(seq, "CPU architecture: %lu\n", (unsigned long)(architecture ? architecture : 8U));
+ dfs_seq_printf(seq, "CPU variant\t: 0x%lx\n", (unsigned long)variant);
+ dfs_seq_printf(seq, "CPU part\t: 0x%03lx\n", (unsigned long)part);
+ dfs_seq_printf(seq, "CPU revision\t: %lu\n", (unsigned long)revision);
+#elif defined(__riscv)
+ dfs_seq_puts(seq, "model name\t: RISC-V Generic\n");
+ dfs_seq_puts(seq, "isa\t\t: rv64\n");
+#else
+ dfs_seq_puts(seq, "model name\t: RT-Thread Generic CPU\n");
+#endif
+ dfs_seq_puts(seq, "\n");
return 0;
}
static const struct dfs_seq_ops seq_ops = {
- .start = seq_start,
- .stop = seq_stop,
- .next = seq_next,
- .show = seq_show,
+ .start = seq_start,
+ .stop = seq_stop,
+ .next = seq_next,
+ .show = seq_show,
};
rt_weak const struct dfs_seq_ops *cpuinfo_get_seq_ops(void)
@@ -70,10 +108,10 @@ static int proc_close(struct dfs_file *file)
}
static const struct dfs_file_ops file_ops = {
- .open = proc_open,
- .read = dfs_seq_read,
- .lseek = dfs_seq_lseek,
- .close = proc_close,
+ .open = proc_open,
+ .read = dfs_seq_read,
+ .lseek = dfs_seq_lseek,
+ .close = proc_close,
};
int proc_cpuinfo_init(void)
diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_loadavg.c b/components/dfs/dfs_v2/filesystems/procfs/proc_loadavg.c
index 6ce1bc487a..acb6ee35b5 100644
--- a/components/dfs/dfs_v2/filesystems/procfs/proc_loadavg.c
+++ b/components/dfs/dfs_v2/filesystems/procfs/proc_loadavg.c
@@ -17,16 +17,62 @@
#include <errno.h>
#include <dfs_dentry.h>
-#include <mm_page.h>
+#ifdef RT_USING_SMART
+#include "lwp_pid.h"
+#ifdef RT_USING_MUSLLIBC
+#include "lwp.h"
+#endif
+#endif
-extern void rt_memory_info(rt_size_t *total,
- rt_size_t *used,
- rt_size_t *max_used);
+#ifdef RT_USING_SMART
+struct loadavg_count
+{
+ int total;
+ int runnable;
+};
+
+static int loadavg_count_pid(pid_t pid, void *arg)
+{
+ struct loadavg_count *count = (struct loadavg_count *)arg;
+ struct rt_lwp *lwp = lwp_from_pid_locked(pid);
+
+ if (!lwp)
+ {
+ return 0;
+ }
+ count->total++;
+#ifdef RT_USING_MUSLLIBC
+ {
+ rt_list_t *node;
+
+ node = lwp->t_grp.next;
+ while (node != &lwp->t_grp)
+ {
+ rt_thread_t thread = rt_list_entry(node, struct rt_thread, sibling);
+ if (RT_SCHED_CTX(thread).stat == RT_THREAD_RUNNING)
+ {
+ count->runnable++;
+ break;
+ }
+ node = node->next;
+ }
+ }
+#endif
+ return 0;
+}
+#endif
static int single_show(struct dfs_seq_file *seq, void *data)
{
- dfs_seq_printf(seq, "0.13 0.16 0.17 1/1035 380436\n");
+#ifdef RT_USING_SMART
+ struct loadavg_count count = { 0, 0 };
+
+ lwp_pid_for_each(loadavg_count_pid, &count);
+ dfs_seq_printf(seq, "0.00 0.00 0.00 %d/%d 0\n", count.runnable, count.total);
+#else
+ dfs_seq_puts(seq, "0.00 0.00 0.00 0/0 0\n");
+#endif
return 0;
}
diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_meminfo.c b/components/dfs/dfs_v2/filesystems/procfs/proc_meminfo.c
index b6ae56288f..b1617f8bfd 100644
--- a/components/dfs/dfs_v2/filesystems/procfs/proc_meminfo.c
+++ b/components/dfs/dfs_v2/filesystems/procfs/proc_meminfo.c
@@ -34,24 +34,27 @@ static int single_show(struct dfs_seq_file *seq, void *data)
total_sum = total_sum + total;
total_freed = total_freed + total - used;
- dfs_seq_printf(seq, "%-16s%8d KB\n", "MemMaxUsed:", max_used / 1024);
- dfs_seq_printf(seq, "%-16s%8d KB\n", "MemAvailable:", (total - used) / 1024);
- dfs_seq_printf(seq, "%-16s%8d KB\n", "Cached:", 0);
- dfs_seq_printf(seq, "%-16s%8d KB\n", "SReclaimable:", 0);
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "MemMaxUsed:", (unsigned long)(max_used / 1024));
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "MemAvailable:", (unsigned long)((total - used) / 1024));
rt_page_get_info(&total, &freed);
total_sum = total_sum + total * RT_MM_PAGE_SIZE;
total_freed = total_freed + freed * RT_MM_PAGE_SIZE;
- dfs_seq_printf(seq, "%-16s%8d KB\n", "MemTotal:", total_sum / 1024);
- dfs_seq_printf(seq, "%-16s%8d KB\n", "MemFree:", total_freed / 1024);
- dfs_seq_printf(seq, "%-16s%8d KB\n", "LowPageTotal:", total * RT_MM_PAGE_SIZE / 1024);
- dfs_seq_printf(seq, "%-16s%8d KB\n", "lowPageFree:", freed * RT_MM_PAGE_SIZE/ 1024);
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "MemTotal:", (unsigned long)(total_sum / 1024));
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "MemFree:", (unsigned long)(total_freed / 1024));
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "Buffers:", 0UL);
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "Cached:", 0UL);
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "SwapCached:", 0UL);
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "SwapTotal:", 0UL);
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "SwapFree:", 0UL);
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "LowPageTotal:", (unsigned long)(total * RT_MM_PAGE_SIZE / 1024));
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "LowPageFree:", (unsigned long)(freed * RT_MM_PAGE_SIZE / 1024));
rt_page_high_get_info(&total, &freed);
- dfs_seq_printf(seq, "%-16s%8d KB\n", "HighPageTotal:", total * RT_MM_PAGE_SIZE / 1024);
- dfs_seq_printf(seq, "%-16s%8d KB\n", "HighPageFree:", freed * RT_MM_PAGE_SIZE / 1024);
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "HighPageTotal:", (unsigned long)(total * RT_MM_PAGE_SIZE / 1024));
+ dfs_seq_printf(seq, "%-16s%8lu kB\n", "HighPageFree:", (unsigned long)(freed * RT_MM_PAGE_SIZE / 1024));
return 0;
}
diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_mounts.c b/components/dfs/dfs_v2/filesystems/procfs/proc_mounts.c
index 49a6ba99c6..1bb3b6a6bc 100644
--- a/components/dfs/dfs_v2/filesystems/procfs/proc_mounts.c
+++ b/components/dfs/dfs_v2/filesystems/procfs/proc_mounts.c
@@ -19,13 +19,62 @@
#include <dfs_dentry.h>
#include <dfs_mnt.h>
+static void mnt_escape(const char *source, char *target, rt_size_t target_size)
+{
+ rt_size_t offset = 0;
+ const char *cursor = source ? source : "";
+
+ if (target_size == 0)
+ {
+ return;
+ }
+
+ while (*cursor != '\0' && offset + 4 < target_size)
+ {
+ if (*cursor == ' ')
+ {
+ target[offset++] = '\\';
+ target[offset++] = '0';
+ target[offset++] = '4';
+ target[offset++] = '0';
+ }
+ else if (*cursor == '\t')
+ {
+ target[offset++] = '\\';
+ target[offset++] = '0';
+ target[offset++] = '1';
+ target[offset++] = '1';
+ }
+ else if (*cursor == '\n')
+ {
+ target[offset++] = '\\';
+ target[offset++] = '0';
+ target[offset++] = '1';
+ target[offset++] = '2';
+ }
+ else if (*cursor == '\\')
+ {
+ target[offset++] = '\\';
+ target[offset++] = '1';
+ target[offset++] = '3';
+ target[offset++] = '4';
+ }
+ else
+ {
+ target[offset++] = *cursor;
+ }
+ cursor++;
+ }
+
+ target[offset] = '\0';
+}
const char *mnt_flag(int flag)
{
- /*if (flag & MNT_READONLY)
+ if (flag & MNT_RDONLY)
{
return "ro";
- }*/
+ }
return "rw";
}
@@ -33,19 +82,23 @@ const char *mnt_flag(int flag)
static struct dfs_mnt* mnt_show(struct dfs_mnt *mnt, void *parameter)
{
struct dfs_seq_file *seq = (struct dfs_seq_file *)parameter;
+ char source[DFS_PATH_MAX];
+ char target[DFS_PATH_MAX];
+ const char *source_name;
+ const char *filesystem_name;
- if (mnt)
+ if (mnt && mnt->fs_ops && mnt->fullpath)
{
- if (mnt->dev_id)
- {
- dfs_seq_printf(seq, "%s %s %s %s 0 0\n", mnt->dev_id->parent.name, mnt->fullpath,
- mnt->fs_ops->name, mnt_flag(mnt->flags));
- }
- else
+ filesystem_name = mnt->fs_ops->name ? mnt->fs_ops->name : "unknown";
+ source_name = filesystem_name;
+ if (mnt->dev_id && mnt->dev_id->parent.name[0] != '\0')
{
- dfs_seq_printf(seq, "%s %s %s %s 0 0\n", mnt->fs_ops->name, mnt->fullpath,
- mnt->fs_ops->name, mnt_flag(mnt->flags));
+ source_name = mnt->dev_id->parent.name;
}
+ mnt_escape(source_name, source, sizeof(source));
+ mnt_escape(mnt->fullpath, target, sizeof(target));
+ dfs_seq_printf(seq, "%s %s %s %s 0 0\n", source, target,
+ filesystem_name, mnt_flag(mnt->flags));
}
return RT_NULL;
diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_pid.c b/components/dfs/dfs_v2/filesystems/procfs/proc_pid.c
index a413f646c8..9212351ac4 100644
--- a/components/dfs/dfs_v2/filesystems/procfs/proc_pid.c
+++ b/components/dfs/dfs_v2/filesystems/procfs/proc_pid.c
@@ -26,6 +26,12 @@
#include "lwp.h"
#include "lwp_pid.h"
#include <lwp_user_mm.h>
+#ifdef ARCH_MM_MMU
+#include <stdint.h>
+#include <mm_aspace.h>
+#include <mm_flag.h>
+#include <mmu.h>
+#endif
struct pid_dentry
{
@@ -49,6 +55,241 @@ static char stat_transform(int __stat)
}
}
+#ifdef ARCH_MM_MMU
+#define PROC_MAP_MAX 256
+
+struct proc_map_entry
+{
+ uintptr_t start;
+ uintptr_t end;
+ uintptr_t offset;
+ rt_size_t resident_pages;
+ rt_bool_t writable;
+ rt_bool_t shared;
+ rt_bool_t executable;
+ char name[DFS_PATH_MAX];
+};
+
+struct proc_map_context
+{
+ struct rt_lwp *lwp;
+ struct proc_map_entry *entries;
+ rt_size_t count;
+ rt_bool_t smaps;
+};
+
+static void proc_map_permissions(rt_varea_t varea, struct proc_map_entry *entry)
+{
+ entry->writable = rt_hw_mmu_attr_test_perm(
+ varea->attr, RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER);
+ entry->shared = (varea->flag & MMF_MAP_SHARED) != 0;
+ entry->executable = (varea->flag & MMF_TEXT) != 0;
+}
+
+static void proc_map_name(rt_varea_t varea, struct proc_map_entry *entry)
+{
+ const char *name = RT_NULL;
+
+ if (varea->mem_obj && varea->mem_obj->get_name)
+ {
+ name = varea->mem_obj->get_name(varea);
+ }
+
+ if (!name || !name[0] || !rt_strcmp(name, "anonymous") ||
+ !rt_strcmp(name, "reference") || !rt_strcmp(name, "null"))
+ {
+ name = "[anon]";
+ }
+ rt_strncpy(entry->name, name, sizeof(entry->name) - 1);
+ entry->name[sizeof(entry->name) - 1] = '\0';
+}
+
+static int proc_map_collect(rt_varea_t varea, void *arg)
+{
+ struct proc_map_context *context = (struct proc_map_context *)arg;
+ struct proc_map_entry *entry;
+ uintptr_t address;
+ uintptr_t end;
+
+ if (context->count >= PROC_MAP_MAX || !varea || varea->size == 0)
+ {
+ return 0;
+ }
+
+ entry = &context->entries[context->count++];
+ entry->start = (uintptr_t)varea->start;
+ entry->end = entry->start + varea->size;
+ entry->offset = (uintptr_t)varea->offset * ARCH_PAGE_SIZE;
+ entry->resident_pages = 0;
+ proc_map_permissions(varea, entry);
+ proc_map_name(varea, entry);
+
+ address = entry->start;
+ end = entry->end;
+ while (address < end)
+ {
+ if (rt_hw_mmu_v2p(varea->aspace, (void *)address) != ARCH_MAP_FAILED)
+ {
+ entry->resident_pages++;
+ }
+ address += ARCH_PAGE_SIZE;
+ }
+
+ return 0;
+}
+
+static void proc_map_context_free(struct proc_map_context *context)
+{
+ if (context)
+ {
+ if (context->lwp)
+ {
+ lwp_from_pid_release_lock(context->lwp);
+ }
+ if (context->entries)
+ {
+ rt_free(context->entries);
+ }
+ rt_free(context);
+ }
+}
+
+static void *proc_maps_start(struct dfs_seq_file *seq, off_t *index)
+{
+ struct proc_map_context *context = (struct proc_map_context *)seq->data;
+
+ return context && *index < (off_t)context->count ? &context->entries[*index] : RT_NULL;
+}
+
+static void *proc_maps_next(struct dfs_seq_file *seq, void *data, off_t *index)
+{
+ struct proc_map_context *context = (struct proc_map_context *)seq->data;
+
+ RT_UNUSED(data);
+ *index += 1;
+ return context && *index < (off_t)context->count ? &context->entries[*index] : RT_NULL;
+}
+
+static void proc_maps_stop(struct dfs_seq_file *seq, void *data)
+{
+ RT_UNUSED(seq);
+ RT_UNUSED(data);
+}
+
+static int proc_maps_show(struct dfs_seq_file *seq, void *data)
+{
+ struct proc_map_entry *entry = (struct proc_map_entry *)data;
+ char permissions[5];
+
+ permissions[0] = 'r';
+ permissions[1] = entry->writable ? 'w' : '-';
+ permissions[2] = entry->executable ? 'x' : '-';
+ permissions[3] = entry->shared ? 's' : 'p';
+ permissions[4] = '\0';
+
+ dfs_seq_printf(seq, "%0*lx-%0*lx %s %0*lx 00:00 0",
+ (int)(sizeof(uintptr_t) * 2), (unsigned long)entry->start,
+ (int)(sizeof(uintptr_t) * 2), (unsigned long)entry->end,
+ permissions, (int)(sizeof(uintptr_t) * 2),
+ (unsigned long)entry->offset);
+ if (entry->name[0])
+ {
+ dfs_seq_printf(seq, " %s", entry->name);
+ }
+ dfs_seq_puts(seq, "\n");
+
+ if (((struct proc_map_context *)seq->data)->smaps)
+ {
+ rt_size_t resident_kb = entry->resident_pages * (ARCH_PAGE_SIZE / 1024);
+ rt_size_t private_dirty = entry->writable && !entry->shared ? resident_kb : 0;
+
+ dfs_seq_printf(seq, "Size: %lu kB\n", (unsigned long)((entry->end - entry->start) / 1024));
+ dfs_seq_printf(seq, "Rss: %lu kB\n", (unsigned long)resident_kb);
+ dfs_seq_printf(seq, "Pss: %lu kB\n", (unsigned long)resident_kb);
+ dfs_seq_puts(seq, "Shared_Clean: 0 kB\n");
+ dfs_seq_puts(seq, "Shared_Dirty: 0 kB\n");
+ dfs_seq_puts(seq, "Private_Clean: 0 kB\n");
+ dfs_seq_printf(seq, "Private_Dirty: %lu kB\n", (unsigned long)private_dirty);
+ dfs_seq_printf(seq, "Anonymous: %lu kB\n", entry->name[0] == '[' ? (unsigned long)resident_kb : 0UL);
+ dfs_seq_puts(seq, "Swap: 0 kB\n\n");
+ }
+
+ return 0;
+}
+
+static const struct dfs_seq_ops proc_maps_seq_ops = {
+ .start = proc_maps_start,
+ .stop = proc_maps_stop,
+ .next = proc_maps_next,
+ .show = proc_maps_show,
+};
+
+static int proc_maps_open(struct dfs_file *file)
+{
+ struct proc_dentry *dentry = (struct proc_dentry *)file->vnode->data;
+ struct proc_map_context *context;
+ struct dfs_seq_file *seq;
+ rt_varea_t varea;
+ int ret;
+
+ context = rt_calloc(1, sizeof(*context));
+ if (!context)
+ {
+ return -RT_ENOMEM;
+ }
+ context->lwp = lwp_from_pid_and_lock(dentry->pid);
+ if (!context->lwp || !context->lwp->aspace)
+ {
+ proc_map_context_free(context);
+ return -RT_ENOENT;
+ }
+ context->smaps = !rt_strcmp(dentry->name, "smaps");
+ context->entries = rt_calloc(PROC_MAP_MAX, sizeof(*context->entries));
+ if (!context->entries)
+ {
+ proc_map_context_free(context);
+ return -RT_ENOMEM;
+ }
+
+ RD_LOCK(context->lwp->aspace);
+ varea = ASPACE_VAREA_FIRST(context->lwp->aspace);
+ while (varea)
+ {
+ proc_map_collect(varea, context);
+ varea = ASPACE_VAREA_NEXT(varea);
+ }
+ RD_UNLOCK(context->lwp->aspace);
+
+ ret = dfs_seq_open(file, &proc_maps_seq_ops);
+ if (ret != RT_EOK)
+ {
+ proc_map_context_free(context);
+ return ret;
+ }
+ seq = (struct dfs_seq_file *)file->data;
+ seq->data = context;
+ return RT_EOK;
+}
+
+static int proc_maps_close(struct dfs_file *file)
+{
+ struct dfs_seq_file *seq = (struct dfs_seq_file *)file->data;
+ struct proc_map_context *context = seq ? (struct proc_map_context *)seq->data : RT_NULL;
+ int ret = dfs_seq_release(file);
+
+ proc_map_context_free(context);
+ file->data = RT_NULL;
+ return ret;
+}
+
+static const struct dfs_file_ops proc_maps_fops = {
+ .open = proc_maps_open,
+ .read = dfs_seq_read,
+ .lseek = dfs_seq_lseek,
+ .close = proc_maps_close,
+};
+#endif /* ARCH_MM_MMU */
+
static int stat_single_show(struct dfs_seq_file *seq, void *data)
{
struct proc_dentry *dentry = (struct proc_dentry *)seq->file->vnode->data;
@@ -60,56 +301,53 @@ static int stat_single_show(struct dfs_seq_file *seq, void *data)
int lwp_oncpu = RT_CPUS_NR;
int lwp_oncpu_ok = 0;
struct rt_lwp *lwp = RT_NULL;
- char** argv = RT_NULL;
+ char **argv = RT_NULL;
char *filename = RT_NULL;
char *dot = RT_NULL;
- lwp_pid_lock_take();
-
- lwp = lwp_from_pid_locked(dentry->pid);
- argv = lwp_get_command_line_args(lwp);
+ lwp = lwp_from_pid_and_lock(dentry->pid);
+ argv = lwp ? lwp_get_command_line_args(lwp) : RT_NULL;
if (lwp)
{
- dfs_seq_printf(seq,"%d ",dentry->pid);
+ dfs_seq_printf(seq, "%d ", dentry->pid);
if (argv)
{
- filename = strrchr(argv[0], '/');
- dot = strchr(argv[0], '.');
-
- if (filename != NULL)
+ if (argv[0])
{
- filename++;
- }
- else
- {
- filename = argv[0];
- }
+ filename = strrchr(argv[0], '/');
- if (dot != NULL)
- {
- *dot = '\0';
- }
+ if (filename != NULL)
+ {
+ filename++;
+ }
+ else
+ {
+ filename = argv[0];
+ }
- if (filename != NULL)
- {
- dfs_seq_printf(seq,"(%s) ", filename);
+ dot = strchr(filename, '.');
+ if (dot != NULL)
+ {
+ *dot = '\0';
+ }
+
+ dfs_seq_printf(seq, "(%s) ", filename);
}
else
{
- dfs_seq_printf(seq,"(%s) ", argv[0]);
+ dfs_seq_printf(seq, "(%s) ", "");
}
-
lwp_free_command_line_args(argv);
}
else
{
- dfs_seq_printf(seq,"(%s) ", "");
+ dfs_seq_printf(seq, "(%s) ", "");
}
if (lwp->terminated)
{
- dfs_seq_printf(seq,"%c ",'Z');
+ dfs_seq_printf(seq, "%c ", 'Z');
}
else
{
@@ -120,11 +358,11 @@ static int stat_single_show(struct dfs_seq_file *seq, void *data)
user_time_lwp = user_time_lwp + thread->user_time;
system_time_lwp = system_time_lwp + thread->system_time;
- #if RT_CPUS_NR > 1
- #define ONCPU(thread) RT_SCHED_CTX(thread).oncpu
- #else
- #define ONCPU(thread) 0
- #endif
+#if RT_CPUS_NR > 1
+#define ONCPU(thread) RT_SCHED_CTX(thread).oncpu
+#else
+#define ONCPU(thread) 0
+#endif
if (lwp_oncpu_ok == 0)
{
lwp_oncpu = ONCPU(thread);
@@ -140,34 +378,37 @@ static int stat_single_show(struct dfs_seq_file *seq, void *data)
if (mask == 1)
{
- dfs_seq_printf(seq,"%c ",'R');
+ dfs_seq_printf(seq, "%c ", 'R');
}
else
{
- dfs_seq_printf(seq,"%c ",'S');
+ dfs_seq_printf(seq, "%c ", 'S');
}
}
- lwp_pid_lock_release();
-
if (lwp->parent != NULL)
- dfs_seq_printf(seq,"%d ",lwp->parent->pid);
+ {
+ dfs_seq_printf(seq, "%d ", lwp->parent->pid);
+ }
else
- dfs_seq_printf(seq,"0 ");
+ {
+ dfs_seq_printf(seq, "0 ");
+ }
dfs_seq_printf(seq, "1 1 0 -1 4194560 48245 133976064 732 425574 ");
- dfs_seq_printf(seq,"%llu ",user_time_lwp);//utime
- dfs_seq_printf(seq,"%llu ",system_time_lwp);//stime
+ dfs_seq_printf(seq, "%llu ", user_time_lwp);//utime
+ dfs_seq_printf(seq, "%llu ", system_time_lwp);//stime
dfs_seq_printf(seq, "1204291 518742 20 0 1 0 50 ");
- dfs_seq_printf(seq, "%d ",rt_aspace_count_vsz(lwp->aspace));//VSZ
+#ifdef ARCH_MM_MMU
+ dfs_seq_printf(seq, "%lu ", lwp->aspace ? (unsigned long)rt_aspace_count_vsz(lwp->aspace) : 0UL);//VSZ
+#else
+ dfs_seq_puts(seq, "0 ");
+#endif
dfs_seq_printf(seq, "1422 18446744073709551615 ");
dfs_seq_printf(seq, "1 1 0 0 0 0 671173123 4096 1260 0 0 0 17 ");
dfs_seq_printf(seq, "%d ", lwp_oncpu);//CPU
dfs_seq_printf(seq, "0 0 0 0 0 0 0 0 0 0 0 0 0");
- dfs_seq_printf(seq,"\n");
- }
- else
- {
- lwp_pid_lock_release();
+ dfs_seq_printf(seq, "\n");
+ lwp_from_pid_release_lock(lwp);
}
return 0;
@@ -177,12 +418,10 @@ static int cmdline_single_show(struct dfs_seq_file *seq, void *data)
{
struct proc_dentry *dentry = (struct proc_dentry *)seq->file->vnode->data;
struct rt_lwp *lwp;
- char** argv;
+ char **argv;
- lwp_pid_lock_take();
- lwp = lwp_from_pid_locked(dentry->pid);
- argv = lwp_get_command_line_args(lwp);
- lwp_pid_lock_release();
+ lwp = lwp_from_pid_and_lock(dentry->pid);
+ argv = lwp ? lwp_get_command_line_args(lwp) : RT_NULL;
if (argv)
{
@@ -198,7 +437,80 @@ static int cmdline_single_show(struct dfs_seq_file *seq, void *data)
{
dfs_seq_puts(seq, "error\n");
}
+ lwp_from_pid_release_lock(lwp);
+
+ return 0;
+}
+
+static int proc_pid_status_show(struct dfs_seq_file *seq, void *data)
+{
+ struct proc_dentry *dentry = (struct proc_dentry *)seq->file->vnode->data;
+ struct rt_lwp *lwp = lwp_from_pid_and_lock(dentry->pid);
+ rt_size_t vm_size = 0;
+ rt_size_t thread_count = 0;
+ rt_list_t *node;
+ char state;
+
+ RT_UNUSED(data);
+ if (!lwp)
+ {
+ return -RT_ENOENT;
+ }
+#ifdef ARCH_MM_MMU
+ if (lwp->aspace)
+ {
+ vm_size = rt_aspace_count_vsz(lwp->aspace);
+ }
+#endif
+ node = lwp->t_grp.next;
+ while (node != &lwp->t_grp)
+ {
+ thread_count++;
+ node = node->next;
+ }
+ state = lwp->terminated ? 'Z' : 'S';
+ dfs_seq_printf(seq, "Name:\t%s\n", lwp->cmd);
+ dfs_seq_printf(seq, "State:\t%c (sleeping)\n", state);
+ dfs_seq_printf(seq, "Pid:\t%d\n", lwp->pid);
+ dfs_seq_printf(seq, "PPid:\t%d\n", lwp->parent ? lwp->parent->pid : 0);
+ dfs_seq_puts(seq, "Uid:\t0\t0\t0\t0\nGid:\t0\t0\t0\t0\n");
+ dfs_seq_printf(seq, "Threads:\t%lu\n", (unsigned long)thread_count);
+ dfs_seq_printf(seq, "VmSize:\t%lu kB\n", (unsigned long)(vm_size / 1024));
+ dfs_seq_printf(seq, "VmRSS:\t%lu kB\n", (unsigned long)(vm_size / 1024));
+ dfs_seq_puts(seq, "VmData:\t0 kB\nVmStk:\t0 kB\nVmExe:\t0 kB\nVmLib:\t0 kB\n");
+ lwp_from_pid_release_lock(lwp);
+ return 0;
+}
+
+static int proc_pid_statm_show(struct dfs_seq_file *seq, void *data)
+{
+ struct proc_dentry *dentry = (struct proc_dentry *)seq->file->vnode->data;
+ struct rt_lwp *lwp = lwp_from_pid_and_lock(dentry->pid);
+ rt_size_t size_pages = 0;
+ rt_size_t text_pages = 0;
+ rt_size_t data_pages = 0;
+
+ RT_UNUSED(data);
+ if (!lwp)
+ {
+ return -RT_ENOENT;
+ }
+
+#ifdef ARCH_MM_MMU
+ if (lwp->aspace)
+ {
+ size_pages = (rt_aspace_count_vsz(lwp->aspace) + ARCH_PAGE_SIZE - 1) / ARCH_PAGE_SIZE;
+ }
+#endif
+#ifdef ARCH_MM_MMU
+ text_pages = (lwp->text_size + ARCH_PAGE_SIZE - 1) / ARCH_PAGE_SIZE;
+ data_pages = (lwp->data_size + ARCH_PAGE_SIZE - 1) / ARCH_PAGE_SIZE;
+#endif
+ dfs_seq_printf(seq, "%lu %lu 0 %lu 0 %lu 0\n",
+ (unsigned long)size_pages, (unsigned long)size_pages,
+ (unsigned long)text_pages, (unsigned long)data_pages);
+ lwp_from_pid_release_lock(lwp);
return 0;
}
@@ -240,13 +552,21 @@ struct proc_dentry *proc_pid_fd_lookup(struct proc_dentry *parent, const char *n
{
//todo add vnode->data
if (file->vnode->type == FT_SOCKET)
+ {
dentry->data = (void *)rt_strdup("socket");
+ }
else if (file->vnode->type == FT_USER)
+ {
dentry->data = (void *)rt_strdup("user");
+ }
else if (file->vnode->type == FT_DEVICE)
+ {
dentry->data = (void *)rt_strdup("device");
+ }
else
+ {
dentry->data = (void *)rt_strdup("unknown");
+ }
}
dentry->pid = parent->pid;
@@ -337,8 +657,9 @@ int proc_pid_exe_readlink(struct proc_dentry *dentry, char *buf, int len)
{
struct rt_lwp *lwp;
- lwp = lwp_self();
- len = rt_snprintf(buf, len, "%s", lwp ? lwp->exe_file : "null");
+ lwp = lwp_from_pid_and_lock(dentry->pid);
+ len = rt_snprintf(buf, len, "%s", lwp && lwp->exe_file ? lwp->exe_file : "null");
+ lwp_from_pid_release_lock(lwp);
return len;
}
@@ -351,8 +672,9 @@ int proc_pid_cwd_readlink(struct proc_dentry *dentry, char *buf, int len)
{
struct rt_lwp *lwp;
- lwp = lwp_self();
+ lwp = lwp_from_pid_and_lock(dentry->pid);
len = rt_snprintf(buf, len, "%s", lwp ? lwp->working_directory : "null");
+ lwp_from_pid_release_lock(lwp);
return len;
}
@@ -362,17 +684,23 @@ static const struct proc_ops proc_pid_cwd_ops = {
};
static struct pid_dentry pid_dentry_base[] = {
- {"cmdline", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, cmdline_single_show, 0},
- {"cwd", S_IFLNK | S_IRUSR | S_IXUSR, 0, &proc_pid_cwd_ops, 0, 0},
- {"exe", S_IFLNK | S_IRUSR | S_IXUSR, 0, &proc_pid_exe_ops, 0, 0},
- {"fd", S_IFDIR | S_IRUSR | S_IXUSR, &proc_pid_fd_fops, &proc_pid_fd_ops, 0, 0, 0},
- {"mounts", S_IFLNK | S_IRUSR | S_IXUSR, 0, 0, 0, 0, "/proc/mounts"},
- {"stat", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, stat_single_show, 0},
+ { "cmdline", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, cmdline_single_show, 0 },
+ { "status", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, proc_pid_status_show, 0 },
+ { "statm", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, proc_pid_statm_show, 0 },
+ { "cwd", S_IFLNK | S_IRUSR | S_IXUSR, 0, &proc_pid_cwd_ops, 0, 0 },
+ { "exe", S_IFLNK | S_IRUSR | S_IXUSR, 0, &proc_pid_exe_ops, 0, 0 },
+ { "fd", S_IFDIR | S_IRUSR | S_IXUSR, &proc_pid_fd_fops, &proc_pid_fd_ops, 0, 0, 0 },
+ { "mounts", S_IFLNK | S_IRUSR | S_IXUSR, 0, 0, 0, 0, "/proc/mounts" },
+ { "stat", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, stat_single_show, 0 },
+#ifdef ARCH_MM_MMU
+ { "maps", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, &proc_maps_fops, 0, 0, 0, 0 },
+ { "smaps", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, &proc_maps_fops, 0, 0, 0, 0 },
+#endif
};
int proc_pid(int pid)
{
- char pid_str[64] = {0};
+ char pid_str[64] = { 0 };
struct proc_dentry *dentry;
rt_snprintf(pid_str, 64, "%d", pid);
diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_stat.c b/components/dfs/dfs_v2/filesystems/procfs/proc_stat.c
index aeba99de51..c24adb291e 100644
--- a/components/dfs/dfs_v2/filesystems/procfs/proc_stat.c
+++ b/components/dfs/dfs_v2/filesystems/procfs/proc_stat.c
@@ -18,6 +18,49 @@
#include <dfs_dentry.h>
+#ifdef RT_USING_SMART
+#include "lwp_pid.h"
+#ifdef RT_USING_MUSLLIBC
+#include "lwp.h"
+#endif
+#endif
+
+#ifdef RT_USING_SMART
+struct stat_process_count
+{
+ int total;
+ int running;
+};
+
+static int stat_process_count(pid_t pid, void *arg)
+{
+ struct stat_process_count *count = (struct stat_process_count *)arg;
+ struct rt_lwp *lwp = lwp_from_pid_locked(pid);
+
+ if (!lwp)
+ {
+ return 0;
+ }
+ count->total++;
+#ifdef RT_USING_MUSLLIBC
+ {
+ rt_list_t *node = lwp->t_grp.next;
+
+ while (node != &lwp->t_grp)
+ {
+ rt_thread_t thread = rt_list_entry(node, struct rt_thread, sibling);
+ if (RT_SCHED_CTX(thread).stat == RT_THREAD_RUNNING)
+ {
+ count->running++;
+ break;
+ }
+ node = node->next;
+ }
+ }
+#endif
+ return 0;
+}
+#endif
static void *seq_start(struct dfs_seq_file *seq, off_t *index)
{
@@ -50,7 +93,7 @@ static int seq_show(struct dfs_seq_file *seq, void *data)
for (i = 0; i < RT_CPUS_NR; i++)
{
- pcpu = rt_cpu_index(i);
+ pcpu = rt_cpu_index(i);
user_total = user_total + pcpu->cpu_stat.user;
system_total = system_total + pcpu->cpu_stat.system;
idle_total = idle_total + pcpu->cpu_stat.idle;
@@ -59,27 +102,36 @@ static int seq_show(struct dfs_seq_file *seq, void *data)
for (i = 0; i < RT_CPUS_NR; i++)
{
- pcpu = rt_cpu_index(i);
- dfs_seq_printf(seq, "cpu%d ",i);
- dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.user);//user
+ pcpu = rt_cpu_index(i);
+ dfs_seq_printf(seq, "cpu%d ", i);
+ dfs_seq_printf(seq, "%llu ", pcpu->cpu_stat.user);//user
dfs_seq_printf(seq, "0 ");//nice
- dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.system);//system
- dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.idle);//idle
+ dfs_seq_printf(seq, "%llu ", pcpu->cpu_stat.system);//system
+ dfs_seq_printf(seq, "%llu ", pcpu->cpu_stat.idle);//idle
dfs_seq_printf(seq, "0 ");//iowait
dfs_seq_printf(seq, "0 ");//irq
dfs_seq_printf(seq, "0 ");//softirq
dfs_seq_printf(seq, "0 0 0\n");//steal,guest,guest_nice
+ }
+#ifdef RT_USING_SMART
+ {
+ struct stat_process_count process_count = { 0, 0 };
+ lwp_pid_for_each(stat_process_count, &process_count);
+ dfs_seq_printf(seq, "processes %d\n", process_count.total);
+ dfs_seq_printf(seq, "procs_running %d\n", process_count.running);
+ dfs_seq_puts(seq, "procs_blocked 0\n");
}
+#endif
return 0;
}
static const struct dfs_seq_ops seq_ops = {
- .start = seq_start,
- .stop = seq_stop,
- .next = seq_next,
- .show = seq_show,
+ .start = seq_start,
+ .stop = seq_stop,
+ .next = seq_next,
+ .show = seq_show,
};
rt_weak const struct dfs_seq_ops *stat_get_seq_ops(void)
@@ -98,10 +150,10 @@ static int proc_close(struct dfs_file *file)
}
static const struct dfs_file_ops file_ops = {
- .open = proc_open,
- .read = dfs_seq_read,
- .lseek = dfs_seq_lseek,
- .close = proc_close,
+ .open = proc_open,
+ .read = dfs_seq_read,
+ .lseek = dfs_seq_lseek,
+ .close = proc_close,
};
int proc_stat_init(void)
diff --git a/components/dfs/dfs_v2/filesystems/procfs/proc_uptime.c b/components/dfs/dfs_v2/filesystems/procfs/proc_uptime.c
index f16ab72b66..5da9e9952d 100644
--- a/components/dfs/dfs_v2/filesystems/procfs/proc_uptime.c
+++ b/components/dfs/dfs_v2/filesystems/procfs/proc_uptime.c
@@ -21,9 +21,26 @@
static int single_show(struct dfs_seq_file *seq, void *data)
{
- dfs_seq_printf(seq, "%lu.%02lu %lu.%02lu\n",
- (unsigned long)rt_tick_get_millisecond() / 1000, (unsigned long)(rt_tick_get_millisecond() % 1000) / 100,
- (unsigned long)rt_tick_get_millisecond() / 1000, (unsigned long)(rt_tick_get_millisecond() % 1000) / 100);
+ rt_tick_t ticks = rt_tick_get();
+ rt_uint64_t uptime_ms;
+ rt_uint64_t idle_ticks = 0;
+#ifdef RT_USING_SMP
+ int index;
+#endif
+
+ uptime_ms = ((rt_uint64_t)ticks * 1000U) / RT_TICK_PER_SECOND;
+#ifdef RT_USING_SMP
+ for (index = 0; index < RT_CPUS_NR; index++)
+ {
+ idle_ticks += rt_cpu_index(index)->cpu_stat.idle;
+ }
+#else
+ idle_ticks = rt_cpu_index(0)->cpu_stat.idle;
+#endif
+ dfs_seq_printf(seq, "%llu.%02llu %llu.%02llu\n",
+ uptime_ms / 1000U, (uptime_ms % 1000U) / 10U,
+ ((rt_uint64_t)idle_ticks * 1000U) / RT_TICK_PER_SECOND / 1000U,
+ (((rt_uint64_t)idle_ticks * 1000U) / RT_TICK_PER_SECOND % 1000U) / 10U);
return 0;
}