mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-07 03:38:31 +00:00
Fix many thread and file descriptor issues on Windows
The greenbean web server now works nearly perfectly on Windows with over 1000 threads. But some synchronization issues still remain which prevent us from going over nine thousand.
This commit is contained in:
parent
96781d0679
commit
7838edae88
32 changed files with 363 additions and 192 deletions
|
@ -4,6 +4,10 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/lockcmpxchg.h"
|
||||
#include "libc/intrin/lockcmpxchgp.h"
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § spinlocks ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│─╝
|
||||
privileged unsophisticated locking subroutines */
|
||||
|
||||
#if IsModeDbg() && !defined(_SPINLOCK_DEBUG)
|
||||
#define _SPINLOCK_DEBUG
|
||||
|
@ -12,15 +16,27 @@
|
|||
#if defined(_SPINLOCK_DEBUG)
|
||||
#define _spinlock(lock) _spinlock_ndebug(lock)
|
||||
#define _spinlock_ndebug(lock) _spinlock_cooperative(lock)
|
||||
#define _trylock(lock) _trylock_debug(lock)
|
||||
#define _seizelock(lock) _seizelock_impl(lock, gettid())
|
||||
#elif defined(TINY)
|
||||
#define _spinlock(lock) _spinlock_tiny(lock)
|
||||
#define _spinlock_ndebug(lock) _spinlock_tiny(lock)
|
||||
#define _trylock(lock) _trylock_inline(lock)
|
||||
#define _seizelock(lock) _seizelock_impl(lock, 1)
|
||||
#else
|
||||
#define _spinlock(lock) _spinlock_cooperative(lock)
|
||||
#define _spinlock_ndebug(lock) _spinlock_cooperative(lock)
|
||||
#define _trylock(lock) _trylock_inline(lock)
|
||||
#define _seizelock(lock) _seizelock_impl(lock, 1)
|
||||
#endif
|
||||
|
||||
#define _trylock(lock) __atomic_test_and_set(lock, __ATOMIC_SEQ_CST)
|
||||
#define _trylock_inline(lock) __atomic_test_and_set(lock, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define _trylock_debug(lock) \
|
||||
_trylock_debug_4(lock, #lock, __FILE__, __LINE__, __FUNCTION__)
|
||||
|
||||
#define _spinlock_debug(lock) \
|
||||
_spinlock_debug_4(lock, #lock, __FILE__, __LINE__, __FUNCTION__)
|
||||
|
||||
#define _spunlock(lock) \
|
||||
do { \
|
||||
|
@ -29,19 +45,19 @@
|
|||
__atomic_store(__lock, &__x, __ATOMIC_RELAXED); \
|
||||
} while (0)
|
||||
|
||||
#define _seizelock(lock) \
|
||||
#define _seizelock_impl(lock, value) \
|
||||
do { \
|
||||
autotype(lock) __lock = (lock); \
|
||||
typeof(*__lock) __x = 1; \
|
||||
typeof(*__lock) __x = (value); \
|
||||
__atomic_store(__lock, &__x, __ATOMIC_RELEASE); \
|
||||
} while (0)
|
||||
|
||||
#define _spinlock_tiny(lock) \
|
||||
do { \
|
||||
autotype(lock) __lock = (lock); \
|
||||
while (_trylock(__lock)) { \
|
||||
__builtin_ia32_pause(); \
|
||||
} \
|
||||
#define _spinlock_tiny(lock) \
|
||||
do { \
|
||||
autotype(lock) __lock = (lock); \
|
||||
while (_trylock_inline(__lock)) { \
|
||||
__builtin_ia32_pause(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _spinlock_cooperative(lock) \
|
||||
|
@ -51,7 +67,7 @@
|
|||
int __tries = 0; \
|
||||
for (;;) { \
|
||||
__atomic_load(__lock, &__x, __ATOMIC_RELAXED); \
|
||||
if (!__x && !_trylock(__lock)) { \
|
||||
if (!__x && !_trylock_inline(__lock)) { \
|
||||
break; \
|
||||
} else if (++__tries & 7) { \
|
||||
__builtin_ia32_pause(); \
|
||||
|
@ -61,21 +77,7 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
void _spinlock_debug_1(void *, const char *, const char *, int, const char *);
|
||||
void _spinlock_debug_4(void *, const char *, const char *, int, const char *);
|
||||
|
||||
#define _spinlock_debug(lock) \
|
||||
do { \
|
||||
switch (sizeof(*(lock))) { \
|
||||
case 1: \
|
||||
_spinlock_debug_1(lock, #lock, __FILE__, __LINE__, __FUNCTION__); \
|
||||
break; \
|
||||
case 4: \
|
||||
_spinlock_debug_4(lock, #lock, __FILE__, __LINE__, __FUNCTION__); \
|
||||
break; \
|
||||
default: \
|
||||
assert(!"unsupported size"); \
|
||||
} \
|
||||
} while (0)
|
||||
int _trylock_debug_4(int *, const char *, const char *, int, const char *);
|
||||
void _spinlock_debug_4(int *, const char *, const char *, int, const char *);
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue