authorgravatar for isaac.yonemoto@gmail.comIsaac Yonemoto <isaac.yonemoto@gmail.com> 2020-12-03 12:49:35-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-12-03 15:49:35-05:00
loga2cd9dc3bd1e6a5f4e6a3c593b05b0f7bd2943ce
treebbf030186ab39ffa668979032441f7c3ac9586e7
parent5317f00e047f35fbee237caa29f45a69152bee81
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Gpa mutex configurable (#7234)

* makes the mutex for the gpa configurable * fixed logic, added test * updates docstring; pushes logic to one place, better duck-type

1 files changed, 24 insertions(+), 1 deletions(-)

lib/std/heap/general_purpose_allocator.zig+24-1
...@@ -148,6 +148,16 @@ pub const Config = struct {...@@ -148,6 +148,16 @@ pub const Config = struct {
148 /// Whether the allocator may be used simultaneously from multiple threads.148 /// Whether the allocator may be used simultaneously from multiple threads.
149 thread_safe: bool = !std.builtin.single_threaded,149 thread_safe: bool = !std.builtin.single_threaded,
150150
151 /// What type of mutex you'd like to use, for thread safety.
152 /// when specfied, the mutex type must have the same shape as `std.Mutex` and
153 /// `std.mutex.Dummy`, and have no required fields. Specifying this field causes
154 /// the `thread_safe` field to be ignored.
155 ///
156 /// when null (default):
157 /// * the mutex type defaults to `std.Mutex` when thread_safe is enabled.
158 /// * the mutex type defaults to `std.mutex.Dummy` otherwise.
159 MutexType: ?type = null,
160
151 /// This is a temporary debugging trick you can use to turn segfaults into more helpful161 /// This is a temporary debugging trick you can use to turn segfaults into more helpful
152 /// logged error messages with stack trace details. The downside is that every allocation162 /// logged error messages with stack trace details. The downside is that every allocation
153 /// will be leaked!163 /// will be leaked!
...@@ -174,7 +184,8 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -174,7 +184,8 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
174 const total_requested_bytes_init = if (config.enable_memory_limit) @as(usize, 0) else {};184 const total_requested_bytes_init = if (config.enable_memory_limit) @as(usize, 0) else {};
175 const requested_memory_limit_init = if (config.enable_memory_limit) @as(usize, math.maxInt(usize)) else {};185 const requested_memory_limit_init = if (config.enable_memory_limit) @as(usize, math.maxInt(usize)) else {};
176186
177 const mutex_init = if (config.thread_safe) std.Mutex{} else std.mutex.Dummy{};187 const mutex_init = if (config.MutexType) |T| T{} else
188 if (config.thread_safe) std.Mutex{} else std.mutex.Dummy{};
178189
179 const stack_n = config.stack_trace_frames;190 const stack_n = config.stack_trace_frames;
180 const one_trace_size = @sizeOf(usize) * stack_n;191 const one_trace_size = @sizeOf(usize) * stack_n;
...@@ -849,6 +860,18 @@ test "realloc large object to small object" {...@@ -849,6 +860,18 @@ test "realloc large object to small object" {
849 std.testing.expect(slice[16] == 0x34);860 std.testing.expect(slice[16] == 0x34);
850}861}
851862
863test "overrideable mutexes" {
864 var gpa = GeneralPurposeAllocator(.{.MutexType = std.Mutex}){
865 .backing_allocator = std.testing.allocator,
866 .mutex = std.Mutex{}
867 };
868 defer std.testing.expect(!gpa.deinit());
869 const allocator = &gpa.allocator;
870
871 const ptr = try allocator.create(i32);
872 defer allocator.destroy(ptr);
873}
874
852test "non-page-allocator backing allocator" {875test "non-page-allocator backing allocator" {
853 var gpa = GeneralPurposeAllocator(.{}){ .backing_allocator = std.testing.allocator };876 var gpa = GeneralPurposeAllocator(.{}){ .backing_allocator = std.testing.allocator };
854 defer std.testing.expect(!gpa.deinit());877 defer std.testing.expect(!gpa.deinit());