Commit 129714d077

Andrew Kelley <andrew@ziglang.org>
2019-05-27 07:35:58
more fixes for windows and wasi
1 parent 6be79d7
std/event/loop.zig
@@ -32,7 +32,7 @@ pub const Loop = struct {
         overlapped: Overlapped,
 
         pub const overlapped_init = switch (builtin.os) {
-            builtin.Os.windows => windows.OVERLAPPED{
+            .windows => windows.OVERLAPPED{
                 .Internal = 0,
                 .InternalHigh = 0,
                 .Offset = 0,
@@ -50,13 +50,13 @@ pub const Loop = struct {
         };
 
         pub const EventFd = switch (builtin.os) {
-            builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => KEventFd,
-            builtin.Os.linux => struct {
+            .macosx, .freebsd, .netbsd => KEventFd,
+            .linux => struct {
                 base: ResumeNode,
                 epoll_op: u32,
                 eventfd: i32,
             },
-            builtin.Os.windows => struct {
+            .windows => struct {
                 base: ResumeNode,
                 completion_key: usize,
             },
@@ -69,11 +69,11 @@ pub const Loop = struct {
         };
 
         pub const Basic = switch (builtin.os) {
-            builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => KEventBasic,
-            builtin.Os.linux => struct {
+            .macosx, .freebsd, .netbsd => KEventBasic,
+            .linux => struct {
                 base: ResumeNode,
             },
-            builtin.Os.windows => struct {
+            .windows => struct {
                 base: ResumeNode,
             },
             else => @compileError("unsupported OS"),
@@ -147,7 +147,7 @@ pub const Loop = struct {
 
     fn initOsData(self: *Loop, extra_thread_count: usize) InitOsDataError!void {
         switch (builtin.os) {
-            builtin.Os.linux => {
+            .linux => {
                 self.os_data.fs_queue = std.atomic.Queue(fs.Request).init();
                 self.os_data.fs_queue_item = 0;
                 // we need another thread for the file system because Linux does not have an async
@@ -221,7 +221,7 @@ pub const Loop = struct {
                     self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun);
                 }
             },
-            builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => {
+            .macosx, .freebsd, .netbsd => {
                 self.os_data.kqfd = try os.bsdKQueue();
                 errdefer os.close(self.os_data.kqfd);
 
@@ -325,14 +325,14 @@ pub const Loop = struct {
                     self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun);
                 }
             },
-            builtin.Os.windows => {
-                self.os_data.io_port = try os.windowsCreateIoCompletionPort(
+            .windows => {
+                self.os_data.io_port = try windows.CreateIoCompletionPort(
                     windows.INVALID_HANDLE_VALUE,
                     null,
                     undefined,
                     maxInt(windows.DWORD),
                 );
-                errdefer os.close(self.os_data.io_port);
+                errdefer windows.CloseHandle(self.os_data.io_port);
 
                 for (self.eventfd_resume_nodes) |*eventfd_node, i| {
                     eventfd_node.* = std.atomic.Stack(ResumeNode.EventFd).Node{
@@ -361,7 +361,7 @@ pub const Loop = struct {
                     while (i < extra_thread_index) : (i += 1) {
                         while (true) {
                             const overlapped = &self.final_resume_node.overlapped;
-                            os.windowsPostQueuedCompletionStatus(self.os_data.io_port, undefined, undefined, overlapped) catch continue;
+                            windows.PostQueuedCompletionStatus(self.os_data.io_port, undefined, undefined, overlapped) catch continue;
                             break;
                         }
                     }
@@ -380,18 +380,18 @@ pub const Loop = struct {
 
     fn deinitOsData(self: *Loop) void {
         switch (builtin.os) {
-            builtin.Os.linux => {
+            .linux => {
                 os.close(self.os_data.final_eventfd);
                 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
                 os.close(self.os_data.epollfd);
                 self.allocator.free(self.eventfd_resume_nodes);
             },
-            builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => {
+            .macosx, .freebsd, .netbsd => {
                 os.close(self.os_data.kqfd);
                 os.close(self.os_data.fs_kqfd);
             },
-            builtin.Os.windows => {
-                os.close(self.os_data.io_port);
+            .windows => {
+                windows.CloseHandle(self.os_data.io_port);
             },
             else => {},
         }
@@ -501,7 +501,7 @@ pub const Loop = struct {
             const eventfd_node = &resume_stack_node.data;
             eventfd_node.base.handle = next_tick_node.data;
             switch (builtin.os) {
-                builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => {
+                .macosx, .freebsd, .netbsd => {
                     const kevent_array = (*const [1]os.Kevent)(&eventfd_node.kevent);
                     const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
                     _ = os.bsdKEvent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
@@ -510,7 +510,7 @@ pub const Loop = struct {
                         return;
                     };
                 },
-                builtin.Os.linux => {
+                .linux => {
                     // the pending count is already accounted for
                     const epoll_events = os.EPOLLONESHOT | os.linux.EPOLLIN | os.linux.EPOLLOUT |
                         os.linux.EPOLLET;
@@ -525,8 +525,8 @@ pub const Loop = struct {
                         return;
                     };
                 },
-                builtin.Os.windows => {
-                    os.windowsPostQueuedCompletionStatus(
+                .windows => {
+                    windows.PostQueuedCompletionStatus(
                         self.os_data.io_port,
                         undefined,
                         undefined,
@@ -623,13 +623,13 @@ pub const Loop = struct {
         if (prev == 1) {
             // cause all the threads to stop
             switch (builtin.os) {
-                builtin.Os.linux => {
+                .linux => {
                     self.posixFsRequest(&self.os_data.fs_end_request);
                     // writing 8 bytes to an eventfd cannot fail
                     os.write(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
                     return;
                 },
-                builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => {
+                .macosx, .freebsd, .netbsd => {
                     self.posixFsRequest(&self.os_data.fs_end_request);
                     const final_kevent = (*const [1]os.Kevent)(&self.os_data.final_kevent);
                     const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
@@ -637,12 +637,12 @@ pub const Loop = struct {
                     _ = os.bsdKEvent(self.os_data.kqfd, final_kevent, empty_kevs, null) catch unreachable;
                     return;
                 },
-                builtin.Os.windows => {
+                .windows => {
                     var i: usize = 0;
                     while (i < self.extra_threads.len + 1) : (i += 1) {
                         while (true) {
                             const overlapped = &self.final_resume_node.overlapped;
-                            os.windowsPostQueuedCompletionStatus(self.os_data.io_port, undefined, undefined, overlapped) catch continue;
+                            windows.PostQueuedCompletionStatus(self.os_data.io_port, undefined, undefined, overlapped) catch continue;
                             break;
                         }
                     }
@@ -663,7 +663,7 @@ pub const Loop = struct {
             }
 
             switch (builtin.os) {
-                builtin.Os.linux => {
+                .linux => {
                     // only process 1 event so we don't steal from other threads
                     var events: [1]os.linux.epoll_event = undefined;
                     const count = os.epoll_wait(self.os_data.epollfd, events[0..], -1);
@@ -687,7 +687,7 @@ pub const Loop = struct {
                         }
                     }
                 },
-                builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => {
+                .macosx, .freebsd, .netbsd => {
                     var eventlist: [1]os.Kevent = undefined;
                     const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
                     const count = os.bsdKEvent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
@@ -713,16 +713,16 @@ pub const Loop = struct {
                         }
                     }
                 },
-                builtin.Os.windows => {
+                .windows => {
                     var completion_key: usize = undefined;
                     const overlapped = while (true) {
                         var nbytes: windows.DWORD = undefined;
                         var overlapped: ?*windows.OVERLAPPED = undefined;
-                        switch (os.windowsGetQueuedCompletionStatus(self.os_data.io_port, &nbytes, &completion_key, &overlapped, windows.INFINITE)) {
-                            os.WindowsWaitResult.Aborted => return,
-                            os.WindowsWaitResult.Normal => {},
-                            os.WindowsWaitResult.EOF => {},
-                            os.WindowsWaitResult.Cancelled => continue,
+                        switch (windows.GetQueuedCompletionStatus(self.os_data.io_port, &nbytes, &completion_key, &overlapped, windows.INFINITE)) {
+                            .Aborted => return,
+                            .Normal => {},
+                            .EOF => {},
+                            .Cancelled => continue,
                         }
                         if (overlapped) |o| break o;
                     } else unreachable; // TODO else unreachable should not be necessary
@@ -831,9 +831,9 @@ pub const Loop = struct {
     }
 
     const OsData = switch (builtin.os) {
-        builtin.Os.linux => LinuxOsData,
-        builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => KEventData,
-        builtin.Os.windows => struct {
+        .linux => LinuxOsData,
+        .macosx, .freebsd, .netbsd => KEventData,
+        .windows => struct {
             io_port: windows.HANDLE,
             extra_thread_count: usize,
         },
std/fs/get_app_data_dir.zig
@@ -23,7 +23,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
                 &dir_path_ptr,
             )) {
                 os.windows.S_OK => {
-                    defer os.windows.CoTaskMemFree(@ptrCast(*c_void, dir_path_ptr));
+                    defer os.windows.ole32.CoTaskMemFree(@ptrCast(*c_void, dir_path_ptr));
                     const global_dir = unicode.utf16leToUtf8Alloc(allocator, utf16lePtrSlice(dir_path_ptr)) catch |err| switch (err) {
                         error.UnexpectedSecondSurrogateHalf => return error.AppDataDirUnavailable,
                         error.ExpectedSecondSurrogateHalf => return error.AppDataDirUnavailable,
std/os/bits/wasi.zig
@@ -1,5 +1,3 @@
-use @import("../bits.zig");
-
 pub const STDIN_FILENO = 0;
 pub const STDOUT_FILENO = 1;
 pub const STDERR_FILENO = 2;
@@ -12,8 +10,6 @@ pub const ADVICE_WILLNEED: advice_t = 3;
 pub const ADVICE_DONTNEED: advice_t = 4;
 pub const ADVICE_NOREUSE: advice_t = 5;
 
-pub const ciovec_t = iovec_const;
-
 pub const clockid_t = u32;
 pub const CLOCK_REALTIME: clockid_t = 0;
 pub const CLOCK_MONOTONIC: clockid_t = 1;
@@ -182,8 +178,6 @@ pub const FILESTAT_SET_MTIM_NOW: fstflags_t = 0x0008;
 
 pub const inode_t = u64;
 
-pub const iovec_t = iovec;
-
 pub const linkcount_t = u32;
 
 pub const lookupflags_t = u32;
std/os/bits/windows.zig
@@ -5,6 +5,13 @@ use @import("../windows/bits.zig");
 pub const fd_t = HANDLE;
 pub const pid_t = HANDLE;
 
+pub const time_t = c_longlong;
+
+pub const timespec = extern struct {
+    tv_sec: time_t,
+    tv_nsec: c_long,
+};
+
 pub const sig_atomic_t = c_int;
 
 /// maximum signal number + 1
@@ -153,3 +160,4 @@ pub const EWOULDBLOCK = 140;
 pub const SIGKILL = @compileError("Windows libc does not have this");
 pub const EDQUOT = @compileError("Windows libc does not have this");
 pub const TIOCGWINSZ = @compileError("Windows libc does not have this");
+pub const F_OK = 0;
std/os/wasi.zig
@@ -5,7 +5,7 @@ const std = @import("std");
 const assert = std.debug.assert;
 
 pub const is_the_target = builtin.os == .wasi;
-pub use @import("bits/wasi.zig");
+pub use @import("bits.zig");
 
 comptime {
     assert(@alignOf(i8) == 1);
@@ -18,6 +18,9 @@ comptime {
     assert(@alignOf(u64) == 8);
 }
 
+pub const iovec_t = iovec;
+pub const ciovec_t = iovec_const;
+
 pub extern "wasi_unstable" fn args_get(argv: [*][*]u8, argv_buf: [*]u8) errno_t;
 pub extern "wasi_unstable" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
 
std/os/windows.zig
@@ -134,6 +134,9 @@ pub fn WaitForSingleObject(handle: HANDLE, milliseconds: DWORD) WaitForSingleObj
 
 pub const FindFirstFileError = error{
     FileNotFound,
+    InvalidUtf8,
+    BadPathName,
+    NameTooLong,
     Unexpected,
 };
 
@@ -192,7 +195,7 @@ pub fn PostQueuedCompletionStatus(
 ) PostQueuedCompletionStatusError!void {
     if (kernel32.PostQueuedCompletionStatus(completion_port, bytes_transferred_count, completion_key, lpOverlapped) == 0) {
         switch (kernel32.GetLastError()) {
-            else => return unexpectedError(err),
+            else => |err| return unexpectedError(err),
         }
     }
 }
@@ -350,7 +353,7 @@ pub fn DeleteFile(filename: []const u8) DeleteFileError!void {
 }
 
 pub fn DeleteFileW(filename: [*]const u16) DeleteFileError!void {
-    if (kernel32.DeleteFileW(file_path) == 0) {
+    if (kernel32.DeleteFileW(filename) == 0) {
         switch (kernel32.GetLastError()) {
             ERROR.FILE_NOT_FOUND => return error.FileNotFound,
             ERROR.ACCESS_DENIED => return error.AccessDenied,
@@ -501,7 +504,7 @@ pub fn GetFinalPathNameByHandleW(
     buf_len: DWORD,
     flags: DWORD,
 ) GetFinalPathNameByHandleError!DWORD {
-    const rc = kernel32.GetFinalPathNameByHandleW(h_file, buf_ptr, buf.len, flags);
+    const rc = kernel32.GetFinalPathNameByHandleW(hFile, buf_ptr, buf_len, flags);
     if (rc == 0) {
         switch (kernel32.GetLastError()) {
             ERROR.FILE_NOT_FOUND => return error.FileNotFound,
@@ -539,7 +542,7 @@ pub fn GetFileAttributes(filename: []const u8) GetFileAttributesError!DWORD {
 }
 
 pub fn GetFileAttributesW(lpFileName: [*]const u16) GetFileAttributesError!DWORD {
-    const rc = kernel32.GetFileAttributesW(path);
+    const rc = kernel32.GetFileAttributesW(lpFileName);
     if (rc == INVALID_FILE_ATTRIBUTES) {
         switch (kernel32.GetLastError()) {
             ERROR.FILE_NOT_FOUND => return error.FileNotFound,
@@ -705,6 +708,14 @@ pub fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter
     assert(kernel32.InitOnceExecuteOnce(InitOnce, InitFn, Parameter, Context) != 0);
 }
 
+pub fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) void {
+    assert(kernel32.HeapFree(hHeap, dwFlags, lpMem) != 0);
+}
+
+pub fn HeapDestroy(hHeap: HANDLE) void {
+    assert(kernel32.HeapDestroy(hHeap) != 0);
+}
+
 pub fn cStrToPrefixedFileW(s: [*]const u8) ![PATH_MAX_WIDE + 1]u16 {
     return sliceToPrefixedFileW(mem.toSliceConst(u8, s));
 }
std/os/epoch.zig → std/time/epoch.zig
File renamed without changes
std/heap.zig
@@ -261,7 +261,7 @@ pub const HeapAllocator = switch (builtin.os) {
 
         pub fn deinit(self: *HeapAllocator) void {
             if (self.heap_handle) |heap_handle| {
-                _ = os.windows.HeapDestroy(heap_handle);
+                os.windows.HeapDestroy(heap_handle);
             }
         }
 
@@ -274,12 +274,12 @@ pub const HeapAllocator = switch (builtin.os) {
             const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, builtin.AtomicOrder.SeqCst);
             const heap_handle = optional_heap_handle orelse blk: {
                 const options = if (builtin.single_threaded) os.windows.HEAP_NO_SERIALIZE else 0;
-                const hh = os.windows.HeapCreate(options, amt, 0) orelse return error.OutOfMemory;
+                const hh = os.windows.kernel32.HeapCreate(options, amt, 0) orelse return error.OutOfMemory;
                 const other_hh = @cmpxchgStrong(?HeapHandle, &self.heap_handle, null, hh, builtin.AtomicOrder.SeqCst, builtin.AtomicOrder.SeqCst) orelse break :blk hh;
-                _ = os.windows.HeapDestroy(hh);
+                os.windows.HeapDestroy(hh);
                 break :blk other_hh.?; // can't be null because of the cmpxchg
             };
-            const ptr = os.windows.HeapAlloc(heap_handle, 0, amt) orelse return error.OutOfMemory;
+            const ptr = os.windows.kernel32.HeapAlloc(heap_handle, 0, amt) orelse return error.OutOfMemory;
             const root_addr = @ptrToInt(ptr);
             const adjusted_addr = mem.alignForward(root_addr, alignment);
             const record_addr = adjusted_addr + n;
@@ -309,12 +309,12 @@ pub const HeapAllocator = switch (builtin.os) {
             const old_ptr = @intToPtr(*c_void, root_addr);
 
             if (new_size == 0) {
-                if (os.windows.HeapFree(self.heap_handle.?, 0, old_ptr) == 0) unreachable;
+                os.windows.HeapFree(self.heap_handle.?, 0, old_ptr);
                 return old_mem[0..0];
             }
 
             const amt = new_size + new_align + @sizeOf(usize);
-            const new_ptr = os.windows.HeapReAlloc(
+            const new_ptr = os.windows.kernel32.HeapReAlloc(
                 self.heap_handle.?,
                 0,
                 old_ptr,
std/os.zig
@@ -944,7 +944,7 @@ pub fn renameC(old_path: [*]const u8, new_path: [*]const u8) RenameError!void {
 /// Assumes target is Windows.
 pub fn renameW(old_path: [*]const u16, new_path: [*]const u16) RenameError!void {
     const flags = windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH;
-    return windows.MoveFileExW(old_path_w, new_path_w, flags);
+    return windows.MoveFileExW(old_path, new_path, flags);
 }
 
 pub const MakeDirError = error{
@@ -959,6 +959,8 @@ pub const MakeDirError = error{
     NoSpaceLeft,
     NotDir,
     ReadOnlyFileSystem,
+    InvalidUtf8,
+    BadPathName,
     Unexpected,
 };
 
@@ -2227,6 +2229,9 @@ pub const RealPathError = error{
     BadPathName,
     DeviceBusy,
 
+    SharingViolation,
+    PipeBusy,
+
     /// On Windows, file paths must be valid Unicode.
     InvalidUtf8,
 
@@ -2294,7 +2299,7 @@ pub fn realpathW(pathname: [*]const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPa
     var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined;
     const wide_len = try windows.GetFinalPathNameByHandleW(h_file, &wide_buf, wide_buf.len, windows.VOLUME_NAME_DOS);
     assert(wide_len <= wide_buf.len);
-    const wide_slice = wide_len[0..wide_len];
+    const wide_slice = wide_buf[0..wide_len];
 
     // Windows returns \\?\ prepended to the path.
     // We strip it to make this function consistent across platforms.
@@ -2311,13 +2316,13 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
     if (windows.is_the_target and !builtin.link_libc) {
         // TODO https://github.com/ziglang/zig/issues/1284
         const small_s = math.cast(windows.DWORD, seconds) catch math.maxInt(windows.DWORD);
-        const ms_from_s = math.mul(small_s, std.time.ms_per_s) catch math.maxInt(windows.DWORD);
+        const ms_from_s = math.mul(windows.DWORD, small_s, std.time.ms_per_s) catch math.maxInt(windows.DWORD);
 
         const ns_per_ms = std.time.ns_per_s / std.time.ms_per_s;
         const big_ms_from_ns = nanoseconds / ns_per_ms;
         const ms_from_ns = math.cast(windows.DWORD, big_ms_from_ns) catch math.maxInt(windows.DWORD);
 
-        const ms = math.add(ms_from_s, ms_from_ns) catch math.maxInt(windows.DWORD);
+        const ms = math.add(windows.DWORD, ms_from_s, ms_from_ns) catch math.maxInt(windows.DWORD);
         windows.kernel32.Sleep(ms);
         return;
     }
std/thread.zig
@@ -57,7 +57,7 @@ pub const Thread = struct {
         } else
             return switch (builtin.os) {
             .linux => os.linux.gettid(),
-            .windows => windows.GetCurrentThreadId(),
+            .windows => windows.kernel32.GetCurrentThreadId(),
             else => @compileError("Unsupported OS"),
         };
     }
@@ -99,9 +99,9 @@ pub const Thread = struct {
                 os.munmap(self.data.memory);
             },
             .windows => {
-                assert(windows.WaitForSingleObject(self.data.handle, windows.INFINITE) == windows.WAIT_OBJECT_0);
-                assert(windows.CloseHandle(self.data.handle) != 0);
-                assert(windows.HeapFree(self.data.heap_handle, 0, self.data.alloc_start) != 0);
+                windows.WaitForSingleObject(self.data.handle, windows.INFINITE) catch unreachable;
+                windows.CloseHandle(self.data.handle);
+                windows.HeapFree(self.data.heap_handle, 0, self.data.alloc_start);
             },
             else => @compileError("Unsupported OS"),
         }
@@ -171,10 +171,10 @@ pub const Thread = struct {
                 }
             };
 
-            const heap_handle = windows.GetProcessHeap() orelse return error.OutOfMemory;
+            const heap_handle = windows.kernel32.GetProcessHeap() orelse return error.OutOfMemory;
             const byte_count = @alignOf(WinThread.OuterContext) + @sizeOf(WinThread.OuterContext);
-            const bytes_ptr = windows.HeapAlloc(heap_handle, 0, byte_count) orelse return error.OutOfMemory;
-            errdefer assert(windows.HeapFree(heap_handle, 0, bytes_ptr) != 0);
+            const bytes_ptr = windows.kernel32.HeapAlloc(heap_handle, 0, byte_count) orelse return error.OutOfMemory;
+            errdefer assert(windows.kernel32.HeapFree(heap_handle, 0, bytes_ptr) != 0);
             const bytes = @ptrCast([*]u8, bytes_ptr)[0..byte_count];
             const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext) catch unreachable;
             outer_context.* = WinThread.OuterContext{
@@ -189,9 +189,9 @@ pub const Thread = struct {
             };
 
             const parameter = if (@sizeOf(Context) == 0) null else @ptrCast(*c_void, &outer_context.inner);
-            outer_context.thread.data.handle = windows.CreateThread(null, default_stack_size, WinThread.threadMain, parameter, 0, null) orelse {
-                switch (windows.GetLastError()) {
-                    else => |err| windows.unexpectedError(err),
+            outer_context.thread.data.handle = windows.kernel32.CreateThread(null, default_stack_size, WinThread.threadMain, parameter, 0, null) orelse {
+                switch (windows.kernel32.GetLastError()) {
+                    else => |err| return windows.unexpectedError(err),
                 }
             };
             return &outer_context.thread;
@@ -333,7 +333,7 @@ pub const Thread = struct {
         }
         if (os.windows.is_the_target) {
             var system_info: windows.SYSTEM_INFO = undefined;
-            windows.GetSystemInfo(&system_info);
+            windows.kernel32.GetSystemInfo(&system_info);
             return @intCast(usize, system_info.dwNumberOfProcessors);
         }
         var count: c_int = undefined;
std/time.zig
@@ -4,7 +4,7 @@ const assert = std.debug.assert;
 const testing = std.testing;
 const os = std.os;
 
-pub const epoch = @import("epoch.zig");
+pub const epoch = @import("time/epoch.zig");
 
 /// Spurious wakeups are possible and no precision of timing is guaranteed.
 pub fn sleep(nanoseconds: u64) void {
CMakeLists.txt
@@ -616,7 +616,6 @@ set(ZIG_STD_FILES
     "os/bits/wasi.zig"
     "os/bits/windows.zig"
     "os/darwin.zig"
-    "os/epoch.zig"
     "os/freebsd.zig"
     "os/linux.zig"
     "os/linux/arm64.zig"
@@ -723,6 +722,7 @@ set(ZIG_STD_FILES
     "testing.zig"
     "thread.zig"
     "time.zig"
+    "time/epoch.zig"
     "unicode.zig"
     "valgrind.zig"
     "valgrind/callgrind.zig"