Skip to content

Commit 88bce80

Browse files
author
Simon Galli
committed
docs: Add example for using lua_user_h build option
1 parent 622dde9 commit 88bce80

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

build.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ pub fn build(b: *Build) void {
108108
var common_examples = [_]struct { []const u8, []const u8 }{
109109
.{ "interpreter", "examples/interpreter.zig" },
110110
.{ "zig-function", "examples/zig-fn.zig" },
111+
.{ "multithreaded", "examples/multithreaded.zig" },
111112
};
112113
const luau_examples = [_]struct { []const u8, []const u8 }{
113114
.{ "luau-bytecode", "examples/luau-bytecode.zig" },

examples/multithreaded.zig

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//! Multi threaded lua program
2+
//! The additional header must be passed to the build using `-Dlua_user_h=examples/user.h`
3+
//! Checkout http://lua-users.org/wiki/ThreadsTutorial for more info
4+
5+
const std = @import("std");
6+
const zlua = @import("zlua");
7+
8+
var mutex = std.Thread.Mutex{};
9+
10+
export fn lua_zlock(L: *zlua.LuaState) callconv(.C) void {
11+
_ = L;
12+
mutex.lock();
13+
}
14+
15+
export fn lua_zunlock(L: *zlua.LuaState) callconv(.C) void {
16+
_ = L;
17+
mutex.unlock();
18+
}
19+
20+
fn add_to_x(lua: *zlua.Lua, num: usize) void {
21+
for (0..num) |_| {
22+
// omit error handling for brevity
23+
lua.loadString("x = x + 1\n") catch return;
24+
lua.protectedCall(.{}) catch return;
25+
}
26+
27+
const size = 256;
28+
var buf = [_:0]u8{0} ** size;
29+
_ = std.fmt.bufPrint(&buf, "print(\"{}: \", x)", .{std.Thread.getCurrentId()}) catch return;
30+
31+
// The printing from different threads does not always work nicely
32+
// There seems to be a separate sterr lock on each argument to print
33+
lua.loadString(&buf) catch return;
34+
lua.protectedCall(.{}) catch return;
35+
}
36+
37+
pub fn main() anyerror!void {
38+
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
39+
const allocator = gpa.allocator();
40+
defer _ = gpa.deinit();
41+
42+
// Initialize The Lua vm and get a reference to the main thread
43+
var lua = try zlua.Lua.init(allocator);
44+
defer lua.deinit();
45+
46+
lua.openLibs();
47+
48+
// create a global variable accessible by all threads
49+
// omit error handling for brevity
50+
try lua.loadString("_G.x = 0\n");
51+
try lua.protectedCall(.{});
52+
53+
const num = 1_000;
54+
const n_jobs = 5;
55+
var subs: [n_jobs]*zlua.Lua = undefined;
56+
57+
// create a thread pool to run all the functions
58+
var pool: std.Thread.Pool = undefined;
59+
try pool.init(.{ .allocator = allocator, .n_jobs = n_jobs });
60+
defer pool.deinit();
61+
62+
var wg: std.Thread.WaitGroup = .{};
63+
64+
for (0..n_jobs) |i| {
65+
subs[i] = lua.newThread();
66+
pool.spawnWg(&wg, add_to_x, .{ subs[i], num });
67+
}
68+
69+
// also do the thing from the main thread
70+
add_to_x(lua, num);
71+
72+
wg.wait();
73+
74+
for (subs) |sub| {
75+
try lua.closeThread(sub);
76+
}
77+
78+
// print the final value
79+
try lua.loadString("print(x)\n");
80+
try lua.protectedCall(.{});
81+
}

examples/user.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#define lua_lock(L) lua_zlock(L)
2+
#define lua_unlock(L) lua_zunlock(L)
3+
4+
void lua_zlock(lua_State* L);
5+
void lua_zunlock(lua_State* L);
6+

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ There are currently three additional options that can be passed to `b.dependency
6666
* `.lang`: Set the Lua language to build and embed. Defaults to `.lua54`. Possible values are `.lua51`, `.lua52`, `.lua53`, `.lua54`, and `luau`.
6767
* `.shared`: Defaults to `false` for embedding in a Zig program. Set to `true` to dynamically link the Lua source code (useful for creating shared modules).
6868
* `luau_use_4_vector`: defaults to false. Set to true to use 4-vectors instead of the default 3-vector in Luau.
69+
* `lua_user_h`: defaults to null. Provide a path to an additional header file for the Lua compilation. Must be set to to `examples/user.h` in order to run the multithreaded example.
6970

7071
For example, here is a `b.dependency()` call that and links against a shared Lua 5.2 library:
7172

0 commit comments

Comments
 (0)