Skip to content

Commit f89d483

Browse files
ffrostfallaatxe
andauthored
System API for getting os, architecture, processor count (#149)
TODO: - ~~Get system info for POSIX compliant systems~~ - ~~Bikeshed on the field name for thread/logical processor/core count (lol)~~ Closes issue #117 --------- Co-authored-by: ariel <[email protected]>
1 parent 24c5079 commit f89d483

File tree

6 files changed

+166
-1
lines changed

6 files changed

+166
-1
lines changed

CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ add_library(Lute.Net STATIC)
1616
add_library(Lute.Task STATIC)
1717
add_library(Lute.VM STATIC)
1818
add_library(Lute.Process STATIC)
19+
add_library(Lute.System STATIC)
1920

2021
# luau setup
2122
set(LUAU_BUILD_CLI OFF)
@@ -89,13 +90,15 @@ target_compile_features(Lute.Net PUBLIC cxx_std_17)
8990
target_compile_features(Lute.Task PUBLIC cxx_std_17)
9091
target_compile_features(Lute.VM PUBLIC cxx_std_17)
9192
target_compile_features(Lute.Process PUBLIC cxx_std_17)
93+
target_compile_features(Lute.System PUBLIC cxx_std_17)
9294
target_include_directories(Lute.Runtime PUBLIC runtime/include ${LIBUV_INCLUDE_DIR})
9395
target_include_directories(Lute.Fs PUBLIC fs/include ${LIBUV_INCLUDE_DIR})
9496
target_include_directories(Lute.Luau PUBLIC luau/include ${LIBUV_INCLUDE_DIR})
9597
target_include_directories(Lute.Net PUBLIC net/include ${LIBUV_INCLUDE_DIR} ${UWEBSOCKETS_INCLUDE_DIR})
9698
target_include_directories(Lute.Task PUBLIC task/include ${LIBUV_INCLUDE_DIR})
9799
target_include_directories(Lute.VM PUBLIC vm/include ${LIBUV_INCLUDE_DIR})
98100
target_include_directories(Lute.Process PUBLIC process/include ${LIBUV_INCLUDE_DIR})
101+
target_include_directories(Lute.System PUBLIC system/include ${LIBUV_INCLUDE_DIR})
99102

100103
target_link_libraries(Lute.Runtime PRIVATE Luau.CLI.lib Luau.Compiler Luau.Config Luau.CodeGen Luau.VM uv_a)
101104
target_link_libraries(Lute.Fs PRIVATE Lute.Runtime Luau.VM uv_a)
@@ -104,7 +107,8 @@ target_link_libraries(Lute.Net PRIVATE Lute.Runtime Luau.VM uv_a ${WOLFSSL_LIBRA
104107
target_link_libraries(Lute.Task PRIVATE Lute.Runtime Luau.VM uv_a)
105108
target_link_libraries(Lute.VM PRIVATE Lute.Runtime Luau.VM uv_a)
106109
target_link_libraries(Lute.Process PRIVATE Lute.Runtime Luau.VM uv_a)
107-
target_link_libraries(Lute.CLI PRIVATE Luau.CLI.lib Luau.Compiler Luau.Config Luau.CodeGen Luau.Analysis Luau.VM Lute.Runtime Lute.Fs Lute.Luau Lute.Net Lute.Task Lute.VM Lute.Process)
110+
target_link_libraries(Lute.System PRIVATE Lute.Runtime Luau.VM uv_a)
111+
target_link_libraries(Lute.CLI PRIVATE Luau.CLI.lib Luau.Compiler Luau.Config Luau.CodeGen Luau.Analysis Luau.VM Lute.Runtime Lute.Fs Lute.Luau Lute.Net Lute.Task Lute.VM Lute.Process Lute.System)
108112

109113
set(LUTE_OPTIONS)
110114

@@ -128,4 +132,5 @@ target_compile_options(Lute.Net PRIVATE ${LUTE_OPTIONS})
128132
target_compile_options(Lute.Task PRIVATE ${LUTE_OPTIONS})
129133
target_compile_options(Lute.VM PRIVATE ${LUTE_OPTIONS})
130134
target_compile_options(Lute.Process PRIVATE ${LUTE_OPTIONS})
135+
target_compile_options(Lute.System PRIVATE ${LUTE_OPTIONS})
131136
target_compile_options(Lute.CLI PRIVATE ${LUTE_OPTIONS})

Sources.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,9 @@ target_sources(Lute.CLI PRIVATE
5353
cli/tc.h
5454
cli/tc.cpp
5555
)
56+
57+
target_sources(Lute.System PRIVATE
58+
system/include/lute/system.h
59+
60+
system/src/system.cpp
61+
)

cli/main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "lute/net.h"
1414
#include "lute/options.h"
1515
#include "lute/process.h"
16+
#include "lute/system.h"
1617
#include "lute/ref.h"
1718
#include "lute/require.h"
1819
#include "lute/runtime.h"
@@ -70,6 +71,9 @@ lua_State* setupState(Runtime& runtime)
7071

7172
luteopen_vm(L);
7273
lua_setfield(L, -2, "@lute/vm");
74+
75+
luteopen_system(L);
76+
lua_setfield(L, -2, "@lute/system");
7377

7478
static const luaL_Reg funcs[] = {
7579
{"require", lua_require},

examples/system_lib.luau

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
local system = require("@lute/system")
2+
3+
print(system.os)
4+
print(system.arch)
5+
print(system.threadcount())
6+
7+
for i, cpu in system.cpus() do
8+
-- print(`[core {string.format("%.02i", i)}] speed: {cpu.speed}, model: {cpu.model}`)
9+
10+
-- for key, time in cpu.times do
11+
-- print(` [times] {key}: {time}`)
12+
-- end
13+
end

system/include/lute/system.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
3+
#include "lua.h"
4+
#include "lualib.h"
5+
#include <string>
6+
7+
// open the library as a standard global luau library
8+
int luaopen_system(lua_State* L);
9+
// open the library as a table on top of the stack
10+
int luteopen_system(lua_State* L);
11+
12+
static const char kArchitectureProperty[] = "arch";
13+
static const char kOperatingSystemProperty[] = "os";
14+
15+
namespace system_lib
16+
{
17+
int lua_cpus(lua_State* L);
18+
int lua_threadcount(lua_State* L);
19+
20+
static const luaL_Reg lib[] = {
21+
{"cpus", lua_cpus},
22+
{"threadcount", lua_threadcount},
23+
24+
{nullptr, nullptr}
25+
};
26+
27+
static const std::string properties[] = {
28+
kArchitectureProperty,
29+
kOperatingSystemProperty,
30+
};
31+
32+
} // namespace system_lib

system/src/system.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#include "lute/system.h"
2+
#include "lua.h"
3+
#include "uv.h"
4+
#include <iterator>
5+
#include <string>
6+
#include <vector>
7+
8+
int luaopen_system(lua_State* L)
9+
{
10+
luteopen_system(L);
11+
lua_setglobal(L, "system");
12+
13+
return 1;
14+
}
15+
16+
int luteopen_system(lua_State* L)
17+
{
18+
lua_createtable(L, 0, std::size(system_lib::lib) + std::size(system_lib::properties));
19+
20+
for (auto& [name, func] : system_lib::lib)
21+
{
22+
if (!name || !func)
23+
break;
24+
25+
lua_pushcfunction(L, func, name);
26+
lua_setfield(L, -2, name);
27+
}
28+
29+
// os
30+
uv_utsname_t sysinfo;
31+
uv_os_uname(&sysinfo);
32+
33+
lua_pushstring(L, sysinfo.sysname);
34+
lua_setfield(L, -2, kOperatingSystemProperty);
35+
36+
lua_pushstring(L, sysinfo.machine);
37+
lua_setfield(L, -2, kArchitectureProperty);
38+
39+
lua_setreadonly(L, -1, 1);
40+
41+
return 1;
42+
}
43+
44+
namespace system_lib
45+
{
46+
int lua_cpus(lua_State* L)
47+
{
48+
int count = uv_available_parallelism();
49+
uv_cpu_info_t* cpus;
50+
51+
uv_cpu_info(&cpus, &count);
52+
53+
lua_createtable(L, count, 0);
54+
55+
int j = 0;
56+
for (int i = 0; i < count; i++)
57+
{
58+
lua_pushinteger(L, ++j);
59+
60+
auto cpuInfo = cpus[i];
61+
62+
// model, speed, times
63+
lua_createtable(L, 0, 2);
64+
65+
lua_pushstring(L, cpuInfo.model);
66+
lua_setfield(L, -2, "model");
67+
68+
lua_pushinteger(L, (int)cpuInfo.speed);
69+
lua_setfield(L, -2, "speed");
70+
71+
// sys, user, idle, irq, nice
72+
lua_createtable(L, 0, 5);
73+
74+
// cast to double cuz uint64 has higher max n and lua numbers are 52bit
75+
lua_pushnumber(L, static_cast<double>(cpuInfo.cpu_times.sys));
76+
lua_setfield(L, -2, "sys");
77+
78+
lua_pushnumber(L, static_cast<double>(cpuInfo.cpu_times.idle));
79+
lua_setfield(L, -2, "idle");
80+
81+
lua_pushnumber(L, static_cast<double>(cpuInfo.cpu_times.irq));
82+
lua_setfield(L, -2, "irq");
83+
84+
lua_pushnumber(L, static_cast<double>(cpuInfo.cpu_times.nice));
85+
lua_setfield(L, -2, "nice");
86+
87+
lua_pushnumber(L, static_cast<double>(cpuInfo.cpu_times.user));
88+
lua_setfield(L, -2, "user");
89+
90+
lua_setfield(L, -2, "times");
91+
92+
lua_settable(L, -3);
93+
};
94+
95+
return 1;
96+
}
97+
98+
int lua_threadcount(lua_State* L)
99+
{
100+
lua_pushinteger(L, uv_available_parallelism());
101+
102+
return 1;
103+
}
104+
105+
} // namespace system_lib

0 commit comments

Comments
 (0)