mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 15:28:30 +00:00
Make some more fixes
This change deletes mkfifo() so that GNU Make on Windows will work in parallel mode using its pipe-based implementation. There's an example called greenbean2 now, which shows how to build a scalable web server for Windows with 10k+ threads. The accuracy of clock_nanosleep is now significantly improved on Linux.
This commit is contained in:
parent
820c3599ed
commit
3b4dbc9fdd
22 changed files with 870 additions and 330 deletions
|
@ -16,52 +16,47 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/nt/enum/wait.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
// each thread has its own pt_futex which is used by both posix signals
|
||||
// and posix thread cancelation to "park" blocking operations that dont
|
||||
// need win32 overlapped i/o. the delay is advisory and may be -1 which
|
||||
// means wait forever. these functions don't guarantee to wait the full
|
||||
// duration. other threads wanting to deliver a signal, can wake parked
|
||||
// futexes without releasing them, just to stir up activity. if a futex
|
||||
// is both woken and released then the cancelation point shall generate
|
||||
// an eintr. we also abstract checking for signals & thread cancelation
|
||||
|
||||
static textwindows int _park_wait(uint32_t msdelay, bool restartable,
|
||||
struct PosixThread *pt) {
|
||||
int got, expect = 0;
|
||||
if (_check_cancel() == -1) return -1;
|
||||
if (_check_signal(restartable) == -1) return -1;
|
||||
WaitOnAddress(&pt->pt_futex, &expect, sizeof(expect), msdelay);
|
||||
got = atomic_load_explicit(&pt->pt_futex, memory_order_acquire);
|
||||
return got != expect ? eintr() : 0;
|
||||
}
|
||||
|
||||
static textwindows int _park_thread(uint32_t msdelay, sigset_t waitmask,
|
||||
bool restartable) {
|
||||
int rc;
|
||||
int64_t sem;
|
||||
sigset_t om;
|
||||
uint32_t wi;
|
||||
struct PosixThread *pt;
|
||||
pt = _pthread_self();
|
||||
pt->pt_flags &= ~PT_RESTARTABLE;
|
||||
if (restartable) pt->pt_flags |= PT_RESTARTABLE;
|
||||
atomic_store_explicit(&pt->pt_futex, 0, memory_order_release);
|
||||
atomic_store_explicit(&pt->pt_blocker, &pt->pt_futex, memory_order_release);
|
||||
pt->pt_semaphore = sem = CreateSemaphore(0, 0, 1, 0);
|
||||
pthread_cleanup_push((void *)CloseHandle, (void *)sem);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM, memory_order_release);
|
||||
om = __sig_beginwait(waitmask);
|
||||
rc = _park_wait(msdelay, restartable, pt);
|
||||
if (rc == -1 && errno == EINTR) _check_cancel();
|
||||
if ((rc = _check_cancel()) != -1 && (rc = _check_signal(restartable)) != -1) {
|
||||
unassert((wi = WaitForSingleObject(sem, msdelay)) != -1u);
|
||||
if (wi != kNtWaitTimeout) {
|
||||
rc = eintr();
|
||||
_check_cancel();
|
||||
}
|
||||
}
|
||||
__sig_finishwait(om);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_CPU, memory_order_release);
|
||||
pt->pt_flags &= ~PT_RESTARTABLE;
|
||||
pthread_cleanup_pop(true);
|
||||
pt->pt_semaphore = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue