-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
More reliable macOS event loop (#1166)
* More reliable macOS event loop * Reduce CPU usage of idling * Add another implementation * Add benchmark Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
- Loading branch information
1 parent
b2141a2
commit c1734c6
Showing
13 changed files
with
607 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { bench, run } from "../node_modules/mitata/src/cli.mjs"; | ||
|
||
bench("setTimeout(, 4) 100 times", async () => { | ||
var i = 100; | ||
while (--i >= 0) { | ||
await new Promise((resolve, reject) => { | ||
setTimeout(() => { | ||
resolve(); | ||
}, 4); | ||
}); | ||
} | ||
}); | ||
|
||
setTimeout(() => { | ||
run({}).then(() => {}); | ||
}, 1); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// most of this file is copy pasted from other files in misctools | ||
const std = @import("std"); | ||
const bun = @import("../src/global.zig"); | ||
const string = bun.string; | ||
const Output = bun.Output; | ||
const Global = bun.Global; | ||
const Environment = bun.Environment; | ||
const strings = bun.strings; | ||
const MutableString = bun.MutableString; | ||
const stringZ = bun.stringZ; | ||
const default_allocator = bun.default_allocator; | ||
const C = bun.C; | ||
const clap = @import("../src/deps/zig-clap/clap.zig"); | ||
const AsyncIO = @import("io"); | ||
|
||
const URL = @import("../src/url.zig").URL; | ||
const Headers = @import("http").Headers; | ||
const Method = @import("../src/http/method.zig").Method; | ||
const ColonListType = @import("../src/cli/colon_list_type.zig").ColonListType; | ||
const HeadersTuple = ColonListType(string, noop_resolver); | ||
const path_handler = @import("../src/resolver/resolve_path.zig"); | ||
const NetworkThread = @import("http").NetworkThread; | ||
const HTTP = @import("http"); | ||
fn noop_resolver(in: string) !string { | ||
return in; | ||
} | ||
|
||
var waker: AsyncIO.Waker = undefined; | ||
|
||
fn spamMe(count: usize) void { | ||
Output.Source.configureNamedThread("1"); | ||
defer Output.flush(); | ||
var timer = std.time.Timer.start() catch unreachable; | ||
|
||
var i: usize = 0; | ||
while (i < count) : (i += 1) { | ||
waker.wake() catch unreachable; | ||
} | ||
Output.prettyErrorln("[EVFILT_MACHPORT] Sent {any}", .{bun.fmt.fmtDuration(timer.read())}); | ||
} | ||
const thread_count = 1; | ||
pub fn machMain(runs: usize) anyerror!void { | ||
defer Output.flush(); | ||
waker = try AsyncIO.Waker.init(bun.default_allocator); | ||
|
||
var args = try std.process.argsAlloc(bun.default_allocator); | ||
const count = std.fmt.parseInt(usize, args[args.len - 1], 10) catch 1024; | ||
var elapsed: u64 = 0; | ||
|
||
var remaining_runs: usize = runs; | ||
while (remaining_runs > 0) : (remaining_runs -= 1) { | ||
var threads: [thread_count]std.Thread = undefined; | ||
var j: usize = 0; | ||
while (j < thread_count) : (j += 1) { | ||
threads[j] = try std.Thread.spawn(.{}, spamMe, .{count}); | ||
} | ||
|
||
var timer = try std.time.Timer.start(); | ||
var i: usize = 0; | ||
while (i < count * thread_count) : (i += 1) { | ||
i += try waker.wait(); | ||
} | ||
|
||
j = 0; | ||
while (j < thread_count) : (j += 1) { | ||
threads[j].join(); | ||
} | ||
elapsed += timer.read(); | ||
} | ||
|
||
Output.prettyErrorln("[EVFILT_MACHPORT] Recv {any}", .{bun.fmt.fmtDuration(elapsed)}); | ||
} | ||
var user_waker: AsyncIO.UserFilterWaker = undefined; | ||
|
||
fn spamMeUserFilter(count: usize) void { | ||
Output.Source.configureNamedThread("2"); | ||
defer Output.flush(); | ||
var timer = std.time.Timer.start() catch unreachable; | ||
var i: usize = 0; | ||
while (i < count * thread_count) : (i += 1) { | ||
user_waker.wake() catch unreachable; | ||
} | ||
|
||
Output.prettyErrorln("[EVFILT_USER] Sent {any}", .{bun.fmt.fmtDuration(timer.read())}); | ||
} | ||
pub fn userMain(runs: usize) anyerror!void { | ||
defer Output.flush(); | ||
user_waker = try AsyncIO.UserFilterWaker.init(bun.default_allocator); | ||
|
||
var args = try std.process.argsAlloc(bun.default_allocator); | ||
const count = std.fmt.parseInt(usize, args[args.len - 1], 10) catch 1024; | ||
var remaining_runs = runs; | ||
var elapsed: u64 = 0; | ||
|
||
while (remaining_runs > 0) : (remaining_runs -= 1) { | ||
var threads: [thread_count]std.Thread = undefined; | ||
var j: usize = 0; | ||
while (j < thread_count) : (j += 1) { | ||
threads[j] = try std.Thread.spawn(.{}, spamMeUserFilter, .{count}); | ||
} | ||
|
||
var timer = try std.time.Timer.start(); | ||
var i: usize = 0; | ||
while (i < count) { | ||
i += try user_waker.wait(); | ||
} | ||
|
||
j = 0; | ||
while (j < thread_count) : (j += 1) { | ||
threads[j].join(); | ||
} | ||
elapsed += timer.read(); | ||
} | ||
|
||
Output.prettyErrorln("[EVFILT_USER] Recv {any}", .{bun.fmt.fmtDuration(elapsed)}); | ||
Output.flush(); | ||
} | ||
|
||
pub fn main() anyerror!void { | ||
var stdout_ = std.io.getStdOut(); | ||
var stderr_ = std.io.getStdErr(); | ||
var output_source = Output.Source.init(stdout_, stderr_); | ||
Output.Source.set(&output_source); | ||
|
||
var args = try std.process.argsAlloc(bun.default_allocator); | ||
const count = std.fmt.parseInt(usize, args[args.len - 1], 10) catch 1024; | ||
Output.prettyErrorln("For {d} messages and {d} threads:", .{ count, thread_count }); | ||
Output.flush(); | ||
defer Output.flush(); | ||
const runs = if (std.os.getenv("RUNS")) |run_count| try std.fmt.parseInt(usize, run_count, 10) else 1; | ||
|
||
if (std.os.getenv("NO_MACH") == null) | ||
try machMain(runs); | ||
|
||
if (std.os.getenv("NO_USER") == null) | ||
try userMain(runs); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.