5 ms·
When 2 threads are allocating sockets sequentially, they fight for the locks. If you preallocate a bigger table by creating fd 666 first, the lock contention go
by viraptor 1y ago
When 2 threads are allocating sockets sequentially, they fight for the locks. If you preallocate a bigger table by creating fd 666 first, the lock contention goes away.
- JdeBP 1y agoIt's something that has always been interesting about Windows NT, which has a multi-level object handle table, and does not have the rule about re-using the lowest numbered available table index. There's scope for reducing contention amongst threads in such an architecture. Although: 1. back in application-mode code the language runtime libraries make things look like a POSIX API and maintain their own table mapping object handles to POSIX-like file descriptors, where there is the old contention over the lowest free entries; and 1. in practice the object handle table seems to mostly append, so multiple object-opening threads all contend over the end of the table.
- the8472 1y agolowest-number-reuse is also a robustness issue. If multi-threaded programs UAF or double-free a file descriptor they likely end up touching FDs owned by other parts of the program which can result in various kinds of corruption and memory-unsafety. Assigning numbers from a large domain, either randomly or from a permutation sequence, would massively reduce that probability and manifest in prompt errors instead.
- loeg 1y agoI want an alternative unix ABI that doesn't guarantee lowest-reuse for this exact reason. I suppose you could (almost) just hijack the close call and replace it with a dup2 of /dev/null or something (but then you'd miss close errors).
- the8472 1y agoIt could be emulated in userspace with F_DUPFD. But that's costly because the kernel table is optimized for dense data, not sparse. The rust standard library aborts the program in debug builds when it detects a double-close; at that point corruption may already have occurred but better than nothing.
- loeg 1y ago> The rust standard library aborts the program in debug builds when it detects a double-close On EBADF? Neat.
- saagarjha 1y agoRCU is very explicitly a lockless synchronization strategy.
- loeg 1y agoThis isn't why it's slow. 2x256 just isn't a lot of locks in CPU time.