Skip to content

Commit 2df93de

Browse files
committed
fixup! fixup! add linux.cpustat()
renamed module to cpu and added cpu.foreach_* iterators
1 parent ce01ed7 commit 2df93de

File tree

6 files changed

+195
-137
lines changed

6 files changed

+195
-137
lines changed

Kbuild

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,5 @@ obj-$(CONFIG_LUNATIK_CRYPTO_SKCIPHER) += lib/luacrypto_skcipher.o
5252
obj-$(CONFIG_LUNATIK_CRYPTO_AEAD) += lib/luacrypto_aead.o
5353
obj-$(CONFIG_LUNATIK_CRYPTO_RNG) += lib/luacrypto_rng.o
5454
obj-$(CONFIG_LUNATIK_CRYPTO_COMP) += lib/luacrypto_comp.o
55-
obj-$(CONFIG_LUNATIK_PROCSTAT) += lib/luaprocstat.o
55+
obj-$(CONFIG_LUNATIK_CPU) += lib/luacpu.o
5656

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ all: lunatik_sym.h
3030
CONFIG_LUNATIK_NETFILTER=m CONFIG_LUNATIK_COMPLETION=m \
3131
CONFIG_LUNATIK_CRYPTO_SHASH=m CONFIG_LUNATIK_CRYPTO_SKCIPHER=m \
3232
CONFIG_LUNATIK_CRYPTO_AEAD=m CONFIG_LUNATIK_CRYPTO_RNG=m \
33-
CONFIG_LUNATIK_CRYPTO_COMP=m CONFIG_LUNATIK_PROCSTAT=m
33+
CONFIG_LUNATIK_CRYPTO_COMP=m CONFIG_LUNATIK_CPU=m
3434

3535
clean:
3636
${MAKE} -C ${MODULES_BUILD_PATH} M=${PWD} clean

bin/lunatik

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ local lunatik = {
1010
modules = {"lunatik", "luadevice", "lualinux", "luanotifier", "luasocket", "luarcu",
1111
"luathread", "luafib", "luadata", "luaprobe", "luasyscall", "luaxdp", "luafifo", "luaxtable",
1212
"luanetfilter", "luacompletion", "luacrypto_shash", "luacrypto_skcipher", "luacrypto_aead",
13-
"luacrypto_rng", "luacrypto_comp", "lunatik_run", "luaprocstat"},
13+
"luacrypto_rng", "luacrypto_comp", "lunatik_run", "luacpu"},
1414
}
1515

1616
function lunatik.prompt()

examples/procstat.lua renamed to examples/cpu.lua

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
-- SPDX-FileCopyrightText: (c) 2025 Enderson Maia <[email protected]>
33
-- SPDX-License-Identifier: MIT OR GPL-2.0-only
44
--
5-
-- Simple example demonstrating linux.cpustat() usage
5+
-- Simple example demonstrating cpu.stats() usage
66

7-
local procstat = require("procstat")
7+
local cpu = require("cpu")
88

99
-- Get number of CPUs
10-
local num_cpus = procstat.nproc()
10+
local num_cpus = cpu.nproc()
1111
print(string.format("System has %d online CPUs\n", num_cpus))
1212

1313
local fmt = [[
@@ -24,10 +24,10 @@ CPU %d statistics:
2424
guest_nice: %d
2525
]]
2626

27-
-- Get stats for each CPU
28-
for i = 0, num_cpus - 1 do
29-
local stats = linux.cpustat(i)
30-
31-
print(string.format(fmt, i, stats.user, stats.nice, stats.system, stats.idle,
32-
stats.iowait, stats.irq, stats.softirq, stats.steal, stats.guest, stats.guest_nice))
33-
end
27+
-- Get stats for each online CPU
28+
cpu.foreach_online(function(cpu_id)
29+
local s = cpu.stats(cpu_id)
30+
31+
print(string.format(fmt, cpu_id, s.user, s.nice, s.system, s.idle,
32+
s.iowait, s.irq, s.softirq, s.steal, s.guest, s.guest_nice))
33+
end)

lib/luacpu.c

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/*
2+
* SPDX-FileCopyrightText: (c) 2025 Enderson Maia <[email protected]
3+
* SPDX-License-Identifier: MIT OR GPL-2.0-only
4+
*/
5+
6+
/***
7+
* Linux CPU Lua interface.
8+
*
9+
* This module provides access to Linux's CPU abstractions.
10+
*
11+
* @module cpu
12+
*/
13+
14+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15+
#include <linux/module.h>
16+
#include <linux/cpumask.h>
17+
#include <linux/kernel_stat.h>
18+
19+
#include <lua.h>
20+
#include <lualib.h>
21+
#include <lauxlib.h>
22+
23+
#include <lunatik.h>
24+
25+
/***
26+
* Gets the number of available processing units (CPUs).
27+
* @function nproc
28+
* @treturn integer The number of CPUs available in the system.
29+
* @usage
30+
* local num_cpus = cpustat.nproc()
31+
* print("Number of CPUs:", num_cpus)
32+
*/
33+
static int luacpu_nproc(lua_State *L)
34+
{
35+
lua_pushinteger(L, (lua_Integer)num_online_cpus());
36+
return 1;
37+
}
38+
39+
/***
40+
* Macro to set CPU statistics in Lua table.
41+
* @param L Lua state
42+
* @param idx Index of the table in the Lua stack
43+
* @param kcs Kernel CPU statistics structure (kernel_cpustat)
44+
* @param name Field name in the Lua table
45+
* @param NAME Corresponding C enum name for CPU time
46+
*/
47+
#define luacpu_setstat(L, idx, kcs, name, NAME) \
48+
do { \
49+
lua_pushinteger(L, (lua_Integer)kcs.cpustat[CPUTIME_##NAME]); \
50+
lua_setfield(L, idx - 1, #name); \
51+
} while (0)
52+
53+
/***
54+
* Gets CPU statistics for a specific CPU.
55+
* Fetches kernel CPU statistics including user, nice, system, idle, iowait,
56+
* irq, softirq, steal, guest, guest_nice and forceidle times.
57+
*
58+
* @function stats
59+
* @tparam integer cpu The CPU number (0-based) to query.
60+
* @treturn table A table containing CPU time statistics with the following fields:
61+
* @tfield integer user Time spent in user mode
62+
* @tfield integer nice Time spent in user mode with low priority (nice)
63+
* @tfield integer system Time spent in system mode
64+
* @tfield integer idle Time spent in idle task
65+
* @tfield integer iowait Time waiting for I/O to complete
66+
* @tfield integer irq Time servicing hardware interrupts
67+
* @tfield integer softirq Time servicing software interrupts
68+
* @tfield integer steal Time stolen by other operating systems (virtualized environment)
69+
* @tfield integer guest Time spent running a virtual CPU for guest OS
70+
* @tfield integer guest_nice Time spent running a niced guest
71+
* @tfield integer forceidle Time spent in forced idle (if CONFIG_SCHED_CORE is enabled)
72+
* @raise Error if CPU is offline
73+
* @usage
74+
* local cpu0 = cpu.stats(0)
75+
* print("CPU 0 user time:", cpu0.user)
76+
* print("CPU 0 idle time:", cpu0.idle)
77+
*/
78+
static int luacpu_stats(lua_State *L)
79+
{
80+
unsigned int cpu = luaL_checkinteger(L, 1);
81+
struct kernel_cpustat kcs;
82+
83+
luaL_argcheck(L, cpu_online(cpu), 1, "CPU is offline");
84+
85+
kcpustat_cpu_fetch(&kcs, cpu);
86+
87+
lua_createtable(L, 0, NR_STATS);
88+
89+
luacpu_setstat(L, -1, kcs, user, USER);
90+
luacpu_setstat(L, -1, kcs, nice, NICE);
91+
luacpu_setstat(L, -1, kcs, system, SYSTEM);
92+
luacpu_setstat(L, -1, kcs, idle, IDLE);
93+
luacpu_setstat(L, -1, kcs, iowait, IOWAIT);
94+
luacpu_setstat(L, -1, kcs, irq, IRQ);
95+
luacpu_setstat(L, -1, kcs, softirq, SOFTIRQ);
96+
luacpu_setstat(L, -1, kcs, steal, STEAL);
97+
luacpu_setstat(L, -1, kcs, guest, GUEST);
98+
luacpu_setstat(L, -1, kcs, guest_nice, GUEST_NICE);
99+
#ifdef CONFIG_SCHED_CORE
100+
luacpu_setstat(L, -1, kcs, forceidle, FORCEIDLE);
101+
#endif
102+
103+
return 1;
104+
}
105+
106+
#define LUACPU_FOREACH(name) \
107+
static int luacpu_foreach_##name(lua_State *L) { \
108+
unsigned int cpu; \
109+
\
110+
luaL_checktype(L, 1, LUA_TFUNCTION); \
111+
\
112+
for_each_##name##_cpu(cpu) { \
113+
lua_pushvalue(L, 1); \
114+
lua_pushinteger(L, cpu); \
115+
lua_call(L, 1, 0); \
116+
} \
117+
\
118+
return 0; \
119+
};
120+
121+
/***
122+
* Iterates over all possible CPUs and calls a function for each.
123+
*
124+
* @function foreach_possible
125+
* @tparam function callback Function to call for each possible CPU
126+
* @usage
127+
* cpu.foreach_possible(function(cpu_num)
128+
* print("CPU", cpu.stats(cpu_num))
129+
* end)
130+
*/
131+
LUACPU_FOREACH(possible)
132+
133+
/***
134+
* Iterates over all present CPUs and calls a function for each.
135+
*
136+
* @function foreach_present
137+
* @tparam function callback Function to call for each present CPU
138+
* @usage
139+
* cpu.foreach_present(function(cpu_num)
140+
* print("CPU", cpu.stats(cpu_num))
141+
* end)
142+
*/
143+
LUACPU_FOREACH(present)
144+
145+
/***
146+
* Iterates over all online CPUs and calls a function for each.
147+
*
148+
* @function foreach_online
149+
* @tparam function callback Function to call for each online CPU
150+
* @usage
151+
* cpu.foreach_online(function(cpu_num)
152+
* print("CPU", cpu.stats(cpu_num))
153+
* end)
154+
*/
155+
LUACPU_FOREACH(online)
156+
157+
static const luaL_Reg luacpu_lib[] = {
158+
{"nproc", luacpu_nproc},
159+
{"stats", luacpu_stats},
160+
{"foreach_possible", luacpu_foreach_possible},
161+
{"foreach_present", luacpu_foreach_present},
162+
{"foreach_online", luacpu_foreach_online},
163+
{NULL, NULL}
164+
};
165+
166+
LUNATIK_NEWLIB(cpu, luacpu_lib, NULL, NULL);
167+
168+
static int __init luacpu_init(void)
169+
{
170+
return 0;
171+
}
172+
173+
static void __exit luacpu_exit(void)
174+
{
175+
}
176+
177+
module_init(luacpu_init);
178+
module_exit(luacpu_exit);
179+
MODULE_LICENSE("Dual MIT/GPL");
180+
MODULE_AUTHOR("Enderson Maia <[email protected]");
181+
MODULE_DESCRIPTION("Lunatik interface to Linux's CPU abstractions.");
182+

lib/luaprocstat.c

Lines changed: 0 additions & 124 deletions
This file was deleted.

0 commit comments

Comments
 (0)