Skip to content

Instantly share code, notes, and snippets.

View lithdew's full-sized avatar

Kenta Iwasaki lithdew

View GitHub Profile
@lithdew
lithdew / main.zig
Last active January 23, 2024 03:51
zig: basic tcp echo server w/ stdlib event loop
const std = @import("std");
const os = std.os;
const net = std.net;
const mem = std.mem;
const log = std.log.scoped(.server);
const assert = std.debug.assert;
pub const io_mode = .evented;
@lithdew
lithdew / benchmark.txt
Last active June 28, 2021 22:07
go: one shot event
$ go test -bench=. -run=NONE
goos: linux
goarch: amd64
cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkOneShotEvent-8 3904360 306.8 ns/op 8 B/op 1 allocs/op
BenchmarkChannel-8 3139602 381.7 ns/op 96 B/op 1 allocs/op
BenchmarkWaitGroup-8 2958838 408.5 ns/op 16 B/op 1 allocs/op
@lithdew
lithdew / main.zig
Last active May 23, 2021 22:24
zig: cancellation token
const std = @import("std");
const os = std.os;
const builtin = std.builtin;
const testing = std.testing;
const assert = std.debug.assert;
/// A simple cancellation framework for blocking/non-blocking tasks.
pub const Cancellation = struct {
@lithdew
lithdew / README.md
Last active February 24, 2024 01:02
Differences between Linux and Mac for sockets.
  1. A listening socket blocked on accept() can be unblocked by calling shutdown(socket_fd, SHUT_RD) on Linux. On Mac, calling shutdown(socket_fd, SHUT_RD) on a listening socket that is blocked on accept() will return an error ENOTCONN. To unblock a listening socket blocked on accept() on Mac requires calling close(socket_fd), which will cause the blocking accept() call to return an error EBADF.

Therefore, in order to unblock a socket on accept() on both Mac/Linux, shutdown() should not be relied on. Rather, an async cancellation scheme (such as cancellation tokens in .NET) should be used instead to unblock the call to accept().

  1. When a socket is instantiated and subsequently registered to epoll, or when a socket is shut down (via. shutdown() or setsockopt(SO_LINGER)) on Linux, epoll will be notified with EPOLLHUP on the socket. On Mac, kqueue will only notify when a socket is shut down (via. shutdown() or setsockopt(SO_LINGER)) by sending a EV_EOF notification on filters EVFILT_READ, and EVFILT_WRITE.

Thi

@lithdew
lithdew / x.md
Last active May 20, 2021 09:20
zig: `std.x` wishlist
  • Include std.x.os.Reactor.

A high-level I/O event reactor interface that wraps over event notification systems like epoll, kqueue.

Plan is to get epoll done first, kqueue second, select third, then iocp/afd fourth.

  • Include std.x.os.Socket.setLinger(linger_for_num_seconds: ?u16) !void.
  • Include std.x.os.Socket.getRemoteAddress() !std.x.Socket.Address.
  • Include std.x.os.Socket.setKeepAlive(enabled bool) !void.
  • Include std.x.os.Socket.(r|R)eader(flags) and std.x.os.Socket.(w|W)riter(flags).
@lithdew
lithdew / mpsc.zig
Created March 1, 2021 11:56
zig: mpsc queue
const std = @import("std");
const os = std.os;
const mem = std.mem;
const testing = std.testing;
pub fn Channel(comptime T: type) type {
return struct {
const Self = @This();
@lithdew
lithdew / disruptor.zig
Created February 21, 2021 10:23
zig: disruptor
const std = @import("std");
const mem = std.mem;
const math = std.math;
const VACANT = math.maxInt(usize);
pub fn RingBuffer(comptime T: type, comptime num_readers: comptime_int, comptime capacity: comptime_int) type {
return struct {
const Self = @This();
@lithdew
lithdew / benchmark.zig
Last active February 6, 2021 17:03
zig: open-addressing robinhood hashmap w/ backward shift deletion
// zig run benchmark.zig -lc -O ReleaseFast
const std = @import("std");
usingnamespace @import("hashmap.zig");
pub fn main() !void {
const allocator = std.heap.c_allocator;
var map = try HashMap(
@lithdew
lithdew / trie.zig
Last active January 27, 2021 08:49
zig: trie for routing
const std = @import("std");
const mem = std.mem;
const fmt = std.fmt;
const sort = std.sort;
const testing = std.testing;
pub fn Trie(comptime S: []const u8, comptime V: type) type {
return struct {
const Self = @This();
const std = @import("std");
const Pool = @import("Pool.zig");
const List = @import("DoublyLinkedList.zig");
const mem = std.mem;
const testing = std.testing;
const Group = @This();
const Child = struct {