@zigc/lib 0.17.0-dev.9 → 0.17.0-dev.93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/c/fcntl.zig +6 -1
  2. package/c/inttypes.zig +0 -10
  3. package/c/math.zig +46 -122
  4. package/c/search.zig +1 -27
  5. package/c/stdlib/drand48.zig +0 -57
  6. package/c/stdlib.zig +0 -100
  7. package/c/string.zig +0 -7
  8. package/c/strings.zig +0 -38
  9. package/c/unistd.zig +27 -26
  10. package/c.zig +1 -2
  11. package/compiler/aro/aro/CodeGen.zig +3 -2
  12. package/compiler/aro/aro/Compilation.zig +15 -12
  13. package/compiler/aro/aro/Driver.zig +9 -6
  14. package/compiler/aro/aro/Parser.zig +18 -12
  15. package/compiler/aro/aro/Pragma.zig +3 -2
  16. package/compiler/aro/aro/Preprocessor.zig +9 -6
  17. package/compiler/aro/aro/pragmas/message.zig +3 -2
  18. package/compiler/aro/aro/text_literal.zig +3 -2
  19. package/compiler/aro/assembly_backend/x86_64.zig +3 -2
  20. package/compiler/build_runner.zig +0 -2
  21. package/compiler/test_runner.zig +1 -1
  22. package/compiler/translate-c/Translator.zig +4 -0
  23. package/compiler_rt/cos.zig +0 -2
  24. package/compiler_rt/divmodei4.zig +40 -17
  25. package/compiler_rt/exp.zig +1 -6
  26. package/compiler_rt/exp2.zig +1 -6
  27. package/compiler_rt/exp_f128.zig +377 -0
  28. package/compiler_rt/fabs.zig +0 -2
  29. package/compiler_rt/fma.zig +0 -2
  30. package/compiler_rt/fmax.zig +0 -2
  31. package/compiler_rt/fmin.zig +0 -2
  32. package/compiler_rt/fmod.zig +0 -2
  33. package/compiler_rt/limb64.zig +876 -15
  34. package/compiler_rt/log.zig +0 -2
  35. package/compiler_rt/log10.zig +0 -2
  36. package/compiler_rt/log2.zig +0 -2
  37. package/compiler_rt/mulXi3.zig +1 -1
  38. package/compiler_rt/round.zig +0 -2
  39. package/compiler_rt/sin.zig +0 -2
  40. package/compiler_rt/sincos.zig +0 -2
  41. package/compiler_rt/sqrt.zig +0 -2
  42. package/compiler_rt/ssp.zig +1 -1
  43. package/compiler_rt/tan.zig +0 -2
  44. package/compiler_rt/trunc.zig +0 -2
  45. package/compiler_rt/udivmodei4.zig +28 -0
  46. package/fuzzer.zig +2 -0
  47. package/libc/musl/arch/mipsn32/syscall_arch.h +35 -32
  48. package/package.json +1 -1
  49. package/std/Build/Step/Compile.zig +0 -1
  50. package/std/Build.zig +0 -3
  51. package/std/Io/Dispatch.zig +3 -13
  52. package/std/Io/Semaphore.zig +112 -17
  53. package/std/Io/Threaded.zig +167 -33
  54. package/std/Io/Uring.zig +12 -14
  55. package/std/Io/Writer.zig +46 -42
  56. package/std/Io/net.zig +11 -11
  57. package/std/Io.zig +89 -25
  58. package/std/Target.zig +50 -5
  59. package/std/builtin.zig +4 -0
  60. package/std/c/haiku.zig +3 -0
  61. package/std/c/serenity.zig +1 -6
  62. package/std/c.zig +59 -6
  63. package/std/debug.zig +4 -3
  64. package/std/fmt.zig +7 -2
  65. package/std/fs/path.zig +6 -4
  66. package/std/heap/BufferFirstAllocator.zig +165 -0
  67. package/std/heap.zig +2 -126
  68. package/std/http/Client.zig +21 -24
  69. package/std/os/linux/aarch64.zig +41 -12
  70. package/std/os/linux/arc.zig +41 -12
  71. package/std/os/linux/arm.zig +41 -12
  72. package/std/os/linux/hexagon.zig +33 -11
  73. package/std/os/linux/loongarch32.zig +41 -13
  74. package/std/os/linux/loongarch64.zig +41 -12
  75. package/std/os/linux/m68k.zig +41 -13
  76. package/std/os/linux/mips.zig +67 -36
  77. package/std/os/linux/mips64.zig +60 -29
  78. package/std/os/linux/mipsn32.zig +60 -29
  79. package/std/os/linux/or1k.zig +41 -12
  80. package/std/os/linux/powerpc.zig +41 -12
  81. package/std/os/linux/powerpc64.zig +41 -12
  82. package/std/os/linux/riscv32.zig +41 -12
  83. package/std/os/linux/riscv64.zig +41 -12
  84. package/std/os/linux/s390x.zig +44 -7
  85. package/std/os/linux/sparc64.zig +83 -52
  86. package/std/os/linux/thumb.zig +52 -36
  87. package/std/os/linux/x32.zig +41 -12
  88. package/std/os/linux/x86.zig +42 -13
  89. package/std/os/linux/x86_64.zig +41 -12
  90. package/std/os/linux.zig +398 -434
  91. package/std/os.zig +41 -0
  92. package/std/sort.zig +3 -3
  93. package/std/zig/AstGen.zig +22 -92
  94. package/std/zig/AstRlAnnotate.zig +0 -11
  95. package/std/zig/BuiltinFn.zig +0 -32
  96. package/std/zig/LibCInstallation.zig +1 -0
  97. package/std/zig/Zir.zig +50 -63
  98. package/std/zig/ZonGen.zig +5 -4
  99. package/std/zig/llvm/Builder.zig +12 -12
  100. package/std/zig.zig +0 -10
  101. package/zig.h +340 -1
  102. package/libc/mingw/math/fdiml.c +0 -24
  103. package/libc/musl/src/linux/tee.c +0 -8
  104. package/libc/musl/src/math/fdimf.c +0 -10
  105. package/libc/musl/src/math/fdiml.c +0 -18
  106. package/libc/musl/src/unistd/dup2.c +0 -20
  107. package/libc/musl/src/unistd/dup3.c +0 -26
@@ -443,8 +443,6 @@ pub fn logq(a: f128) callconv(.c) f128 {
443
443
 
444
444
  pub fn logl(x: c_longdouble) callconv(.c) c_longdouble {
445
445
  switch (@typeInfo(c_longdouble).float.bits) {
446
- 16 => return __logh(x),
447
- 32 => return logf(x),
448
446
  64 => return log(x),
449
447
  80 => return __logx(x),
450
448
  128 => return logq(x),
@@ -177,8 +177,6 @@ pub fn log10q(a: f128) callconv(.c) f128 {
177
177
 
178
178
  pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble {
179
179
  switch (@typeInfo(c_longdouble).float.bits) {
180
- 16 => return __log10h(x),
181
- 32 => return log10f(x),
182
180
  64 => return log10(x),
183
181
  80 => return __log10x(x),
184
182
  128 => return log10q(x),
@@ -170,8 +170,6 @@ pub fn log2q(a: f128) callconv(.c) f128 {
170
170
 
171
171
  pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble {
172
172
  switch (@typeInfo(c_longdouble).float.bits) {
173
- 16 => return __log2h(x),
174
- 32 => return log2f(x),
175
173
  64 => return log2(x),
176
174
  80 => return __log2x(x),
177
175
  128 => return log2q(x),
@@ -63,7 +63,7 @@ fn DoubleInt(comptime T: type) type {
63
63
  };
64
64
  }
65
65
 
66
- fn muldXi(comptime T: type, a: T, b: T) DoubleInt(T) {
66
+ pub fn muldXi(comptime T: type, a: T, b: T) DoubleInt(T) {
67
67
  const DT = DoubleInt(T);
68
68
  const word_t = compiler_rt.HalveInt(DT, false);
69
69
  const bits_in_word_2 = @sizeOf(T) * 8 / 2;
@@ -142,8 +142,6 @@ pub fn roundq(x_: f128) callconv(.c) f128 {
142
142
 
143
143
  pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble {
144
144
  switch (@typeInfo(c_longdouble).float.bits) {
145
- 16 => return __roundh(x),
146
- 32 => return roundf(x),
147
145
  64 => return round(x),
148
146
  80 => return __roundx(x),
149
147
  128 => return roundq(x),
@@ -189,8 +189,6 @@ pub fn sinq(x: f128) callconv(.c) f128 {
189
189
 
190
190
  pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble {
191
191
  switch (@typeInfo(c_longdouble).float.bits) {
192
- 16 => return sinh(x),
193
- 32 => return sinf(x),
194
192
  64 => return sin(x),
195
193
  80 => return sinx(x),
196
194
  128 => return sinq(x),
@@ -292,8 +292,6 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void {
292
292
 
293
293
  pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void {
294
294
  switch (@typeInfo(c_longdouble).float.bits) {
295
- 16 => return sincosh(x, r_sin, r_cos),
296
- 32 => return sincosf(x, r_sin, r_cos),
297
295
  64 => return sincos(x, r_sin, r_cos),
298
296
  80 => return sincosx(x, r_sin, r_cos),
299
297
  128 => return sincosq(x, r_sin, r_cos),
@@ -481,8 +481,6 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void {
481
481
 
482
482
  pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble {
483
483
  switch (@typeInfo(c_longdouble).float.bits) {
484
- 16 => return __sqrth(x),
485
- 32 => return sqrtf(x),
486
484
  64 => return sqrt(x),
487
485
  80 => return __sqrtx(x),
488
486
  128 => return sqrtq(x),
@@ -24,7 +24,7 @@ extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.c) ?[*]u8
24
24
  comptime {
25
25
  @export(&__stack_chk_fail, .{ .name = if (builtin.os.tag == .openbsd) "__stack_smash_handler" else "__stack_chk_fail", .linkage = compiler_rt.linkage, .visibility = compiler_rt.visibility });
26
26
  symbol(&__chk_fail, "__chk_fail");
27
- symbol(&__stack_chk_guard, "__stack_chk_guard");
27
+ symbol(&__stack_chk_guard, if (builtin.os.tag == .openbsd) "__guard_local" else "__stack_chk_guard");
28
28
  symbol(&__strcpy_chk, "__strcpy_chk");
29
29
  symbol(&__strncpy_chk, "__strncpy_chk");
30
30
  symbol(&__strcat_chk, "__strcat_chk");
@@ -164,8 +164,6 @@ pub fn tanq(x: f128) callconv(.c) f128 {
164
164
 
165
165
  pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble {
166
166
  switch (@typeInfo(c_longdouble).float.bits) {
167
- 16 => return tanh(x),
168
- 32 => return tanf(x),
169
167
  64 => return tan(x),
170
168
  80 => return tanx(x),
171
169
  128 => return tanq(x),
@@ -99,8 +99,6 @@ pub fn truncq(x: f128) callconv(.c) f128 {
99
99
 
100
100
  pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble {
101
101
  switch (@typeInfo(c_longdouble).float.bits) {
102
- 16 => return __trunch(x),
103
- 32 => return truncf(x),
104
102
  64 => return trunc(x),
105
103
  80 => return __truncx(x),
106
104
  128 => return truncq(x),
@@ -13,6 +13,8 @@ const max_limbs = std.math.divCeil(usize, 65535, 32) catch unreachable; // max s
13
13
  comptime {
14
14
  symbol(&__udivei4, "__udivei4");
15
15
  symbol(&__umodei4, "__umodei4");
16
+ symbol(&__udivei5, "__udivei5");
17
+ symbol(&__umodei5, "__umodei5");
16
18
  }
17
19
 
18
20
  /// Get the value of a limb.
@@ -132,6 +134,32 @@ pub fn __umodei4(r_p: [*]u8, u_p: [*]const u8, v_p: [*]const u8, bits: usize) ca
132
134
  @call(.always_inline, divmod, .{ null, r, u, v }) catch unreachable;
133
135
  }
134
136
 
137
+ pub fn __udivei5(q_p: [*]u8, u_p: [*]const u8, v_p: [*]const u8, t_p: [*]u8, bits: usize) callconv(.c) void {
138
+ @setRuntimeSafety(compiler_rt.test_safety);
139
+ const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
140
+ const q: []u32 = @ptrCast(@alignCast(q_p[0..byte_size]));
141
+ const u: []const u32 = @ptrCast(@alignCast(u_p[0..byte_size]));
142
+ const v: []const u32 = @ptrCast(@alignCast(v_p[0..byte_size]));
143
+ const tu: []u32 = @ptrCast(@alignCast(t_p[0..byte_size]));
144
+ _ = tu;
145
+ const tv: []u32 = @ptrCast(@alignCast(t_p[byte_size..][0..byte_size]));
146
+ _ = tv;
147
+ @call(.always_inline, divmod, .{ q, null, u, v }) catch unreachable;
148
+ }
149
+
150
+ pub fn __umodei5(r_p: [*]u8, u_p: [*]const u8, v_p: [*]const u8, t_p: [*]u8, bits: usize) callconv(.c) void {
151
+ @setRuntimeSafety(compiler_rt.test_safety);
152
+ const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits));
153
+ const r: []u32 = @ptrCast(@alignCast(r_p[0..byte_size]));
154
+ const u: []const u32 = @ptrCast(@alignCast(u_p[0..byte_size]));
155
+ const v: []const u32 = @ptrCast(@alignCast(v_p[0..byte_size]));
156
+ const tu: []u32 = @ptrCast(@alignCast(t_p[0..byte_size]));
157
+ _ = tu;
158
+ const tv: []u32 = @ptrCast(@alignCast(t_p[byte_size..][0..byte_size]));
159
+ _ = tv;
160
+ @call(.always_inline, divmod, .{ null, r, u, v }) catch unreachable;
161
+ }
162
+
135
163
  test "__udivei4/__umodei4" {
136
164
  if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
137
165
  if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
package/fuzzer.zig CHANGED
@@ -171,6 +171,8 @@ const Executable = struct {
171
171
 
172
172
  const cache_dir = Io.Dir.cwd().createDirPathOpen(io, cache_dir_path, .{}) catch |e|
173
173
  panic("failed to open directory '{s}': {t}", .{ cache_dir_path, e });
174
+ cache_dir.createDirPath(io, "tmp") catch |e|
175
+ panic("failed to create directory 'tmp': {t}", .{e});
174
176
  log_f = cache_dir.createFile(io, "tmp/libfuzzer.log", .{ .truncate = false }) catch |e|
175
177
  panic("failed to create file 'tmp/libfuzzer.log': {t}", .{e});
176
178
  self.cache_f = cache_dir.createDirPathOpen(io, "f", .{}) catch |e|
@@ -1,6 +1,9 @@
1
1
  #define __SYSCALL_LL_E(x) (x)
2
2
  #define __SYSCALL_LL_O(x) (x)
3
3
 
4
+ #define __scc(X) sizeof(1?(X):0ULL) < 8 ? (unsigned long) (X) : (long long) (X)
5
+ typedef long long syscall_arg_t;
6
+
4
7
  #define SYSCALL_RLIM_INFINITY (-1UL/2)
5
8
 
6
9
  #if __mips_isa_rev >= 6
@@ -13,9 +16,9 @@
13
16
  "$14", "$15", "$24", "$25", "hi", "lo", "memory"
14
17
  #endif
15
18
 
16
- static inline long __syscall0(long n)
19
+ static inline long __syscall0(long long n)
17
20
  {
18
- register long r7 __asm__("$7");
21
+ register long long r7 __asm__("$7");
19
22
  register long r2 __asm__("$2");
20
23
  __asm__ __volatile__ (
21
24
  "daddu $2,$0,%2 ; syscall"
@@ -25,10 +28,10 @@ static inline long __syscall0(long n)
25
28
  return r7 && r2>0 ? -r2 : r2;
26
29
  }
27
30
 
28
- static inline long __syscall1(long n, long a)
31
+ static inline long __syscall1(long long n, long long a)
29
32
  {
30
- register long r4 __asm__("$4") = a;
31
- register long r7 __asm__("$7");
33
+ register long long r4 __asm__("$4") = a;
34
+ register long long r7 __asm__("$7");
32
35
  register long r2 __asm__("$2");
33
36
  __asm__ __volatile__ (
34
37
  "daddu $2,$0,%2 ; syscall"
@@ -38,11 +41,11 @@ static inline long __syscall1(long n, long a)
38
41
  return r7 && r2>0 ? -r2 : r2;
39
42
  }
40
43
 
41
- static inline long __syscall2(long n, long a, long b)
44
+ static inline long __syscall2(long long n, long long a, long long b)
42
45
  {
43
- register long r4 __asm__("$4") = a;
44
- register long r5 __asm__("$5") = b;
45
- register long r7 __asm__("$7");
46
+ register long long r4 __asm__("$4") = a;
47
+ register long long r5 __asm__("$5") = b;
48
+ register long long r7 __asm__("$7");
46
49
  register long r2 __asm__("$2");
47
50
 
48
51
  __asm__ __volatile__ (
@@ -53,12 +56,12 @@ static inline long __syscall2(long n, long a, long b)
53
56
  return r7 && r2>0 ? -r2 : r2;
54
57
  }
55
58
 
56
- static inline long __syscall3(long n, long a, long b, long c)
59
+ static inline long __syscall3(long long n, long long a, long long b, long long c)
57
60
  {
58
- register long r4 __asm__("$4") = a;
59
- register long r5 __asm__("$5") = b;
60
- register long r6 __asm__("$6") = c;
61
- register long r7 __asm__("$7");
61
+ register long long r4 __asm__("$4") = a;
62
+ register long long r5 __asm__("$5") = b;
63
+ register long long r6 __asm__("$6") = c;
64
+ register long long r7 __asm__("$7");
62
65
  register long r2 __asm__("$2");
63
66
 
64
67
  __asm__ __volatile__ (
@@ -69,12 +72,12 @@ static inline long __syscall3(long n, long a, long b, long c)
69
72
  return r7 && r2>0 ? -r2 : r2;
70
73
  }
71
74
 
72
- static inline long __syscall4(long n, long a, long b, long c, long d)
75
+ static inline long __syscall4(long long n, long long a, long long b, long long c, long long d)
73
76
  {
74
- register long r4 __asm__("$4") = a;
75
- register long r5 __asm__("$5") = b;
76
- register long r6 __asm__("$6") = c;
77
- register long r7 __asm__("$7") = d;
77
+ register long long r4 __asm__("$4") = a;
78
+ register long long r5 __asm__("$5") = b;
79
+ register long long r6 __asm__("$6") = c;
80
+ register long long r7 __asm__("$7") = d;
78
81
  register long r2 __asm__("$2");
79
82
 
80
83
  __asm__ __volatile__ (
@@ -85,13 +88,13 @@ static inline long __syscall4(long n, long a, long b, long c, long d)
85
88
  return r7 && r2>0 ? -r2 : r2;
86
89
  }
87
90
 
88
- static inline long __syscall5(long n, long a, long b, long c, long d, long e)
91
+ static inline long __syscall5(long long n, long long a, long long b, long long c, long long d, long long e)
89
92
  {
90
- register long r4 __asm__("$4") = a;
91
- register long r5 __asm__("$5") = b;
92
- register long r6 __asm__("$6") = c;
93
- register long r7 __asm__("$7") = d;
94
- register long r8 __asm__("$8") = e;
93
+ register long long r4 __asm__("$4") = a;
94
+ register long long r5 __asm__("$5") = b;
95
+ register long long r6 __asm__("$6") = c;
96
+ register long long r7 __asm__("$7") = d;
97
+ register long long r8 __asm__("$8") = e;
95
98
  register long r2 __asm__("$2");
96
99
 
97
100
  __asm__ __volatile__ (
@@ -102,14 +105,14 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e)
102
105
  return r7 && r2>0 ? -r2 : r2;
103
106
  }
104
107
 
105
- static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
108
+ static inline long __syscall6(long long n, long long a, long long b, long long c, long long d, long long e, long long f)
106
109
  {
107
- register long r4 __asm__("$4") = a;
108
- register long r5 __asm__("$5") = b;
109
- register long r6 __asm__("$6") = c;
110
- register long r7 __asm__("$7") = d;
111
- register long r8 __asm__("$8") = e;
112
- register long r9 __asm__("$9") = f;
110
+ register long long r4 __asm__("$4") = a;
111
+ register long long r5 __asm__("$5") = b;
112
+ register long long r6 __asm__("$6") = c;
113
+ register long long r7 __asm__("$7") = d;
114
+ register long long r8 __asm__("$8") = e;
115
+ register long long r9 __asm__("$9") = f;
113
116
  register long r2 __asm__("$2");
114
117
 
115
118
  __asm__ __volatile__ (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zigc/lib",
3
- "version": "0.17.0-dev.9",
3
+ "version": "0.17.0-dev.93",
4
4
  "description": "Zig standard library and libc headers (shared across all platforms)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1393,7 +1393,6 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
1393
1393
  try zig_args.append("--debug-incremental");
1394
1394
  }
1395
1395
 
1396
- if (b.verbose_cimport) try zig_args.append("--verbose-cimport");
1397
1396
  if (b.verbose_air) try zig_args.append("--verbose-air");
1398
1397
  if (b.verbose_llvm_ir) |path| try zig_args.append(b.fmt("--verbose-llvm-ir={s}", .{path}));
1399
1398
  if (b.verbose_llvm_bc) |path| try zig_args.append(b.fmt("--verbose-llvm-bc={s}", .{path}));
package/std/Build.zig CHANGED
@@ -38,7 +38,6 @@ verbose_cc: bool,
38
38
  verbose_air: bool,
39
39
  verbose_llvm_ir: ?[]const u8,
40
40
  verbose_llvm_bc: ?[]const u8,
41
- verbose_cimport: bool,
42
41
  verbose_llvm_cpu_features: bool,
43
42
  reference_trace: ?u32 = null,
44
43
  invalid_user_input: bool,
@@ -278,7 +277,6 @@ pub fn create(
278
277
  .verbose_air = false,
279
278
  .verbose_llvm_ir = null,
280
279
  .verbose_llvm_bc = null,
281
- .verbose_cimport = false,
282
280
  .verbose_llvm_cpu_features = false,
283
281
  .invalid_user_input = false,
284
282
  .allocator = arena,
@@ -377,7 +375,6 @@ fn createChildOnly(
377
375
  .verbose_air = parent.verbose_air,
378
376
  .verbose_llvm_ir = parent.verbose_llvm_ir,
379
377
  .verbose_llvm_bc = parent.verbose_llvm_bc,
380
- .verbose_cimport = parent.verbose_cimport,
381
378
  .verbose_llvm_cpu_features = parent.verbose_llvm_cpu_features,
382
379
  .reference_trace = parent.reference_trace,
383
380
  .invalid_user_input = false,
@@ -459,7 +459,6 @@ pub fn io(ev: *Evented) Io {
459
459
  .netConnectUnix = netConnectUnixUnavailable,
460
460
  .netSocketCreatePair = netSocketCreatePairUnavailable,
461
461
  .netSend = netSendUnavailable,
462
- .netRead = netReadUnavailable,
463
462
  .netWrite = netWriteUnavailable,
464
463
  .netWriteFile = netWriteFileUnavailable,
465
464
  .netClose = netClose,
@@ -1713,6 +1712,7 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper
1713
1712
  },
1714
1713
  .device_io_control => |*o| return .{ .device_io_control = try deviceIoControl(o) },
1715
1714
  .net_receive => @panic("TODO implement net_receive operation"),
1715
+ .net_read => @panic("TODO implement net_read operation"),
1716
1716
  }
1717
1717
  }
1718
1718
 
@@ -2134,6 +2134,7 @@ fn batchDrainSubmitted(
2134
2134
  },
2135
2135
  .device_io_control => {},
2136
2136
  .net_receive => @panic("TODO implement batched net_receive"),
2137
+ .net_read => @panic("TODO implement batched net_read"),
2137
2138
  };
2138
2139
  if (concurrency) return error.ConcurrencyUnavailable;
2139
2140
  break :result try operate(ev, storage.submission.operation);
@@ -2193,6 +2194,7 @@ fn batchSourceEvent(context: ?*anyopaque) callconv(.c) void {
2193
2194
  },
2194
2195
  .device_io_control => unreachable,
2195
2196
  .net_receive => @panic("TODO implement batched net_receive"),
2197
+ .net_read => @panic("TODO implement batched net_read"),
2196
2198
  };
2197
2199
 
2198
2200
  switch (pending.node.prev) {
@@ -4877,18 +4879,6 @@ fn netSendUnavailable(
4877
4879
  return .{ error.NetworkDown, 0 };
4878
4880
  }
4879
4881
 
4880
- fn netReadUnavailable(
4881
- userdata: ?*anyopaque,
4882
- fd: net.Socket.Handle,
4883
- data: [][]u8,
4884
- ) net.Stream.Reader.Error!usize {
4885
- const ev: *Evented = @ptrCast(@alignCast(userdata));
4886
- _ = ev;
4887
- _ = fd;
4888
- _ = data;
4889
- return error.NetworkDown;
4890
- }
4891
-
4892
4882
  fn netWriteUnavailable(
4893
4883
  userdata: ?*anyopaque,
4894
4884
  handle: net.Socket.Handle,
@@ -15,14 +15,42 @@ cond: Io.Condition = .init,
15
15
  /// It is OK to initialize this field to any value.
16
16
  permits: usize = 0,
17
17
 
18
+ /// Blocks until a `permit` is available and consumes a single one.
19
+ /// Unblocks without consuming a `permit` when canceled.
20
+ ///
21
+ /// See also:
22
+ /// * `waitTimeout`
23
+ /// * `waitUncancelable`
18
24
  pub fn wait(s: *Semaphore, io: Io) Io.Cancelable!void {
25
+ s.waitTimeout(io, .none) catch |err| switch (err) {
26
+ error.Timeout => unreachable,
27
+ error.Canceled => |e| return e,
28
+ };
29
+ }
30
+
31
+ pub const WaitTimeoutError = Io.Cancelable || Io.Timeout.Error;
32
+
33
+ /// Blocks until a `permit` is available and consumes a single one.
34
+ /// Unblocks without consuming a `permit` when canceled or when the provided
35
+ /// timeout expires before a `permit` is available.
36
+ ///
37
+ /// See also:
38
+ /// * `wait`
39
+ /// * `waitUncancelable`
40
+ pub fn waitTimeout(s: *Semaphore, io: Io, timeout: Io.Timeout) WaitTimeoutError!void {
41
+ const deadline = timeout.toDeadline(io);
19
42
  try s.mutex.lock(io);
20
43
  defer s.mutex.unlock(io);
21
- while (s.permits == 0) try s.cond.wait(io, &s.mutex);
44
+ while (s.permits == 0) try s.cond.waitTimeout(io, &s.mutex, deadline);
22
45
  s.permits -= 1;
23
46
  if (s.permits > 0) s.cond.signal(io);
24
47
  }
25
48
 
49
+ /// Blocks until a `permit` is available and consumes a single one.
50
+ ///
51
+ /// See also:
52
+ /// * `wait`
53
+ /// * `waitTimeout`
26
54
  pub fn waitUncancelable(s: *Semaphore, io: Io) void {
27
55
  s.mutex.lockUncancelable(io);
28
56
  defer s.mutex.unlock(io);
@@ -31,6 +59,7 @@ pub fn waitUncancelable(s: *Semaphore, io: Io) void {
31
59
  if (s.permits > 0) s.cond.signal(io);
32
60
  }
33
61
 
62
+ /// Makes an additional `permit` available.
34
63
  pub fn post(s: *Semaphore, io: Io) void {
35
64
  s.mutex.lockUncancelable(io);
36
65
  defer s.mutex.unlock(io);
@@ -39,27 +68,93 @@ pub fn post(s: *Semaphore, io: Io) void {
39
68
  s.cond.signal(io);
40
69
  }
41
70
 
42
- test Semaphore {
43
- if (builtin.single_threaded) return error.SkipZigTest;
71
+ test wait {
44
72
  const io = testing.io;
45
73
 
46
- const TestContext = struct {
47
- sem: *Semaphore,
48
- n: *i32,
74
+ const Context = struct {
75
+ sem: Semaphore = .{ .permits = 1 },
76
+ n: u32 = 0,
77
+
49
78
  fn worker(ctx: *@This()) !void {
50
79
  try ctx.sem.wait(io);
51
- ctx.n.* += 1;
80
+ ctx.n += 1;
52
81
  ctx.sem.post(io);
53
82
  }
54
83
  };
55
- const num_threads = 3;
56
- var sem: Semaphore = .{ .permits = 1 };
57
- var threads: [num_threads]std.Thread = undefined;
58
- var n: i32 = 0;
59
- var ctx = TestContext{ .sem = &sem, .n = &n };
60
-
61
- for (&threads) |*t| t.* = try std.Thread.spawn(.{}, TestContext.worker, .{&ctx});
62
- for (threads) |t| t.join();
63
- try sem.wait(io);
64
- try testing.expect(n == num_threads);
84
+
85
+ var ctx: Context = .{};
86
+
87
+ var group: Io.Group = .init;
88
+ defer group.cancel(io);
89
+
90
+ const num_workers = 3;
91
+ for (0..num_workers) |_| group.async(io, Context.worker, .{&ctx});
92
+
93
+ try group.await(io);
94
+ try testing.expectEqual(num_workers, ctx.n);
95
+ }
96
+
97
+ test waitTimeout {
98
+ const io = testing.io;
99
+
100
+ const Context = struct {
101
+ ready: Io.Event = .unset,
102
+ sem: Semaphore = .{ .permits = 0 },
103
+ value: u32 = 0,
104
+
105
+ fn worker(ctx: *@This()) !void {
106
+ defer ctx.ready.set(io);
107
+
108
+ try testing.expectError(error.Timeout, ctx.sem.waitTimeout(io, .{ .duration = .{
109
+ .raw = .fromMilliseconds(1),
110
+ .clock = .awake,
111
+ } }));
112
+ try testing.expectEqual(0, ctx.value);
113
+
114
+ ctx.ready.set(io);
115
+
116
+ while (ctx.value == 0) try ctx.sem.wait(io);
117
+ try testing.expectEqual(1, ctx.value);
118
+ }
119
+ };
120
+
121
+ var ctx: Context = .{};
122
+
123
+ var future = io.concurrent(Context.worker, .{&ctx}) catch |err| switch (err) {
124
+ error.ConcurrencyUnavailable => return error.SkipZigTest,
125
+ };
126
+ defer future.cancel(io) catch {};
127
+
128
+ try ctx.ready.wait(io);
129
+
130
+ ctx.value = 1;
131
+ ctx.sem.post(io);
132
+
133
+ try future.await(io);
134
+ }
135
+
136
+ test waitUncancelable {
137
+ const io = testing.io;
138
+
139
+ const Context = struct {
140
+ sem: Semaphore = .{ .permits = 1 },
141
+ n: u32 = 0,
142
+
143
+ fn worker(ctx: *@This()) !void {
144
+ ctx.sem.waitUncancelable(io);
145
+ ctx.n += 1;
146
+ ctx.sem.post(io);
147
+ }
148
+ };
149
+
150
+ var ctx: Context = .{};
151
+
152
+ var group: Io.Group = .init;
153
+ defer group.cancel(io);
154
+
155
+ const num_workers = 3;
156
+ for (0..num_workers) |_| group.async(io, Context.worker, .{&ctx});
157
+
158
+ try group.await(io);
159
+ try testing.expectEqual(num_workers, ctx.n);
65
160
  }