diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-12-18 23:57:46 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-18 23:57:46 -0500 |
| commit | 506af7e52e0985b410ea089bf5fa3247ab2377cb (patch) | |
| tree | 2ec26d70f41a1382b736b606ebfa094ace62573e /lib/std/os | |
| parent | ce65533985caa9e2da567948e36d7d4ba0185005 (diff) | |
| parent | f416535768fc30195cad6cd481f73fd1e80082aa (diff) | |
| download | zig-506af7e52e0985b410ea089bf5fa3247ab2377cb.tar.gz zig-506af7e52e0985b410ea089bf5fa3247ab2377cb.zip | |
Merge pull request #7482 from ziglang/tlcsprng
std: introduce a thread-local CSPRNG for general use
Diffstat (limited to 'lib/std/os')
| -rw-r--r-- | lib/std/os/bits/linux.zig | 22 | ||||
| -rw-r--r-- | lib/std/os/linux.zig | 4 | ||||
| -rw-r--r-- | lib/std/os/linux/tls.zig | 39 |
3 files changed, 50 insertions, 15 deletions
diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index 583240fd4e..2bcfc89ecf 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -2045,3 +2045,25 @@ pub const rlimit = extern struct { /// Hard limit max: rlim_t, }; + +pub const MADV_NORMAL = 0; +pub const MADV_RANDOM = 1; +pub const MADV_SEQUENTIAL = 2; +pub const MADV_WILLNEED = 3; +pub const MADV_DONTNEED = 4; +pub const MADV_FREE = 8; +pub const MADV_REMOVE = 9; +pub const MADV_DONTFORK = 10; +pub const MADV_DOFORK = 11; +pub const MADV_MERGEABLE = 12; +pub const MADV_UNMERGEABLE = 13; +pub const MADV_HUGEPAGE = 14; +pub const MADV_NOHUGEPAGE = 15; +pub const MADV_DONTDUMP = 16; +pub const MADV_DODUMP = 17; +pub const MADV_WIPEONFORK = 18; +pub const MADV_KEEPONFORK = 19; +pub const MADV_COLD = 20; +pub const MADV_PAGEOUT = 21; +pub const MADV_HWPOISON = 100; +pub const MADV_SOFT_OFFLINE = 101; diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index f840f6a255..f252a08fc9 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1351,6 +1351,10 @@ pub fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: ?*const rlimit, ); } +pub fn madvise(address: [*]u8, len: usize, advice: u32) usize { + return syscall3(.madvise, @ptrToInt(address), len, advice); +} + test "" { if (builtin.os.tag == .linux) { _ = @import("linux/test.zig"); diff --git a/lib/std/os/linux/tls.zig b/lib/std/os/linux/tls.zig index d956266114..6d61e60e95 100644 --- a/lib/std/os/linux/tls.zig +++ b/lib/std/os/linux/tls.zig @@ -327,34 +327,43 @@ pub fn prepareTLS(area: []u8) usize { if (tls_tp_points_past_tcb) tls_image.data_offset else tls_image.tcb_offset; } -var main_thread_tls_buffer: [256]u8 = undefined; +// The main motivation for the size chosen here is this is how much ends up being +// requested for the thread local variables of the std.crypto.random implementation. +// I'm not sure why it ends up being so much; the struct itself is only 64 bytes. +// I think it has to do with being page aligned and LLVM or LLD is not smart enough +// to lay out the TLS data in a space conserving way. Anyway I think it's fine +// because it's less than 3 pages of memory, and putting it in the ELF like this +// is equivalent to moving the mmap call below into the kernel, avoiding syscall +// overhead. +var main_thread_tls_buffer: [0x2100]u8 align(mem.page_size) = undefined; pub fn initStaticTLS() void { initTLS(); - const alloc_tls_area: []u8 = blk: { - const full_alloc_size = tls_image.alloc_size + tls_image.alloc_align - 1; - + const tls_area = blk: { // Fast path for the common case where the TLS data is really small, - // avoid an allocation and use our local buffer - if (full_alloc_size < main_thread_tls_buffer.len) - break :blk main_thread_tls_buffer[0..]; + // avoid an allocation and use our local buffer. + if (tls_image.alloc_align <= mem.page_size and + tls_image.alloc_size <= main_thread_tls_buffer.len) + { + break :blk main_thread_tls_buffer[0..tls_image.alloc_size]; + } - break :blk os.mmap( + const alloc_tls_area = os.mmap( null, - full_alloc_size, + tls_image.alloc_size + tls_image.alloc_align - 1, os.PROT_READ | os.PROT_WRITE, os.MAP_PRIVATE | os.MAP_ANONYMOUS, -1, 0, ) catch os.abort(); - }; - // Make sure the slice is correctly aligned - const begin_addr = @ptrToInt(alloc_tls_area.ptr); - const begin_aligned_addr = mem.alignForward(begin_addr, tls_image.alloc_align); - const start = begin_aligned_addr - begin_addr; - const tls_area = alloc_tls_area[start .. start + tls_image.alloc_size]; + // Make sure the slice is correctly aligned. + const begin_addr = @ptrToInt(alloc_tls_area.ptr); + const begin_aligned_addr = mem.alignForward(begin_addr, tls_image.alloc_align); + const start = begin_aligned_addr - begin_addr; + break :blk alloc_tls_area[start .. start + tls_image.alloc_size]; + }; const tp_value = prepareTLS(tls_area); setThreadPointer(tp_value); |
