mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-12 05:59:10 +00:00
Refactor some code
- Write tests for cthreads - Fix bugs in pe2.com tool - Fix ASAN issue with GetDosEnviron() - Consolidate the cthread header files - Some code size optimizations for MODE= - Attempted to squash a tls linker warning - Attempted to get futexes working on FreeBSD
This commit is contained in:
parent
909e54510d
commit
425ff5dff0
61 changed files with 529 additions and 382 deletions
|
@ -468,7 +468,8 @@ int sys_clone_linux(int flags, char *stk, int *ptid, int *ctid, void *tls,
|
|||
* effectively work around libc features like atfork(), so that means
|
||||
* other calls like getpid() may return incorrect values.
|
||||
*
|
||||
* @param func is your callback function
|
||||
* @param func is your callback function, which this wrapper requires
|
||||
* not be null, otherwise EINVAL is raised
|
||||
* @param stk points to the bottom of a caller allocated stack, which
|
||||
* must be allocated via mmap() using the MAP_STACK flag, or else
|
||||
* you won't get optimal performance and it won't work on OpenBSD
|
||||
|
@ -532,20 +533,22 @@ int clone(int (*func)(void *), void *stk, size_t stksz, int flags, void *arg,
|
|||
__threaded = gettid();
|
||||
}
|
||||
|
||||
if (IsAsan() &&
|
||||
((stksz > PAGESIZE &&
|
||||
!__asan_is_valid((char *)stk + PAGESIZE, stksz - PAGESIZE)) ||
|
||||
((flags & CLONE_SETTLS) && !__asan_is_valid(tls, tlssz)) ||
|
||||
((flags & CLONE_SETTLS) && !__asan_is_valid(tls, sizeof(long))) ||
|
||||
((flags & CLONE_PARENT_SETTID) &&
|
||||
!__asan_is_valid(ptid, sizeof(*ptid))) ||
|
||||
((flags & CLONE_CHILD_SETTID) &&
|
||||
!__asan_is_valid(ctid, sizeof(*ctid))))) {
|
||||
rc = efault();
|
||||
if (!func) {
|
||||
rc = einval();
|
||||
} else if (!IsTiny() &&
|
||||
(((flags & CLONE_VM) && (stksz < PAGESIZE || (stksz & 15))) ||
|
||||
((flags & CLONE_SETTLS) && (tlssz < 64 || (tlssz & 7))))) {
|
||||
rc = einval();
|
||||
} else if (IsAsan() &&
|
||||
((stksz > PAGESIZE &&
|
||||
!__asan_is_valid((char *)stk + PAGESIZE, stksz - PAGESIZE)) ||
|
||||
((flags & CLONE_SETTLS) && !__asan_is_valid(tls, tlssz)) ||
|
||||
((flags & CLONE_SETTLS) && !__asan_is_valid(tls, sizeof(long))) ||
|
||||
((flags & CLONE_PARENT_SETTID) &&
|
||||
!__asan_is_valid(ptid, sizeof(*ptid))) ||
|
||||
((flags & CLONE_CHILD_SETTID) &&
|
||||
!__asan_is_valid(ctid, sizeof(*ctid))))) {
|
||||
rc = efault();
|
||||
} else if (IsLinux()) {
|
||||
rc =
|
||||
sys_clone_linux(flags, (char *)stk + stksz, ptid, ctid, tls, func, arg);
|
||||
|
|
|
@ -125,7 +125,7 @@ textwindows noasan noinstrument int GetDosEnviron(const char16_t *env,
|
|||
while (*env) {
|
||||
if (i + 1 < max) envp[i++] = buf;
|
||||
r = Recode16to8(buf, size, env);
|
||||
if ((p = memchr(buf, '=', r.ax)) && IsAlpha(p[1]) && p[2] == ':' &&
|
||||
if ((p = MemChr(buf, '=', r.ax)) && IsAlpha(p[1]) && p[2] == ':' &&
|
||||
(p[3] == '\\' || p[3] == '/')) {
|
||||
FixPath(p + 1);
|
||||
}
|
||||
|
|
|
@ -16,29 +16,56 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/atomic.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/lockcmpxchg.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
typedef void *pthread_t;
|
||||
typedef bool pthread_once_t;
|
||||
typedef int pthread_once_t;
|
||||
typedef int pthread_mutex_t;
|
||||
|
||||
int pthread_once(pthread_once_t *once, void init(void)) {
|
||||
if (_lockcmpxchg(once, 0, 1)) init();
|
||||
int x;
|
||||
unsigned tries;
|
||||
switch ((x = atomic_load(once))) {
|
||||
case 0:
|
||||
if (atomic_compare_exchange_strong(once, &x, 1)) {
|
||||
init();
|
||||
atomic_store(once, 2);
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case 1:
|
||||
tries = 0;
|
||||
do {
|
||||
if (++tries & 7) {
|
||||
__builtin_ia32_pause();
|
||||
} else {
|
||||
sched_yield();
|
||||
}
|
||||
} while (atomic_load(once) == 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_lock(pthread_mutex_t *mutex) {
|
||||
return EINVAL;
|
||||
_spinlock(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_trylock(pthread_mutex_t *mutex) {
|
||||
return EINVAL;
|
||||
return _trylock(mutex);
|
||||
}
|
||||
|
||||
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
|
||||
return EPERM;
|
||||
_spunlock(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_cancel(pthread_t thread) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue