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:
Justine Tunney 2022-05-28 05:50:01 -07:00
parent 909e54510d
commit 425ff5dff0
61 changed files with 529 additions and 382 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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) {