mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Change support vector to Windows 8+
Doing this makes binaries tinier, since we don't need to have all the
extra code for supporting a 32-bit address space. It also benefits us
because we're able to use WIN32 futexes, which makes locking simpler.
b69f3d2488
is what officially ended our
Windows 7 support. This change is merely a formalization. You can use
old versions of Cosmo now and forevermore if you need Windows 7 since
our repository is hermetic and vendors all its dependencies.
Won't fix #617
This commit is contained in:
parent
6c90f830d9
commit
134ffee519
25 changed files with 296 additions and 167 deletions
1
Makefile
1
Makefile
|
@ -325,6 +325,7 @@ COSMOPOLITAN_OBJECTS = \
|
||||||
LIBC_NT_USER32 \
|
LIBC_NT_USER32 \
|
||||||
LIBC_NT_NTDLL \
|
LIBC_NT_NTDLL \
|
||||||
LIBC_NT_ADVAPI32 \
|
LIBC_NT_ADVAPI32 \
|
||||||
|
LIBC_NT_SYNCHRONIZATION \
|
||||||
LIBC_FMT \
|
LIBC_FMT \
|
||||||
THIRD_PARTY_COMPILER_RT \
|
THIRD_PARTY_COMPILER_RT \
|
||||||
LIBC_TINYMATH \
|
LIBC_TINYMATH \
|
||||||
|
|
|
@ -245,11 +245,11 @@ gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
|
||||||
| :--- | ---: | ---: |
|
| :--- | ---: | ---: |
|
||||||
| AMD | K8 Venus | 2005 |
|
| AMD | K8 Venus | 2005 |
|
||||||
| Intel | Core | 2006 |
|
| Intel | Core | 2006 |
|
||||||
| Windows | Vista | 2006 |
|
|
||||||
| Linux | 2.6.18 | 2007 |
|
| Linux | 2.6.18 | 2007 |
|
||||||
|
| Windows | 8 | 2012 |
|
||||||
| Mac OS X | 15.6 | 2018 |
|
| Mac OS X | 15.6 | 2018 |
|
||||||
| FreeBSD | 13 | 2020 |
|
|
||||||
| OpenBSD | 6.4 | 2018 |
|
| OpenBSD | 6.4 | 2018 |
|
||||||
|
| FreeBSD | 13 | 2020 |
|
||||||
| NetBSD | 9.2 | 2021 |
|
| NetBSD | 9.2 | 2021 |
|
||||||
|
|
||||||
## Special Thanks
|
## Special Thanks
|
||||||
|
|
|
@ -32,23 +32,23 @@
|
||||||
// @see ape/ape.lds
|
// @see ape/ape.lds
|
||||||
// @see winimp
|
// @see winimp
|
||||||
.macro .imp dll:req fn:req actual:req hint
|
.macro .imp dll:req fn:req actual:req hint
|
||||||
.dll \dll
|
.dll "\dll"
|
||||||
.section .piro.data.sort.iat.2.\dll\().2.\actual,"aw",@progbits
|
.section ".piro.data.sort.iat.2.\dll\().2.\actual","aw",@progbits
|
||||||
.type \fn,@object
|
.type \fn,@object
|
||||||
.align __SIZEOF_POINTER__
|
.align __SIZEOF_POINTER__
|
||||||
\fn: .quad RVA((\dll\().\actual))
|
\fn: .quad RVA(("\dll\().\actual"))
|
||||||
.size \fn,.-\fn
|
.size \fn,.-\fn
|
||||||
.globl \fn
|
.globl \fn
|
||||||
.hidden \fn
|
.hidden \fn
|
||||||
.previous
|
.previous
|
||||||
.section .idata.ro.ilt.\dll\().2.\actual,"a",@progbits
|
.section ".idata.ro.ilt.\dll\().2.\actual","a",@progbits
|
||||||
.Lidata.ilt.\dll\().\actual:
|
".Lidata.ilt.\dll\().\actual":
|
||||||
.quad RVA((\dll\().\actual))
|
.quad RVA("\dll\().\actual")
|
||||||
.type .Lidata.ilt.\dll\().\actual,@object
|
.type ".Lidata.ilt.\dll\().\actual",@object
|
||||||
.size .Lidata.ilt.\dll\().\actual,.-.Lidata.ilt.\dll\().\actual
|
.size ".Lidata.ilt.\dll\().\actual",.-".Lidata.ilt.\dll\().\actual"
|
||||||
.previous
|
.previous
|
||||||
.section .idata.ro.hnt.\dll\().2.\actual,"a",@progbits
|
.section ".idata.ro.hnt.\dll\().2.\actual","a",@progbits
|
||||||
\dll\().\actual:
|
"\dll\().\actual":
|
||||||
.ifnb \hint # hint i.e. guess function ordinal
|
.ifnb \hint # hint i.e. guess function ordinal
|
||||||
.short \hint
|
.short \hint
|
||||||
.else
|
.else
|
||||||
|
@ -56,55 +56,55 @@
|
||||||
.endif
|
.endif
|
||||||
.asciz "\actual"
|
.asciz "\actual"
|
||||||
.align 2 # documented requirement
|
.align 2 # documented requirement
|
||||||
.globl \dll\().\actual
|
.globl "\dll\().\actual"
|
||||||
.hidden \dll\().\actual
|
.hidden "\dll\().\actual"
|
||||||
.type \dll\().\actual,@object
|
.type "\dll\().\actual",@object
|
||||||
.size \dll\().\actual,.-\dll\().\actual
|
.size "\dll\().\actual",.-"\dll\().\actual"
|
||||||
.previous
|
.previous
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
// Defines DLL import.
|
// Defines DLL import.
|
||||||
// @note this is an implementation detail of .imp
|
// @note this is an implementation detail of .imp
|
||||||
.macro .dll name:req
|
.macro .dll name:req
|
||||||
.section .idata.ro.idt.2.\name,"aG",@progbits,\name,comdat
|
.section ".idata.ro.idt.2.\name","aG",@progbits,"\name",comdat
|
||||||
.equ .Lidata.idt.\name,.
|
.equ ".Lidata.idt.\name",.
|
||||||
.long RVA(idata.ilt.\name) # ImportLookupTable
|
.long RVA("idata.ilt.\name") # ImportLookupTable
|
||||||
.long 0 # TimeDateStamp
|
.long 0 # TimeDateStamp
|
||||||
.long 0 # ForwarderChain
|
.long 0 # ForwarderChain
|
||||||
.long RVA(.Lidata.str.\name) # DllNameRva
|
.long RVA(".Lidata.str.\name") # DllNameRva
|
||||||
.long RVA(idata.iat.\name) # ImportAddressTable
|
.long RVA("idata.iat.\name") # ImportAddressTable
|
||||||
.type .Lidata.idt.\name,@object
|
.type ".Lidata.idt.\name",@object
|
||||||
.size .Lidata.idt.\name,.-.Lidata.idt.\name
|
.size ".Lidata.idt.\name",.-".Lidata.idt.\name"
|
||||||
.previous
|
.previous
|
||||||
.section .idata.ro.ilt.\name\().1,"aG",@progbits,\name,comdat
|
.section ".idata.ro.ilt.\name\().1","aG",@progbits,"\name",comdat
|
||||||
.align __SIZEOF_POINTER__
|
.align __SIZEOF_POINTER__
|
||||||
.type idata.ilt.\name,@object
|
.type "idata.ilt.\name",@object
|
||||||
idata.ilt.\name:
|
"idata.ilt.\name":
|
||||||
.previous/*
|
.previous/*
|
||||||
...
|
...
|
||||||
decentralized content
|
decentralized content
|
||||||
...
|
...
|
||||||
*/.section .idata.ro.ilt.\name\().3,"aG",@progbits,\name,comdat
|
*/.section ".idata.ro.ilt.\name\().3","aG",@progbits,"\name",comdat
|
||||||
.quad 0
|
.quad 0
|
||||||
.previous
|
.previous
|
||||||
.section .idata.ro.hnt.\name\().1,"aG",@progbits,\name,comdat
|
.section ".idata.ro.hnt.\name\().1","aG",@progbits,"\name",comdat
|
||||||
.align __SIZEOF_POINTER__
|
.align __SIZEOF_POINTER__
|
||||||
.type idata.hnt.\name,@object
|
.type "idata.hnt.\name",@object
|
||||||
.equ idata.hnt.\name,.
|
.equ "idata.hnt.\name",.
|
||||||
.previous
|
.previous
|
||||||
.section .piro.data.sort.iat.2.\name\().1,"awG",@progbits,\name,comdat
|
.section ".piro.data.sort.iat.2.\name\().1","awG",@progbits,"\name",comdat
|
||||||
.align __SIZEOF_POINTER__
|
.align __SIZEOF_POINTER__
|
||||||
.type idata.iat.\name,@object
|
.type "idata.iat.\name",@object
|
||||||
idata.iat.\name:
|
"idata.iat.\name":
|
||||||
.previous/*
|
.previous/*
|
||||||
...
|
...
|
||||||
decentralized content
|
decentralized content
|
||||||
...
|
...
|
||||||
*/.section .piro.data.sort.iat.2.\name\().3,"awG",@progbits,\name,comdat
|
*/.section ".piro.data.sort.iat.2.\name\().3","awG",@progbits,"\name",comdat
|
||||||
.quad 0
|
.quad 0
|
||||||
.previous
|
.previous
|
||||||
.section .rodata.str1.1,"aSM",@progbits,1
|
.section .rodata.str1.1,"aSM",@progbits,1
|
||||||
.Lidata.str.\name:
|
".Lidata.str.\name":
|
||||||
.asciz "\name\().dll"
|
.asciz "\name\().dll"
|
||||||
.previous
|
.previous
|
||||||
.endm
|
.endm
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "libc/calls/weirdtypes.h"
|
#include "libc/calls/weirdtypes.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/nt/accounting.h"
|
||||||
#include "libc/nt/dll.h"
|
#include "libc/nt/dll.h"
|
||||||
#include "libc/nt/struct/systeminfo.h"
|
#include "libc/nt/struct/systeminfo.h"
|
||||||
#include "libc/nt/systeminfo.h"
|
#include "libc/nt/systeminfo.h"
|
||||||
|
@ -61,18 +62,6 @@ static unsigned GetCpuCountBsd(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static textwindows unsigned GetCpuCountWindows(void) {
|
|
||||||
struct NtSystemInfo si;
|
|
||||||
uint32_t (*f)(uint16_t);
|
|
||||||
if ((f = GetProcAddress(GetModuleHandle("KERNEL32"),
|
|
||||||
"GetMaximumProcessorCount"))) {
|
|
||||||
return f(ALL_PROCESSOR_GROUPS);
|
|
||||||
} else {
|
|
||||||
GetSystemInfo(&si);
|
|
||||||
return si.dwNumberOfProcessors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned GetCpuCountImpl(void) {
|
static unsigned GetCpuCountImpl(void) {
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
if (!IsBsd()) {
|
if (!IsBsd()) {
|
||||||
|
@ -81,7 +70,7 @@ static unsigned GetCpuCountImpl(void) {
|
||||||
return GetCpuCountBsd();
|
return GetCpuCountBsd();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return GetCpuCountWindows();
|
return GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
0
libc/intrin/intrin.h
Executable file
0
libc/intrin/intrin.h
Executable file
12
libc/nt/API-MS-Win-Core-Synch-l1-2-0/WaitOnAddress.s
Normal file
12
libc/nt/API-MS-Win-Core-Synch-l1-2-0/WaitOnAddress.s
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.include "o/libc/nt/codegen.inc"
|
||||||
|
.imp API-MS-Win-Core-Synch-l1-2-0,__imp_WaitOnAddress,WaitOnAddress,111
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
WaitOnAddress:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_WaitOnAddress(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn WaitOnAddress,globl
|
||||||
|
.previous
|
15
libc/nt/API-MS-Win-Core-Synch-l1-2-0/WakeByAddressAll.s
Normal file
15
libc/nt/API-MS-Win-Core-Synch-l1-2-0/WakeByAddressAll.s
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
.include "o/libc/nt/codegen.inc"
|
||||||
|
.imp API-MS-Win-Core-Synch-l1-2-0,__imp_WakeByAddressAll,WakeByAddressAll,113
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
WakeByAddressAll:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov %rdi,%rcx
|
||||||
|
sub $32,%rsp
|
||||||
|
call *__imp_WakeByAddressAll(%rip)
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
.endfn WakeByAddressAll,globl
|
||||||
|
.previous
|
15
libc/nt/API-MS-Win-Core-Synch-l1-2-0/WakeByAddressSingle.s
Normal file
15
libc/nt/API-MS-Win-Core-Synch-l1-2-0/WakeByAddressSingle.s
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
.include "o/libc/nt/codegen.inc"
|
||||||
|
.imp API-MS-Win-Core-Synch-l1-2-0,__imp_WakeByAddressSingle,WakeByAddressSingle,116
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
WakeByAddressSingle:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov %rdi,%rcx
|
||||||
|
sub $32,%rsp
|
||||||
|
call *__imp_WakeByAddressSingle(%rip)
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
.endfn WakeByAddressSingle,globl
|
||||||
|
.previous
|
|
@ -992,7 +992,7 @@
|
||||||
#define kNtErrorInvalidKeyboardHandle 1457
|
#define kNtErrorInvalidKeyboardHandle 1457
|
||||||
#define kNtErrorHookTypeNotAllowed 1458
|
#define kNtErrorHookTypeNotAllowed 1458
|
||||||
#define kNtErrorRequiresInteractiveWindowstation 1459
|
#define kNtErrorRequiresInteractiveWindowstation 1459
|
||||||
#define kNtErrorTimeout 1460
|
#define kNtErrorTimeout 1460 /* ETIMEDOUT */
|
||||||
#define kNtErrorInvalidMonitorHandle 1461
|
#define kNtErrorInvalidMonitorHandle 1461
|
||||||
#define kNtErrorIncorrectSize 1462
|
#define kNtErrorIncorrectSize 1462
|
||||||
#define kNtErrorSymlinkClassDisabled 1463
|
#define kNtErrorSymlinkClassDisabled 1463
|
||||||
|
|
|
@ -3554,6 +3554,13 @@ imp 'InetIsOffline' InetIsOffline url 106
|
||||||
imp 'MIMEAssociationDialog' MIMEAssociationDialogW url 108
|
imp 'MIMEAssociationDialog' MIMEAssociationDialogW url 108
|
||||||
imp 'MailToProtocolHandler' MailToProtocolHandler url 109
|
imp 'MailToProtocolHandler' MailToProtocolHandler url 109
|
||||||
|
|
||||||
|
# API-MS-Win-Core-Synch-l1-2-0.dll (Windows 8+)
|
||||||
|
#
|
||||||
|
# Name Actual DLL Hint Arity
|
||||||
|
imp 'WaitOnAddress' WaitOnAddress API-MS-Win-Core-Synch-l1-2-0 111 4
|
||||||
|
imp 'WakeByAddressAll' WakeByAddressAll API-MS-Win-Core-Synch-l1-2-0 113 1
|
||||||
|
imp 'WakeByAddressSingle' WakeByAddressSingle API-MS-Win-Core-Synch-l1-2-0 116 1
|
||||||
|
|
||||||
# NTDLL.DLL
|
# NTDLL.DLL
|
||||||
# BEYOND THE PALE
|
# BEYOND THE PALE
|
||||||
#
|
#
|
||||||
|
|
|
@ -167,6 +167,27 @@ $(LIBC_NT_URL_A).pkg: \
|
||||||
|
|
||||||
#───────────────────────────────────────────────────────────────────────────────
|
#───────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
LIBC_NT_ARTIFACTS += LIBC_NT_SYNCHRONIZATION_A
|
||||||
|
LIBC_NT_SYNCHRONIZATION = $(LIBC_NT_SYNCHRONIZATION_A_DEPS) $(LIBC_NT_SYNCHRONIZATION_A)
|
||||||
|
LIBC_NT_SYNCHRONIZATION_A = o/$(MODE)/libc/nt/synchronization.a
|
||||||
|
LIBC_NT_SYNCHRONIZATION_A_SRCS := $(wildcard libc/nt/API-MS-Win-Core-Synch-l1-2-0/*.s)
|
||||||
|
LIBC_NT_SYNCHRONIZATION_A_OBJS = $(LIBC_NT_SYNCHRONIZATION_A_SRCS:%.s=o/$(MODE)/%.o)
|
||||||
|
LIBC_NT_SYNCHRONIZATION_A_CHECKS = $(LIBC_NT_SYNCHRONIZATION_A).pkg
|
||||||
|
LIBC_NT_SYNCHRONIZATION_A_DIRECTDEPS = LIBC_NT_KERNEL32
|
||||||
|
LIBC_NT_SYNCHRONIZATION_A_DEPS := \
|
||||||
|
$(call uniq,$(foreach x,$(LIBC_NT_SYNCHRONIZATION_A_DIRECTDEPS),$($(x))))
|
||||||
|
|
||||||
|
$(LIBC_NT_SYNCHRONIZATION_A): \
|
||||||
|
libc/nt/API-MS-Win-Core-Synch-l1-2-0/ \
|
||||||
|
$(LIBC_NT_SYNCHRONIZATION_A).pkg \
|
||||||
|
$(LIBC_NT_SYNCHRONIZATION_A_OBJS)
|
||||||
|
|
||||||
|
$(LIBC_NT_SYNCHRONIZATION_A).pkg: \
|
||||||
|
$(LIBC_NT_SYNCHRONIZATION_A_OBJS) \
|
||||||
|
$(foreach x,$(LIBC_NT_SYNCHRONIZATION_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||||
|
|
||||||
|
#───────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
LIBC_NT_ARTIFACTS += LIBC_NT_USER32_A
|
LIBC_NT_ARTIFACTS += LIBC_NT_USER32_A
|
||||||
LIBC_NT_USER32 = $(LIBC_NT_USER32_A_DEPS) $(LIBC_NT_USER32_A)
|
LIBC_NT_USER32 = $(LIBC_NT_USER32_A_DEPS) $(LIBC_NT_USER32_A)
|
||||||
LIBC_NT_USER32_A = o/$(MODE)/libc/nt/user32.a
|
LIBC_NT_USER32_A = o/$(MODE)/libc/nt/user32.a
|
||||||
|
|
|
@ -54,6 +54,11 @@ typedef void (*NtTimerapcroutine)(void *lpArgToCompletionRoutine,
|
||||||
typedef void (*NtWaitOrTimerCallback)(void *lpParameter,
|
typedef void (*NtWaitOrTimerCallback)(void *lpParameter,
|
||||||
bool32 TimerOrWaitFired);
|
bool32 TimerOrWaitFired);
|
||||||
|
|
||||||
|
void WakeByAddressAll(void *Address);
|
||||||
|
void WakeByAddressSingle(void *Address);
|
||||||
|
bool32 WaitOnAddress(volatile void *Address, void *CompareAddress,
|
||||||
|
size_t AddressSize, uint32_t opt_dwMilliseconds);
|
||||||
|
|
||||||
void Sleep(uint32_t dwMilliseconds);
|
void Sleep(uint32_t dwMilliseconds);
|
||||||
uint32_t SleepEx(uint32_t dwMilliseconds, bool32 bAlertable);
|
uint32_t SleepEx(uint32_t dwMilliseconds, bool32 bAlertable);
|
||||||
|
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
# -*- conf -*-
|
|
||||||
# Cosmopolitan Libc Legacy Memory Plan
|
|
||||||
|
|
||||||
00000000-0000001f 2048kb guard
|
|
||||||
00000020-0000003f 2048kb loader
|
|
||||||
00000040-000000ff 12mb image
|
|
||||||
00000100-000003ff 48mb free
|
|
||||||
00000400-000007ff 64mb free
|
|
||||||
00000800-00000bff 64mb free
|
|
||||||
00000c00-00000fff 64mb free
|
|
||||||
00001000-000013ff 64mb automap
|
|
||||||
00001400-000017ff 64mb automap
|
|
||||||
00001800-00001bff 64mb automap
|
|
||||||
00001c00-00001fff 64mb automap
|
|
||||||
00002000-000023ff 64mb automap
|
|
||||||
00002400-000027ff 64mb automap
|
|
||||||
00002800-00002bff 64mb automap
|
|
||||||
00002c00-00002fff 64mb automap
|
|
||||||
00003000-000033ff 64mb automap
|
|
||||||
00003400-000037ff 64mb automap
|
|
||||||
00003800-00003bff 64mb automap
|
|
||||||
00003c00-00003fe7 63mb automap
|
|
||||||
00003fe4-00003ffb 1536kb memtrack
|
|
||||||
00003ffc-00003fff 256kb free
|
|
||||||
00004000-000043ff 64mb fixedmap
|
|
||||||
00004400-000047ff 64mb fixedmap
|
|
||||||
00004800-00004bff 64mb fixedmap
|
|
||||||
00004c00-00004fff 64mb fixedmap
|
|
||||||
00005000-000053ff 64mb fixedmap
|
|
||||||
00005400-000057ff 64mb fixedmap
|
|
||||||
00005800-00005bff 64mb fixedmap
|
|
||||||
00005c00-00005fff 64mb fixedmap
|
|
||||||
00006000-000063ff 64mb fixedmap
|
|
||||||
00006400-000067ff 64mb fixedmap
|
|
||||||
00006800-00006bff 64mb fixedmap
|
|
||||||
00006c00-00006fff 64mb fixedmap
|
|
||||||
00005000-000053ff 64mb arena
|
|
||||||
00005400-000057ff 64mb arena
|
|
||||||
00005800-00005bff 64mb arena
|
|
||||||
00005c00-00005fff 64mb arena
|
|
||||||
00006000-000063ff 64mb arena
|
|
||||||
00006400-000067ff 64mb arena
|
|
||||||
00006800-00006bff 64mb fds
|
|
||||||
00006c00-00006fff 64mb zipos
|
|
||||||
00007000-000073ff 64mb zipos
|
|
||||||
00007400-000077ff 64mb zipos
|
|
||||||
00007800-00007bff 64mb zipos
|
|
||||||
00007c00-00007ffd 64mb arena
|
|
||||||
00007ffe-00007fff 128kb free
|
|
||||||
00008000-000083ff 64mb free
|
|
||||||
00008400-000087ff 64mb free
|
|
||||||
00008800-00008bff 64mb free
|
|
||||||
00008c00-00008fff 64mb free
|
|
||||||
00009000-000093ff 64mb free
|
|
||||||
00009400-000097ff 64mb free
|
|
||||||
00009800-00009bff 64mb free
|
|
||||||
00009c00-00009fff 64mb free
|
|
||||||
0000a000-0000a3ff 64mb free
|
|
||||||
0000a400-0000a7ff 64mb free
|
|
||||||
0000a800-0000abff 64mb free
|
|
||||||
0000ac00-0000afff 64mb free
|
|
||||||
0000b000-0000b3ff 64mb free
|
|
||||||
0000b400-0000b7ff 64mb free
|
|
||||||
0000b800-0000bbff 64mb free
|
|
||||||
0000bc00-0000bfff 64mb free
|
|
||||||
0000c000-0000c3ff 64mb free
|
|
||||||
0000c400-0000c7ff 64mb free
|
|
||||||
0000c800-0000cbff 64mb free
|
|
||||||
0000cc00-0000cfff 64mb free
|
|
||||||
0000d000-0000d3ff 64mb free
|
|
||||||
0000d400-0000d7ff 64mb free
|
|
||||||
0000d800-0000dbff 64mb free
|
|
||||||
0000dc00-0000dfff 64mb free
|
|
||||||
0000e000-0000e3ff 64mb free
|
|
||||||
0000e400-0000e7ff 64mb free
|
|
||||||
0000e800-0000ebff 64mb free
|
|
||||||
0000ec00-0000efff 64mb free
|
|
||||||
0000f000-0000f3ff 64mb free
|
|
||||||
0000f400-0000f7ff 64mb free
|
|
||||||
0000f800-0000fbff 64mb free
|
|
||||||
0000fc00-0000fffb 64mb free
|
|
||||||
0000fffc-0000fffd 128kb winargs
|
|
||||||
0000fffe-0000ffff 128kb stack
|
|
|
@ -94,7 +94,7 @@ syscon errno EISCONN 106 56 56 56 56 10056 # socket is connected
|
||||||
syscon errno ENOTCONN 107 57 57 57 57 10057 # socket is not connected; bsd consensus; WSAENOTCONN; raised by getpeername(2), recv(2), send(2), shutdown(2), ip(7)
|
syscon errno ENOTCONN 107 57 57 57 57 10057 # socket is not connected; bsd consensus; WSAENOTCONN; raised by getpeername(2), recv(2), send(2), shutdown(2), ip(7)
|
||||||
syscon errno ESHUTDOWN 108 58 58 58 58 10058 # cannot send after transport endpoint shutdown; note that shutdown write is an EPIPE; bsd consensus; WSAESHUTDOWN
|
syscon errno ESHUTDOWN 108 58 58 58 58 10058 # cannot send after transport endpoint shutdown; note that shutdown write is an EPIPE; bsd consensus; WSAESHUTDOWN
|
||||||
syscon errno ETOOMANYREFS 109 59 59 59 59 10059 # too many references: cannot splice; bsd consensus; WSAETOOMANYREFS; raised by sendmsg(2), unix(7)
|
syscon errno ETOOMANYREFS 109 59 59 59 59 10059 # too many references: cannot splice; bsd consensus; WSAETOOMANYREFS; raised by sendmsg(2), unix(7)
|
||||||
syscon errno ETIMEDOUT 110 60 60 60 60 10060 # connection timed out; bsd consensus; WSAETIMEDOUT; raised by connect(2), futex(2), keyctl(2), tcp(7)
|
syscon errno ETIMEDOUT 110 60 60 60 60 1460 # connection timed out; kNtErrorTimeout; bsd consensus; WSAETIMEDOUT; raised by connect(2), futex(2), keyctl(2), tcp(7)
|
||||||
syscon errno ECONNREFUSED 111 61 61 61 61 10061 # bsd consensus; WSAECONNREFUSED; raised by connect(2), listen(2), recv(2), unix(7), udp(7)system-imposed limit on the number of threads was encountered.
|
syscon errno ECONNREFUSED 111 61 61 61 61 10061 # bsd consensus; WSAECONNREFUSED; raised by connect(2), listen(2), recv(2), unix(7), udp(7)system-imposed limit on the number of threads was encountered.
|
||||||
syscon errno EHOSTDOWN 112 64 64 64 64 10064 # bsd consensus; WSAEHOSTDOWN; raised by accept(2)
|
syscon errno EHOSTDOWN 112 64 64 64 64 10064 # bsd consensus; WSAEHOSTDOWN; raised by accept(2)
|
||||||
syscon errno EHOSTUNREACH 113 65 65 65 65 10065 # bsd consensus; WSAEHOSTUNREACH; raised by accept(2), ip(7)
|
syscon errno EHOSTUNREACH 113 65 65 65 65 10065 # bsd consensus; WSAEHOSTUNREACH; raised by accept(2), ip(7)
|
||||||
|
@ -1316,7 +1316,7 @@ syscon rusage RUSAGE_BOTH -2 99 99 99 99 99 # woop
|
||||||
#
|
#
|
||||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||||
syscon futex FUTEX_WAIT 0 0 0 1 0 0
|
syscon futex FUTEX_WAIT 0 0 0 1 0 0
|
||||||
syscon futex FUTEX_WAKE 1 0 0 2 0 0
|
syscon futex FUTEX_WAKE 1 0 0 2 0 1
|
||||||
syscon futex FUTEX_REQUEUE 3 0 0 3 0 0
|
syscon futex FUTEX_REQUEUE 3 0 0 3 0 0
|
||||||
syscon futex FUTEX_PRIVATE_FLAG 128 0 0 128 0 0
|
syscon futex FUTEX_PRIVATE_FLAG 128 0 0 128 0 0
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
.include "o/libc/sysv/consts/syscon.internal.inc"
|
.include "o/libc/sysv/consts/syscon.internal.inc"
|
||||||
.syscon errno,ETIMEDOUT,110,60,60,60,60,10060
|
.syscon errno,ETIMEDOUT,110,60,60,60,60,1460
|
||||||
.yoink kDos2Errno.ETIMEDOUT
|
.yoink kDos2Errno.ETIMEDOUT
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
.include "o/libc/sysv/consts/syscon.internal.inc"
|
.include "o/libc/sysv/consts/syscon.internal.inc"
|
||||||
.syscon futex,FUTEX_WAKE,1,0,0,2,0,0
|
.syscon futex,FUTEX_WAKE,1,0,0,2,0,1
|
||||||
|
|
|
@ -84,7 +84,7 @@ dir=libc/sysv/dos2errno
|
||||||
# dos WSAENOTCONN ENOTCONN # in consts.sh
|
# dos WSAENOTCONN ENOTCONN # in consts.sh
|
||||||
# dos WSAESHUTDOWN ESHUTDOWN # in consts.sh
|
# dos WSAESHUTDOWN ESHUTDOWN # in consts.sh
|
||||||
# dos WSAETOOMANYREFS ETOOMANYREFS # in consts.sh
|
# dos WSAETOOMANYREFS ETOOMANYREFS # in consts.sh
|
||||||
# dos WSAETIMEDOUT ETIMEDOUT # in consts.sh
|
# dos kNtErrorTimeout ETIMEDOUT # in consts.sh
|
||||||
# dos WSAECONNREFUSED ECONNREFUSED # in consts.sh
|
# dos WSAECONNREFUSED ECONNREFUSED # in consts.sh
|
||||||
# dos WSAEHOSTDOWN EHOSTDOWN # in consts.sh
|
# dos WSAEHOSTDOWN EHOSTDOWN # in consts.sh
|
||||||
# dos WSAEHOSTUNREACH EHOSTUNREACH # in consts.sh
|
# dos WSAEHOSTUNREACH EHOSTUNREACH # in consts.sh
|
||||||
|
@ -170,3 +170,4 @@ dos WSAEPROCLIM ENOMEM
|
||||||
dos WSANOTINITIALISED ENETDOWN
|
dos WSANOTINITIALISED ENETDOWN
|
||||||
dos WSASYSNOTREADY ENETDOWN
|
dos WSASYSNOTREADY ENETDOWN
|
||||||
dos WSAVERNOTSUPPORTED ENOSYS
|
dos WSAVERNOTSUPPORTED ENOSYS
|
||||||
|
dos WSAETIMEDOUT ETIMEDOUT
|
||||||
|
|
|
@ -9,3 +9,4 @@
|
||||||
.type kDos2Errno.ETIMEDOUT,@object
|
.type kDos2Errno.ETIMEDOUT,@object
|
||||||
kDos2Errno.ETIMEDOUT:
|
kDos2Errno.ETIMEDOUT:
|
||||||
.e kNtErrorSemTimeout,ETIMEDOUT
|
.e kNtErrorSemTimeout,ETIMEDOUT
|
||||||
|
.e WSAETIMEDOUT,ETIMEDOUT
|
||||||
|
|
87
test/libc/intrin/lockscale_test.c
Normal file
87
test/libc/intrin/lockscale_test.c
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/atomic.h"
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/struct/timespec.h"
|
||||||
|
#include "libc/intrin/intrin.h"
|
||||||
|
#include "libc/mem/gc.h"
|
||||||
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
#include "libc/testlib/testlib.h"
|
||||||
|
#include "libc/thread/thread.h"
|
||||||
|
#include "libc/time/time.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fileoverview Lock Waiter Scalability Test
|
||||||
|
*
|
||||||
|
* This test can be run as follows:
|
||||||
|
*
|
||||||
|
* make o//test/libc/intrin/lockscale_test.com.runs V=5 TESTARGS=-b
|
||||||
|
*
|
||||||
|
* It's intended to demonstrate the importance of futexes. On systems
|
||||||
|
* that don't have them, this test consumes orders of a magnitude more
|
||||||
|
* cpu time, because there's a lot of waiters and they need to wait a
|
||||||
|
* very long time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WAITERS 100
|
||||||
|
#define ITERATIONS 10000
|
||||||
|
|
||||||
|
atomic_int x;
|
||||||
|
pthread_t t[WAITERS];
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
pthread_barrier_t barrier;
|
||||||
|
|
||||||
|
void Worker(void) {
|
||||||
|
pthread_mutex_lock(&lock);
|
||||||
|
pthread_barrier_wait(&barrier);
|
||||||
|
for (x = 0; x < ITERATIONS; ++x) {
|
||||||
|
sched_yield();
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Waiter(void *arg) {
|
||||||
|
pthread_barrier_wait(&barrier);
|
||||||
|
pthread_mutex_lock(&lock);
|
||||||
|
ASSERT_EQ(ITERATIONS, x);
|
||||||
|
pthread_mutex_unlock(&lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCH(lock, scalability) {
|
||||||
|
int i;
|
||||||
|
struct timespec t1, t2;
|
||||||
|
t1 = _timespec_real();
|
||||||
|
pthread_mutex_init(&lock, 0);
|
||||||
|
pthread_barrier_init(&barrier, 0, WAITERS + 1);
|
||||||
|
for (i = 0; i < WAITERS; ++i) {
|
||||||
|
ASSERT_EQ(0, pthread_create(t + i, 0, Waiter, 0));
|
||||||
|
}
|
||||||
|
Worker();
|
||||||
|
for (i = 0; i < WAITERS; ++i) {
|
||||||
|
ASSERT_EQ(0, pthread_join(t[i], 0));
|
||||||
|
}
|
||||||
|
pthread_barrier_destroy(&barrier);
|
||||||
|
pthread_mutex_destroy(&lock);
|
||||||
|
t2 = _timespec_real();
|
||||||
|
printf("consumed %10g seconds monotonic time and %10g seconds cpu time\n",
|
||||||
|
_timespec_tonanos(_timespec_sub(t2, t1)) / 1000000000.,
|
||||||
|
(double)clock() / CLOCKS_PER_SEC);
|
||||||
|
}
|
89
third_party/nsync/futex.c
vendored
89
third_party/nsync/futex.c
vendored
|
@ -17,14 +17,19 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/struct/timespec.internal.h"
|
#include "libc/calls/struct/timespec.internal.h"
|
||||||
|
#include "libc/calls/syscall_support-nt.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/describeflags.internal.h"
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
#include "libc/intrin/strace.internal.h"
|
#include "libc/intrin/strace.internal.h"
|
||||||
|
#include "libc/limits.h"
|
||||||
|
#include "libc/nt/runtime.h"
|
||||||
|
#include "libc/nt/synchronization.h"
|
||||||
#include "libc/sysv/consts/futex.h"
|
#include "libc/sysv/consts/futex.h"
|
||||||
#include "libc/thread/thread.h"
|
#include "libc/thread/thread.h"
|
||||||
#include "third_party/nsync/common.internal.h"
|
#include "third_party/nsync/common.internal.h"
|
||||||
#include "third_party/nsync/futex.internal.h"
|
#include "third_party/nsync/futex.internal.h"
|
||||||
|
#include "third_party/nsync/mu_semaphore.internal.h"
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
/* futex() polyfill w/ sched_yield() fallback */
|
/* futex() polyfill w/ sched_yield() fallback */
|
||||||
|
@ -41,8 +46,18 @@ bool FUTEX_TIMEOUT_IS_ABSOLUTE;
|
||||||
__attribute__((__constructor__)) static void nsync_futex_init_ (void) {
|
__attribute__((__constructor__)) static void nsync_futex_init_ (void) {
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
|
||||||
if (!(FUTEX_IS_SUPPORTED = IsLinux() || IsOpenbsd()))
|
if (NSYNC_FUTEX_WIN32 && IsWindows ()) {
|
||||||
|
FUTEX_IS_SUPPORTED = true;
|
||||||
|
FUTEX_WAIT_ = FUTEX_WAIT;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(FUTEX_IS_SUPPORTED = IsLinux () || IsOpenbsd ())) {
|
||||||
|
// we're using sched_yield() so let's
|
||||||
|
// avoid needless clock_gettime calls
|
||||||
|
FUTEX_TIMEOUT_IS_ABSOLUTE = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// In our testing, we found that the monotonic clock on various
|
// In our testing, we found that the monotonic clock on various
|
||||||
// popular systems (such as Linux, and some BSD variants) was no
|
// popular systems (such as Linux, and some BSD variants) was no
|
||||||
|
@ -78,8 +93,30 @@ __attribute__((__constructor__)) static void nsync_futex_init_ (void) {
|
||||||
|
|
||||||
int nsync_futex_wait_ (int *p, int expect, char pshare, struct timespec *timeout) {
|
int nsync_futex_wait_ (int *p, int expect, char pshare, struct timespec *timeout) {
|
||||||
int rc, op;
|
int rc, op;
|
||||||
if (FUTEX_IS_SUPPORTED) {
|
uint32_t ms;
|
||||||
op = FUTEX_WAIT_;
|
|
||||||
|
if (!FUTEX_IS_SUPPORTED) {
|
||||||
|
nsync_yield_ ();
|
||||||
|
if (timeout) {
|
||||||
|
return -EINTR;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
op = FUTEX_WAIT_;
|
||||||
|
if (NSYNC_FUTEX_WIN32 && IsWindows ()) {
|
||||||
|
if (timeout) {
|
||||||
|
ms = _timespec_tomillis (*timeout);
|
||||||
|
} else {
|
||||||
|
ms = -1;
|
||||||
|
}
|
||||||
|
if (WaitOnAddress (p, &expect, sizeof(int), ms)) {
|
||||||
|
rc = 0;
|
||||||
|
} else {
|
||||||
|
rc = -GetLastError ();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (pshare == PTHREAD_PROCESS_PRIVATE) {
|
if (pshare == PTHREAD_PROCESS_PRIVATE) {
|
||||||
op |= FUTEX_PRIVATE_FLAG_;
|
op |= FUTEX_PRIVATE_FLAG_;
|
||||||
}
|
}
|
||||||
|
@ -88,35 +125,45 @@ int nsync_futex_wait_ (int *p, int expect, char pshare, struct timespec *timeout
|
||||||
// [jart] openbsd does this without setting carry flag
|
// [jart] openbsd does this without setting carry flag
|
||||||
rc = -rc;
|
rc = -rc;
|
||||||
}
|
}
|
||||||
STRACE("futex(%t, %s, %d, %s) → %s",
|
|
||||||
p, DescribeFutexOp(op), expect,
|
|
||||||
DescribeTimespec(0, timeout), DescribeFutexResult(rc));
|
|
||||||
} else {
|
|
||||||
nsync_yield_ ();
|
|
||||||
if (timeout) {
|
|
||||||
rc = -ETIMEDOUT;
|
|
||||||
} else {
|
|
||||||
rc = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STRACE("futex(%t, %s, %d, %s) → %s",
|
||||||
|
p, DescribeFutexOp (op), expect,
|
||||||
|
DescribeTimespec (0, timeout),
|
||||||
|
DescribeFutexResult (rc));
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nsync_futex_wake_ (int *p, int count, char pshare) {
|
int nsync_futex_wake_ (int *p, int count, char pshare) {
|
||||||
int rc, op;
|
int rc, op;
|
||||||
int wake (void *, int, int) asm ("_futex");
|
int wake (void *, int, int) asm ("_futex");
|
||||||
if (FUTEX_IS_SUPPORTED) {
|
|
||||||
op = FUTEX_WAKE;
|
ASSERT (count == 1 || count == INT_MAX);
|
||||||
|
|
||||||
|
if (!FUTEX_IS_SUPPORTED) {
|
||||||
|
nsync_yield_ ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
op = FUTEX_WAKE;
|
||||||
|
if (NSYNC_FUTEX_WIN32 && IsWindows ()) {
|
||||||
|
if (count == 1) {
|
||||||
|
WakeByAddressSingle (p);
|
||||||
|
} else {
|
||||||
|
WakeByAddressAll (p);
|
||||||
|
}
|
||||||
|
rc = 0;
|
||||||
|
} else {
|
||||||
if (pshare == PTHREAD_PROCESS_PRIVATE) {
|
if (pshare == PTHREAD_PROCESS_PRIVATE) {
|
||||||
op |= FUTEX_PRIVATE_FLAG_;
|
op |= FUTEX_PRIVATE_FLAG_;
|
||||||
}
|
}
|
||||||
rc = wake (p, op, count);
|
rc = wake (p, op, count);
|
||||||
STRACE("futex(%t, %s, %d) → %s", p,
|
|
||||||
DescribeFutexOp(op),
|
|
||||||
count, DescribeFutexResult(rc));
|
|
||||||
} else {
|
|
||||||
nsync_yield_ ();
|
|
||||||
rc = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STRACE("futex(%t, %s, %d) → %s", p,
|
||||||
|
DescribeFutexOp(op),
|
||||||
|
count, DescribeFutexResult(rc));
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
8
third_party/nsync/mu_semaphore.c
vendored
8
third_party/nsync/mu_semaphore.c
vendored
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
/* Initialize *s; the initial value is 0. */
|
/* Initialize *s; the initial value is 0. */
|
||||||
void nsync_mu_semaphore_init (nsync_semaphore *s) {
|
void nsync_mu_semaphore_init (nsync_semaphore *s) {
|
||||||
if (!IsWindows ())
|
if (NSYNC_FUTEX_WIN32 || !IsWindows ())
|
||||||
nsync_mu_semaphore_init_futex (s);
|
nsync_mu_semaphore_init_futex (s);
|
||||||
else
|
else
|
||||||
nsync_mu_semaphore_init_win32 (s);
|
nsync_mu_semaphore_init_win32 (s);
|
||||||
|
@ -31,7 +31,7 @@ void nsync_mu_semaphore_init (nsync_semaphore *s) {
|
||||||
|
|
||||||
/* Wait until the count of *s exceeds 0, and decrement it. */
|
/* Wait until the count of *s exceeds 0, and decrement it. */
|
||||||
void nsync_mu_semaphore_p (nsync_semaphore *s) {
|
void nsync_mu_semaphore_p (nsync_semaphore *s) {
|
||||||
if (!IsWindows ())
|
if (NSYNC_FUTEX_WIN32 || !IsWindows ())
|
||||||
nsync_mu_semaphore_p_futex (s);
|
nsync_mu_semaphore_p_futex (s);
|
||||||
else
|
else
|
||||||
nsync_mu_semaphore_p_win32 (s);
|
nsync_mu_semaphore_p_win32 (s);
|
||||||
|
@ -41,7 +41,7 @@ void nsync_mu_semaphore_p (nsync_semaphore *s) {
|
||||||
the count of *s is non-zero, in which case decrement *s and return 0;
|
the count of *s is non-zero, in which case decrement *s and return 0;
|
||||||
or abs_deadline expires, in which case return ETIMEDOUT. */
|
or abs_deadline expires, in which case return ETIMEDOUT. */
|
||||||
int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline) {
|
int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline) {
|
||||||
if (!IsWindows ())
|
if (NSYNC_FUTEX_WIN32 || !IsWindows ())
|
||||||
return nsync_mu_semaphore_p_with_deadline_futex (s, abs_deadline);
|
return nsync_mu_semaphore_p_with_deadline_futex (s, abs_deadline);
|
||||||
else
|
else
|
||||||
return nsync_mu_semaphore_p_with_deadline_win32 (s, abs_deadline);
|
return nsync_mu_semaphore_p_with_deadline_win32 (s, abs_deadline);
|
||||||
|
@ -49,7 +49,7 @@ int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadl
|
||||||
|
|
||||||
/* Ensure that the count of *s is at least 1. */
|
/* Ensure that the count of *s is at least 1. */
|
||||||
void nsync_mu_semaphore_v (nsync_semaphore *s) {
|
void nsync_mu_semaphore_v (nsync_semaphore *s) {
|
||||||
if (!IsWindows ())
|
if (NSYNC_FUTEX_WIN32 || !IsWindows ())
|
||||||
nsync_mu_semaphore_v_futex (s);
|
nsync_mu_semaphore_v_futex (s);
|
||||||
else
|
else
|
||||||
nsync_mu_semaphore_v_win32 (s);
|
nsync_mu_semaphore_v_win32 (s);
|
||||||
|
|
5
third_party/nsync/mu_semaphore.internal.h
vendored
5
third_party/nsync/mu_semaphore.internal.h
vendored
|
@ -2,6 +2,11 @@
|
||||||
#define NSYNC_MU_SEMAPHORE_INTERNAL_H_
|
#define NSYNC_MU_SEMAPHORE_INTERNAL_H_
|
||||||
#include "third_party/nsync/mu_semaphore.h"
|
#include "third_party/nsync/mu_semaphore.h"
|
||||||
#include "third_party/nsync/time.h"
|
#include "third_party/nsync/time.h"
|
||||||
|
|
||||||
|
#ifndef NSYNC_FUTEX_WIN32
|
||||||
|
#define NSYNC_FUTEX_WIN32 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
|
7
third_party/nsync/mu_semaphore_win32.c
vendored
7
third_party/nsync/mu_semaphore_win32.c
vendored
|
@ -15,6 +15,7 @@
|
||||||
│ See the License for the specific language governing permissions and │
|
│ See the License for the specific language governing permissions and │
|
||||||
│ limitations under the License. │
|
│ limitations under the License. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/state.internal.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/nt/enum/wait.h"
|
#include "libc/nt/enum/wait.h"
|
||||||
#include "libc/nt/synchronization.h"
|
#include "libc/nt/synchronization.h"
|
||||||
|
@ -32,14 +33,14 @@ https://github.com/google/nsync\"");
|
||||||
/* Initialize *s; the initial value is 0. */
|
/* Initialize *s; the initial value is 0. */
|
||||||
void nsync_mu_semaphore_init_win32 (nsync_semaphore *s) {
|
void nsync_mu_semaphore_init_win32 (nsync_semaphore *s) {
|
||||||
int64_t *h = (int64_t *) s;
|
int64_t *h = (int64_t *) s;
|
||||||
*h = CreateSemaphore(NULL, 0, 1, NULL);
|
*h = CreateSemaphore (&kNtIsInheritable, 0, 1, NULL);
|
||||||
if (!*h) notpossible;
|
if (!*h) notpossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait until the count of *s exceeds 0, and decrement it. */
|
/* Wait until the count of *s exceeds 0, and decrement it. */
|
||||||
void nsync_mu_semaphore_p_win32 (nsync_semaphore *s) {
|
void nsync_mu_semaphore_p_win32 (nsync_semaphore *s) {
|
||||||
int64_t *h = (int64_t *) s;
|
int64_t *h = (int64_t *) s;
|
||||||
WaitForSingleObject(*h, -1u);
|
WaitForSingleObject (*h, -1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait until one of:
|
/* Wait until one of:
|
||||||
|
@ -50,7 +51,7 @@ int nsync_mu_semaphore_p_with_deadline_win32 (nsync_semaphore *s, nsync_time abs
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (nsync_time_cmp (abs_deadline, nsync_time_no_deadline) == 0) {
|
if (nsync_time_cmp (abs_deadline, nsync_time_no_deadline) == 0) {
|
||||||
result = WaitForSingleObject(*h, -1u);
|
result = WaitForSingleObject (*h, -1u);
|
||||||
} else {
|
} else {
|
||||||
nsync_time now;
|
nsync_time now;
|
||||||
now = nsync_time_now ();
|
now = nsync_time_now ();
|
||||||
|
|
1
third_party/nsync/nsync.mk
vendored
1
third_party/nsync/nsync.mk
vendored
|
@ -27,6 +27,7 @@ THIRD_PARTY_NSYNC_A_DIRECTDEPS = \
|
||||||
LIBC_INTRIN \
|
LIBC_INTRIN \
|
||||||
LIBC_NEXGEN32E \
|
LIBC_NEXGEN32E \
|
||||||
LIBC_NT_KERNEL32 \
|
LIBC_NT_KERNEL32 \
|
||||||
|
LIBC_NT_SYNCHRONIZATION \
|
||||||
LIBC_STR \
|
LIBC_STR \
|
||||||
LIBC_STUBS \
|
LIBC_STUBS \
|
||||||
LIBC_SYSV \
|
LIBC_SYSV \
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
ASCII2UTF8=$(command -v ascii2utf8.com 2>/dev/null) || {
|
||||||
|
ASCII2UTF8=$(ls -1 o/*/tool/viz/ascii2utf8.com | head -n1)
|
||||||
|
}
|
||||||
|
|
||||||
for x; do
|
for x; do
|
||||||
nroff -mandoc -rLL=80n -rLT=80n -Tutf8 <"$x" |
|
nroff -mandoc -rLL=80n -rLT=80n -Tutf8 <"$x" | $ASCII2UTF8
|
||||||
o//tool/viz/ascii2utf8.com
|
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in a new issue