Skip to content
80 changes: 61 additions & 19 deletions components/dfs/dfs_v2/filesystems/procfs/proc_cpuinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

return NULL + (i == 0);
__asm__ volatile("mrs %0, midr_el1" : "=r"(value));
return value;
}
#endif

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)
Expand All @@ -31,27 +39,61 @@ 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");
#if defined(__riscv_xlen) && (__riscv_xlen == 32)
dfs_seq_puts(seq, "isa\t\t: rv32\n");
#else
dfs_seq_puts(seq, "isa\t\t: rv64\n");
#endif
#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)
Expand All @@ -70,10 +112,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)
Expand Down
111 changes: 106 additions & 5 deletions components/dfs/dfs_v2/filesystems/procfs/proc_loadavg.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,117 @@
#include <errno.h>

#include <dfs_dentry.h>
#include <mm_page.h>

#ifdef RT_USING_SMART
#include "lwp.h"
#include "lwp_pid.h"
#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;
};

/* Fixed-point load averages, 11 bits of fraction like Linux FSHIFT. */
#define PROC_LOAD_FSHIFT 11
#define PROC_LOAD_FIXED_1 (1UL << PROC_LOAD_FSHIFT)
#define PROC_LOAD_EXP_1 1884UL /* 1 / exp(5s / 60s) * 2048 */
#define PROC_LOAD_EXP_5 2014UL /* 1 / exp(5s / 300s) * 2048 */
#define PROC_LOAD_EXP_15 2037UL /* 1 / exp(5s / 900s) * 2048 */

static unsigned long load_1 = 0;
static unsigned long load_5 = 0;
static unsigned long load_15 = 0;
static rt_tick_t load_last_tick = 0;

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++;
{
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);
int stat = RT_SCHED_CTX(thread).stat & RT_THREAD_STAT_MASK;

if (stat == RT_THREAD_RUNNING || stat == RT_THREAD_READY)
{
count->runnable++;
break;
}
node = node->next;
}
}
return 0;
}

static void loadavg_fold(unsigned long active)
{
load_1 = load_1 * PROC_LOAD_EXP_1 / PROC_LOAD_FIXED_1 +
active * (PROC_LOAD_FIXED_1 - PROC_LOAD_EXP_1) / PROC_LOAD_FIXED_1;
load_5 = load_5 * PROC_LOAD_EXP_5 / PROC_LOAD_FIXED_1 +
active * (PROC_LOAD_FIXED_1 - PROC_LOAD_EXP_5) / PROC_LOAD_FIXED_1;
load_15 = load_15 * PROC_LOAD_EXP_15 / PROC_LOAD_FIXED_1 +
active * (PROC_LOAD_FIXED_1 - PROC_LOAD_EXP_15) / PROC_LOAD_FIXED_1;
}

static void loadavg_update(unsigned long active)
{
rt_tick_t now = rt_tick_get();
rt_tick_t period = RT_TICK_PER_SECOND * 5;

if (load_last_tick == 0)
{
load_1 = load_5 = load_15 = active;
load_last_tick = now;
return;
}

while ((rt_tick_t)(now - load_last_tick) >= period)
{
loadavg_fold(active);
load_last_tick += period;
}
}

static void loadavg_print(struct dfs_seq_file *seq, unsigned long load)
{
unsigned long integer = load >> PROC_LOAD_FSHIFT;
unsigned long frac = ((load & (PROC_LOAD_FIXED_1 - 1)) * 100) >> PROC_LOAD_FSHIFT;

dfs_seq_printf(seq, "%lu.%02lu", integer, frac);
}
#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");
RT_UNUSED(data);
#ifdef RT_USING_SMART
struct loadavg_count count = { 0, 0 };

lwp_pid_for_each(loadavg_count_pid, &count);
loadavg_update(((unsigned long)count.runnable) << PROC_LOAD_FSHIFT);
loadavg_print(seq, load_1);
dfs_seq_puts(seq, " ");
loadavg_print(seq, load_5);
dfs_seq_puts(seq, " ");
loadavg_print(seq, load_15);
dfs_seq_printf(seq, " %d/%d %d\n", count.runnable, count.total,
(int)lwp_pid_get_last());
#else
dfs_seq_puts(seq, "0.00 0.00 0.00 0/0 0\n");
Comment on lines +119 to +129

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: /proc/loadavg now maintains 1/5/15-minute averages and reports the last created PID.

#endif

return 0;
}
Expand Down
23 changes: 13 additions & 10 deletions components/dfs/dfs_v2/filesystems/procfs/proc_meminfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));

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", "MemAvailable:", (unsigned long)(total_freed / 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;
}
Expand Down
83 changes: 72 additions & 11 deletions components/dfs/dfs_v2/filesystems/procfs/proc_mounts.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,94 @@
#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')
{
const char *escape = RT_NULL;
rt_size_t need = 1;

if (*cursor == ' ')
{
escape = "\\040";
need = 4;
}
else if (*cursor == '\t')
{
escape = "\\011";
need = 4;
}
else if (*cursor == '\n')
{
escape = "\\012";
need = 4;
}
else if (*cursor == '\\')
{
escape = "\\134";
need = 4;
}

if (offset + need >= target_size)
{
break;
}

if (escape)
{
target[offset++] = escape[0];
target[offset++] = escape[1];
target[offset++] = escape[2];
target[offset++] = escape[3];
}
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";
}

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;
Expand Down
Loading
Loading