Skip to content

Commit 877d062

Browse files
committed
Omp: use names and synchronization behaviours for critical sections
This may not fit the standard completely since we need to specify every time a name and a sync behaviour, but it works. Also the critical section will come with a huge performance hit compared to the native counterpart i imagine
1 parent 098ea95 commit 877d062

2 files changed

Lines changed: 26 additions & 12 deletions

File tree

src/kmp.zig

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ pub const ident_t = extern struct {
5757
psource: [*:0]const u8,
5858
};
5959

60-
pub const critical_name_t = [8]c_int;
6160
pub const kmpc_micro_t = fn (global_tid: *c_int, bound_tid: *c_int, args: *align(@alignOf(usize)) anyopaque) callconv(.C) void;
6261

6362
extern "C" fn __kmpc_fork_call(name: *ident_t, argc: c_int, fun: *const kmpc_micro_t, ...) void;
@@ -136,16 +135,15 @@ pub inline fn push_num_threads(name: *ident_t, global_tid: c_int, num_threads: c
136135
__kmpc_push_num_threads(@constCast(name), global_tid, num_threads);
137136
}
138137

139-
// Maybe figure out how to use the clang API, but since this GOMP is supported by clang we can just use it
140-
// This is "needed" because it's an API that doesn't need to use the name for which i don't know the rules to it
141-
extern "C" fn GOMP_critical_start() void;
142-
pub inline fn critical() void {
143-
GOMP_critical_start();
138+
pub const critical_name_t = [8]c_int; // This seems to be just a lock, so I give up on ever using it
139+
extern "C" fn __kmpc_critical_with_hint(loc: *ident_t, global_tid: c_int, crit: *critical_name_t, hint: c_int) void;
140+
pub inline fn critical(loc: *ident_t, global_tid: c_int, crit: *critical_name_t, hint: c_int) void {
141+
__kmpc_critical_with_hint(loc, global_tid, crit, hint);
144142
}
145143

146-
extern "C" fn GOMP_critical_end() void;
147-
pub inline fn critical_end() void {
148-
GOMP_critical_end();
144+
extern "C" fn __kmpc_end_critical(loc: *ident_t, global_tid: c_int, crit: *critical_name_t) void;
145+
pub inline fn critical_end(loc: *ident_t, global_tid: c_int, crit: *critical_name_t) void {
146+
__kmpc_end_critical(loc, global_tid, crit);
149147
}
150148

151149
// Todo: invert for big endian

src/omp.zig

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,15 @@ pub const ctx = struct {
103103

104104
global_tid: c_int,
105105
bound_tid: c_int,
106+
locks: std.StringHashMap(kmp.critical_name_t),
106107

107108
fn make_outline(comptime T: type, comptime R: type, comptime f: anytype) type {
108109
return opaque {
109110
fn outline(gtid: *c_int, btid: *c_int, argss: *T) callconv(.C) void {
110111
var this: Self = .{
111112
.global_tid = gtid.*,
112113
.bound_tid = btid.*,
114+
.locks = std.StringHashMap(kmp.critical_name_t).init(std.heap.page_allocator),
113115
};
114116

115117
const private_type = @TypeOf(argss.args.privates);
@@ -149,6 +151,7 @@ pub const ctx = struct {
149151
} else {
150152
argss.ret = @call(.auto, f, .{&this} ++ true_args);
151153
}
154+
152155
return;
153156
}
154157
};
@@ -304,8 +307,21 @@ pub const ctx = struct {
304307
kmp.barrier(&id, this.global_tid);
305308
}
306309

307-
pub fn critical(this: *Self, f: anytype, args: anytype) copy_ret(f) {
308-
kmp.critical();
310+
pub fn critical(this: *Self, name: []const u8, sync: sync_hint_t, f: anytype, args: anytype) copy_ret(f) {
311+
var id: kmp.ident_t = .{
312+
.flags = @intFromEnum(kmp.ident_flags.IDENT_KMPC) | @intFromEnum(kmp.ident_flags.IDENT_WORK_LOOP),
313+
.psource = "barrier",
314+
};
315+
316+
var loc: kmp.critical_name_t = this.locks.get(name) orelse l: {
317+
var l: kmp.critical_name_t = @bitCast([_]u8{0} ** 32);
318+
this.locks.put(name, l) catch {
319+
@panic("Failed to allocate memory for lock");
320+
};
321+
break :l l;
322+
};
323+
324+
kmp.critical(&id, this.global_tid, &loc, @intFromEnum(sync));
309325

310326
const new_args = .{this} ++ args;
311327

@@ -317,7 +333,7 @@ pub const ctx = struct {
317333
break :ret @call(.auto, f, new_args);
318334
}
319335
};
320-
kmp.critical_end();
336+
kmp.critical_end(&id, this.global_tid, &loc);
321337

322338
return ret;
323339
}

0 commit comments

Comments
 (0)