summaryrefslogtreecommitdiffstats
path: root/src/ioq.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ioq.c')
-rw-r--r--src/ioq.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/src/ioq.c b/src/ioq.c
index ced9864..57eb4a5 100644
--- a/src/ioq.c
+++ b/src/ioq.c
@@ -203,7 +203,7 @@ struct ioqq {
cache_align atomic size_t tail;
/** The circular buffer itself. */
- cache_align ioq_slot slots[];
+ cache_align ioq_slot slots[]; // _counted_by(slot_mask + 1)
};
/** Destroy an I/O command queue. */
@@ -277,11 +277,13 @@ static struct ioq_monitor *ioq_slot_monitor(struct ioqq *ioqq, ioq_slot *slot) {
/** Atomically wait for a slot to change. */
_noinline
static uintptr_t ioq_slot_wait(struct ioqq *ioqq, ioq_slot *slot, uintptr_t value) {
- // Try spinning a few times before blocking
uintptr_t ret;
- for (int i = 0; i < 10; ++i) {
- // Exponential backoff
- for (int j = 0; j < (1 << i); ++j) {
+
+ // Try spinning a few times (with exponential backoff) before blocking
+ _nounroll
+ for (int i = 1; i < 1024; i *= 2) {
+ _nounroll
+ for (int j = 0; j < i; ++j) {
spin_loop();
}
@@ -387,7 +389,7 @@ static struct ioq_ent *ioq_slot_pop(struct ioqq *ioqq, ioq_slot *slot, bool bloc
// slot is not full, this will prefetch an invalid address, but
// experimentally this is worth it on both Intel (Alder Lake)
// and AMD (Zen 2).
- __builtin_prefetch((void *)(prev << 1));
+ __builtin_prefetch((void *)(prev << 1), 1 /* write */);
#endif
// empty → skip(1)
@@ -591,7 +593,7 @@ struct ioq {
/** The number of background threads. */
size_t nthreads;
/** The background threads themselves. */
- struct ioq_thread threads[];
+ struct ioq_thread threads[] _counted_by(nthreads);
};
/** Cancel a request if we need to. */
@@ -615,7 +617,7 @@ static void ioq_dispatch_sync(struct ioq *ioq, struct ioq_ent *ent) {
case IOQ_NOP:
if (ent->nop.type == IOQ_NOP_HEAVY) {
// A fast, no-op syscall
- getpid();
+ getppid();
}
ent->result = 0;
return;
@@ -844,7 +846,7 @@ static struct io_uring_sqe *ioq_dispatch_async(struct ioq_ring_state *state, str
sqe = ioq_get_sqe(state);
struct ioq_stat *args = &ent->stat;
int flags = bfs_statx_flags(args->flags);
- unsigned int mask = STATX_BASIC_STATS | STATX_BTIME;
+ unsigned int mask = bfs_statx_mask();
io_uring_prep_statx(sqe, args->dfd, args->path, flags, mask, args->xbuf);
}
#endif
@@ -1034,7 +1036,7 @@ static int ioq_ring_init(struct ioq *ioq, struct ioq_thread *thread) {
ioq_ring_probe_flags(&params, IORING_SETUP_SINGLE_ISSUER);
# endif
# ifdef IORING_SETUP_DEFER_TASKRUN
- // Don't interrupt us aggresively with completion events
+ // Don't interrupt us aggressively with completion events
ioq_ring_probe_flags(&params, IORING_SETUP_DEFER_TASKRUN);
# endif
}