| ... | @@ -378,21 +378,33 @@ pub inline fn spinLoopHint() void { | ... | @@ -378,21 +378,33 @@ pub inline fn spinLoopHint() void { |
| 378 | // No-op instruction that can hint to save (or share with a hardware-thread) | 378 | // No-op instruction that can hint to save (or share with a hardware-thread) |
| 379 | // pipelining/power resources | 379 | // pipelining/power resources |
| 380 | // https://software.intel.com/content/www/us/en/develop/articles/benefitting-power-and-performance-sleep-loops.html | 380 | // https://software.intel.com/content/www/us/en/develop/articles/benefitting-power-and-performance-sleep-loops.html |
| 381 | .x86, .x86_64 => asm volatile ("pause" ::: "memory"), | 381 | .x86, |
| | 382 | .x86_64, |
| | 383 | => asm volatile ("pause" ::: "memory"), |
| 382 | | 384 | |
| 383 | // No-op instruction that serves as a hardware-thread resource yield hint. | 385 | // No-op instruction that serves as a hardware-thread resource yield hint. |
| 384 | // https://stackoverflow.com/a/7588941 | 386 | // https://stackoverflow.com/a/7588941 |
| 385 | .powerpc64, .powerpc64le => asm volatile ("or 27, 27, 27" ::: "memory"), | 387 | .powerpc, |
| | 388 | .powerpcle, |
| | 389 | .powerpc64, |
| | 390 | .powerpc64le, |
| | 391 | => asm volatile ("or 27, 27, 27" ::: "memory"), |
| 386 | | 392 | |
| 387 | // `isb` appears more reliable for releasing execution resources than `yield` | 393 | // `isb` appears more reliable for releasing execution resources than `yield` |
| 388 | // on common aarch64 CPUs. | 394 | // on common aarch64 CPUs. |
| 389 | // https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8258604 | 395 | // https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8258604 |
| 390 | // https://bugs.mysql.com/bug.php?id=100664 | 396 | // https://bugs.mysql.com/bug.php?id=100664 |
| 391 | .aarch64, .aarch64_be => asm volatile ("isb" ::: "memory"), | 397 | .aarch64, |
| | 398 | .aarch64_be, |
| | 399 | => asm volatile ("isb" ::: "memory"), |
| 392 | | 400 | |
| 393 | // `yield` was introduced in v6k but is also available on v6m. | 401 | // `yield` was introduced in v6k but is also available on v6m. |
| 394 | // https://www.keil.com/support/man/docs/armasm/armasm_dom1361289926796.htm | 402 | // https://www.keil.com/support/man/docs/armasm/armasm_dom1361289926796.htm |
| 395 | .arm, .armeb, .thumb, .thumbeb => { | 403 | .arm, |
| | 404 | .armeb, |
| | 405 | .thumb, |
| | 406 | .thumbeb, |
| | 407 | => { |
| 396 | const can_yield = comptime std.Target.arm.featureSetHasAny(builtin.target.cpu.features, .{ | 408 | const can_yield = comptime std.Target.arm.featureSetHasAny(builtin.target.cpu.features, .{ |
| 397 | .has_v6k, .has_v6m, | 409 | .has_v6k, .has_v6m, |
| 398 | }); | 410 | }); |
| ... | @@ -402,6 +414,22 @@ pub inline fn spinLoopHint() void { | ... | @@ -402,6 +414,22 @@ pub inline fn spinLoopHint() void { |
| 402 | asm volatile ("" ::: "memory"); | 414 | asm volatile ("" ::: "memory"); |
| 403 | } | 415 | } |
| 404 | }, | 416 | }, |
| | 417 | |
| | 418 | // The 8-bit immediate specifies the amount of cycles to pause for. We can't really be too |
| | 419 | // opinionated here. |
| | 420 | .hexagon, |
| | 421 | => asm volatile ("pause(#1)" ::: "memory"), |
| | 422 | |
| | 423 | .riscv32, |
| | 424 | .riscv64, |
| | 425 | => { |
| | 426 | if (comptime std.Target.riscv.featureSetHas(builtin.target.cpu.features, .zihintpause)) { |
| | 427 | asm volatile ("pause" ::: "memory"); |
| | 428 | } else { |
| | 429 | asm volatile ("" ::: "memory"); |
| | 430 | } |
| | 431 | }, |
| | 432 | |
| 405 | // Memory barrier to prevent the compiler from optimizing away the spin-loop | 433 | // Memory barrier to prevent the compiler from optimizing away the spin-loop |
| 406 | // even if no hint_instruction was provided. | 434 | // even if no hint_instruction was provided. |
| 407 | else => asm volatile ("" ::: "memory"), | 435 | else => asm volatile ("" ::: "memory"), |