<feed xmlns='http://www.w3.org/2005/Atom'>
<title>musl/src/thread, branch v1.1.23</title>
<subtitle>musl - an implementation of the standard library for Linux-based systems</subtitle>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/'/>
<entry>
<title>add riscv64 architecture support</title>
<updated>2019-06-14T21:13:05+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-05-24T14:46:08+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=0a48860c27a8eb291bcc7616ea9eb073dc660cab'/>
<id>0a48860c27a8eb291bcc7616ea9eb073dc660cab</id>
<content type='text'>
Author: Alex Suykov &lt;alex.suykov@gmail.com&gt;
Author: Aric Belsito &lt;lluixhi@gmail.com&gt;
Author: Drew DeVault &lt;sir@cmpwn.com&gt;
Author: Michael Clark &lt;mjc@sifive.com&gt;
Author: Michael Forney &lt;mforney@mforney.org&gt;
Author: Stefan O'Rear &lt;sorear2@gmail.com&gt;

This port has involved the work of many people over several years. I
have tried to ensure that everyone with substantial contributions has
been credited above; if any omissions are found they will be noted
later in an update to the authors/contributors list in the COPYRIGHT
file.

The version committed here comes from the riscv/riscv-musl repo's
commit 3fe7e2c75df78eef42dcdc352a55757729f451e2, with minor changes by
me for issues found during final review:

- a_ll/a_sc atomics are removed (according to the ISA spec, lr/sc
  are not safe to use in separate inline asm fragments)

- a_cas[_p] is fixed to be a memory barrier

- the call from the _start assembly into the C part of crt1/ldso is
  changed to allow for the possibility that the linker does not place
  them nearby each other.

- DTP_OFFSET is defined correctly so that local-dynamic TLS works

- reloc.h LDSO_ARCH logic is simplified and made explicit.

- unused, non-functional crti/n asm files are removed.

- an empty .sdata section is added to crt1 so that the
  __global_pointer reference is resolvable.

- indentation style errors in some asm files are fixed.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Author: Alex Suykov &lt;alex.suykov@gmail.com&gt;
Author: Aric Belsito &lt;lluixhi@gmail.com&gt;
Author: Drew DeVault &lt;sir@cmpwn.com&gt;
Author: Michael Clark &lt;mjc@sifive.com&gt;
Author: Michael Forney &lt;mforney@mforney.org&gt;
Author: Stefan O'Rear &lt;sorear2@gmail.com&gt;

This port has involved the work of many people over several years. I
have tried to ensure that everyone with substantial contributions has
been credited above; if any omissions are found they will be noted
later in an update to the authors/contributors list in the COPYRIGHT
file.

The version committed here comes from the riscv/riscv-musl repo's
commit 3fe7e2c75df78eef42dcdc352a55757729f451e2, with minor changes by
me for issues found during final review:

- a_ll/a_sc atomics are removed (according to the ISA spec, lr/sc
  are not safe to use in separate inline asm fragments)

- a_cas[_p] is fixed to be a memory barrier

- the call from the _start assembly into the C part of crt1/ldso is
  changed to allow for the possibility that the linker does not place
  them nearby each other.

- DTP_OFFSET is defined correctly so that local-dynamic TLS works

- reloc.h LDSO_ARCH logic is simplified and made explicit.

- unused, non-functional crti/n asm files are removed.

- an empty .sdata section is added to crt1 so that the
  __global_pointer reference is resolvable.

- indentation style errors in some asm files are fixed.
</pre>
</div>
</content>
</entry>
<entry>
<title>remove external __syscall function and last remaining users</title>
<updated>2019-04-11T00:11:19+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-04-11T00:11:19+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=788d5e24ca19c6291cebd8d1ad5b5ed6abf42665'/>
<id>788d5e24ca19c6291cebd8d1ad5b5ed6abf42665</id>
<content type='text'>
the weak version of __syscall_cp_c was using a tail call to __syscall
to avoid duplicating the 6-argument syscall code inline in small
static-linked programs, but now that __syscall no longer exists, the
inline expansion is no longer duplication.

the syscall.h machinery suppported up to 7 syscall arguments, only via
an external __syscall function, but we presently have no syscall call
points that actually make use of that many, and the kernel only
defines 7-argument calling conventions for arm, powerpc (32-bit), and
sh. if it turns out we need them in the future, they can easily be
added.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the weak version of __syscall_cp_c was using a tail call to __syscall
to avoid duplicating the 6-argument syscall code inline in small
static-linked programs, but now that __syscall no longer exists, the
inline expansion is no longer duplication.

the syscall.h machinery suppported up to 7 syscall arguments, only via
an external __syscall function, but we presently have no syscall call
points that actually make use of that many, and the kernel only
defines 7-argument calling conventions for arm, powerpc (32-bit), and
sh. if it turns out we need them in the future, they can easily be
added.
</pre>
</div>
</content>
</entry>
<entry>
<title>overhaul i386 syscall mechanism not to depend on external asm source</title>
<updated>2019-04-10T21:10:36+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-04-10T21:10:36+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=22e5bbd0deadcbd767864bd714e890b70e1fe1df'/>
<id>22e5bbd0deadcbd767864bd714e890b70e1fe1df</id>
<content type='text'>
this is the first part of a series of patches intended to make
__syscall fully self-contained in the object file produced using
syscall.h, which will make it possible for crt1 code to perform
syscalls.

the (confusingly named) i386 __vsyscall mechanism, which this commit
removes, was introduced before the presence of a valid thread pointer
was mandatory; back then the thread pointer was setup lazily only if
threads were used. the intent was to be able to perform syscalls using
the kernel's fast entry point in the VDSO, which can use the sysenter
(Intel) or syscall (AMD) instruction instead of int $128, but without
inlining an access to the __syscall global at the point of each
syscall, which would incur a significant size cost from PIC setup
everywhere. the mechanism also shuffled registers/calling convention
around to avoid spills of call-saved registers, and to avoid
allocating ebx or ebp via asm constraints, since there are plenty of
broken-but-supported compiler versions which are incapable of
allocating ebx with -fPIC or ebp with -fno-omit-frame-pointer.

the new mechanism preserves the properties of avoiding spills and
avoiding allocation of ebx/ebp in constraints, but does it inline,
using some fairly simple register shuffling, and uses a field of the
thread structure rather than global data for the vdso-provided syscall
code address.

for now, the external __syscall function is refactored not to use the
old __vsyscall so it can be kept, but the intent is to remove it too.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
this is the first part of a series of patches intended to make
__syscall fully self-contained in the object file produced using
syscall.h, which will make it possible for crt1 code to perform
syscalls.

the (confusingly named) i386 __vsyscall mechanism, which this commit
removes, was introduced before the presence of a valid thread pointer
was mandatory; back then the thread pointer was setup lazily only if
threads were used. the intent was to be able to perform syscalls using
the kernel's fast entry point in the VDSO, which can use the sysenter
(Intel) or syscall (AMD) instruction instead of int $128, but without
inlining an access to the __syscall global at the point of each
syscall, which would incur a significant size cost from PIC setup
everywhere. the mechanism also shuffled registers/calling convention
around to avoid spills of call-saved registers, and to avoid
allocating ebx or ebp via asm constraints, since there are plenty of
broken-but-supported compiler versions which are incapable of
allocating ebx with -fPIC or ebp with -fno-omit-frame-pointer.

the new mechanism preserves the properties of avoiding spills and
avoiding allocation of ebx/ebp in constraints, but does it inline,
using some fairly simple register shuffling, and uses a field of the
thread structure rather than global data for the vdso-provided syscall
code address.

for now, the external __syscall function is refactored not to use the
old __vsyscall so it can be kept, but the intent is to remove it too.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix harmless-by-chance typo in priority inheritance mutex code</title>
<updated>2019-04-01T22:51:50+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-04-01T22:51:50+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=8ee0ca0ce6cc04f3283e5391773108376ba5b4aa'/>
<id>8ee0ca0ce6cc04f3283e5391773108376ba5b4aa</id>
<content type='text'>
commit 54ca677983d47529bab8752315ac1a2b49888870 inadvertently
introduced bitwise and where logical and was intended. since the
right-hand operand is always 0 or -1 whenever the left-hand operand is
nonzero, the behavior happened to be equivalent.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 54ca677983d47529bab8752315ac1a2b49888870 inadvertently
introduced bitwise and where logical and was intended. since the
right-hand operand is always 0 or -1 whenever the left-hand operand is
nonzero, the behavior happened to be equivalent.
</pre>
</div>
</content>
</entry>
<entry>
<title>implement priority inheritance mutexes</title>
<updated>2019-04-01T00:59:13+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-03-31T22:03:27+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=54ca677983d47529bab8752315ac1a2b49888870'/>
<id>54ca677983d47529bab8752315ac1a2b49888870</id>
<content type='text'>
priority inheritance is a feature to mitigate priority inversion
situations, where a execution of a medium-priority thread can
unboundedly block forward progress of a high-priority thread when a
lock it needs is held by a low-priority thread.

the natural way to do priority inheritance would be with a simple
futex flag to donate the calling thread's priority to a target thread
while it waits on the futex. unfortunately, linux does not offer such
an interface, but instead insists on implementing the whole locking
protocol in kernelspace with special futex commands that exist solely
for the purpose of doing PI mutexes. this would require the entire
"trylock" logic to be duplicated in the timedlock code path for PI
mutexes, since, once the previous lock holder releases the lock and
the futex call returns, the lock is already held by the caller.
obviously such code duplication is undesirable.

instead, I've made the PI timedlock success path set the mutex lock
count to -1, which can be thought of as "not yet complete", since a
lock count of 0 is "locked, with no recursive references". a simple
branch in a non-hot path of pthread_mutex_trylock can then see and act
on this state, skipping past the code that would check and take the
lock to the same code path that runs after the lock is obtained for a
non-PI mutex.

because we're forced to let the kernel perform the actual lock and
unlock operations whenever the mutex is contended, we have to patch
things up when it does the wrong thing:

1. the lock operation is not aware of whether the mutex is
   error-checking, so it will always fail with EDEADLK rather than
   deadlocking.

2. the lock operation is not aware of whether the mutex is robust, so
   it will successfully obtain mutexes in the owner-died state even if
   they're non-robust, whereas this operation should deadlock.

3. the unlock operation always sets the lock value to zero, whereas
   for robust mutexes, we want to set it to a special value indicating
   that the mutex obtained after its owner died was unlocked without
   marking it consistent, so that future operations all fail with
   ENOTRECOVERABLE.

the first of these is easy to solve, just by performing a futex wait
on a dummy futex address to simulate deadlock or ETIMEDOUT as
appropriate. but problems 2 and 3 interact in a nasty way. to solve
problem 2, we need to back out the spurious success. but if waiters
are present -- which we can't just ignore, because even if we don't
want to wake them, the calling thread is incorrectly inheriting their
priorities -- this requires using the kernel's unlock operation, which
will zero the lock value, thereby losing the "owner died with lock
held" state.

to solve these problems, we overload the mutex's waiters field, which
is unused for PI mutexes since they don't call the normal futex wait
functions, as an indicator that the PI mutex is permanently
non-lockable. originally I wanted to use the count field, but there is
one code path that needs to access this flag without synchronization:
trylock's CAS failure path needs to be able to decide whether to fail
with EBUSY or ENOTRECOVERABLE, the waiters field is already treated as
a relaxed-order atomic in our memory model, so this works out nicely.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
priority inheritance is a feature to mitigate priority inversion
situations, where a execution of a medium-priority thread can
unboundedly block forward progress of a high-priority thread when a
lock it needs is held by a low-priority thread.

the natural way to do priority inheritance would be with a simple
futex flag to donate the calling thread's priority to a target thread
while it waits on the futex. unfortunately, linux does not offer such
an interface, but instead insists on implementing the whole locking
protocol in kernelspace with special futex commands that exist solely
for the purpose of doing PI mutexes. this would require the entire
"trylock" logic to be duplicated in the timedlock code path for PI
mutexes, since, once the previous lock holder releases the lock and
the futex call returns, the lock is already held by the caller.
obviously such code duplication is undesirable.

instead, I've made the PI timedlock success path set the mutex lock
count to -1, which can be thought of as "not yet complete", since a
lock count of 0 is "locked, with no recursive references". a simple
branch in a non-hot path of pthread_mutex_trylock can then see and act
on this state, skipping past the code that would check and take the
lock to the same code path that runs after the lock is obtained for a
non-PI mutex.

because we're forced to let the kernel perform the actual lock and
unlock operations whenever the mutex is contended, we have to patch
things up when it does the wrong thing:

1. the lock operation is not aware of whether the mutex is
   error-checking, so it will always fail with EDEADLK rather than
   deadlocking.

2. the lock operation is not aware of whether the mutex is robust, so
   it will successfully obtain mutexes in the owner-died state even if
   they're non-robust, whereas this operation should deadlock.

3. the unlock operation always sets the lock value to zero, whereas
   for robust mutexes, we want to set it to a special value indicating
   that the mutex obtained after its owner died was unlocked without
   marking it consistent, so that future operations all fail with
   ENOTRECOVERABLE.

the first of these is easy to solve, just by performing a futex wait
on a dummy futex address to simulate deadlock or ETIMEDOUT as
appropriate. but problems 2 and 3 interact in a nasty way. to solve
problem 2, we need to back out the spurious success. but if waiters
are present -- which we can't just ignore, because even if we don't
want to wake them, the calling thread is incorrectly inheriting their
priorities -- this requires using the kernel's unlock operation, which
will zero the lock value, thereby losing the "owner died with lock
held" state.

to solve these problems, we overload the mutex's waiters field, which
is unused for PI mutexes since they don't call the normal futex wait
functions, as an indicator that the PI mutex is permanently
non-lockable. originally I wanted to use the count field, but there is
one code path that needs to access this flag without synchronization:
trylock's CAS failure path needs to be able to decide whether to fail
with EBUSY or ENOTRECOVERABLE, the waiters field is already treated as
a relaxed-order atomic in our memory model, so this works out nicely.
</pre>
</div>
</content>
</entry>
<entry>
<title>clean up access to mutex type in pthread_mutex_trylock</title>
<updated>2019-03-29T19:49:14+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-03-29T19:49:14+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=2142cafdc7692428b5f993fe211279d1ed2e7271'/>
<id>2142cafdc7692428b5f993fe211279d1ed2e7271</id>
<content type='text'>
there was no point in masking off the pshared bit when first loading
the type, since every subsequent access involves a mask anyway. not
masking it may avoid a subsequent load to check the pshared flag, and
it's just simpler.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
there was no point in masking off the pshared bit when first loading
the type, since every subsequent access involves a mask anyway. not
masking it may avoid a subsequent load to check the pshared flag, and
it's just simpler.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix data race choosing next key slot in pthread_key_create</title>
<updated>2019-03-21T17:58:12+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-03-21T17:58:12+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=59f88d766263344ce3e124d969ba66720aff4590'/>
<id>59f88d766263344ce3e124d969ba66720aff4590</id>
<content type='text'>
commit 84d061d5a31c9c773e29e1e2b1ffe8cb9557bc58 wrongly moved the
access to the global next_key outside of the scope of the lock. the
error manifested as spurious failure to find an available key slot
under concurrent calls to pthread_key_create, since the stopping
condition could be met after only a small number of slots were
examined.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 84d061d5a31c9c773e29e1e2b1ffe8cb9557bc58 wrongly moved the
access to the global next_key outside of the scope of the lock. the
error manifested as spurious failure to find an available key slot
under concurrent calls to pthread_key_create, since the stopping
condition could be met after only a small number of slots were
examined.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix namespace violation in dependencies of mtx_lock</title>
<updated>2019-03-14T03:23:26+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-03-14T03:23:26+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=c62dfe61611cee4b9b2667e1aec8a20385bc5c55'/>
<id>c62dfe61611cee4b9b2667e1aec8a20385bc5c55</id>
<content type='text'>
commit 2de29bc994029b903a366b8a4a9f8c3c3ee2be90 left behind one
reference to pthread_mutex_trylock. fixing this also improves code
generation due to the namespace-safe version being hidde.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 2de29bc994029b903a366b8a4a9f8c3c3ee2be90 left behind one
reference to pthread_mutex_trylock. fixing this also improves code
generation due to the namespace-safe version being hidde.
</pre>
</div>
</content>
</entry>
<entry>
<title>add membarrier syscall wrapper, refactor dynamic tls install to use it</title>
<updated>2019-02-22T08:25:39+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-02-22T07:56:10+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=ba18c1ecc6a18203ad8496791154af86f706f632'/>
<id>ba18c1ecc6a18203ad8496791154af86f706f632</id>
<content type='text'>
the motivation for this change is twofold. first, it gets the fallback
logic out of the dynamic linker, improving code readability and
organization. second, it provides application code that wants to use
the membarrier syscall, which depends on preregistration of intent
before the process becomes multithreaded unless unbounded latency is
acceptable, with a symbol that, when linked, ensures that this
registration happens.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the motivation for this change is twofold. first, it gets the fallback
logic out of the dynamic linker, improving code readability and
organization. second, it provides application code that wants to use
the membarrier syscall, which depends on preregistration of intent
before the process becomes multithreaded unless unbounded latency is
acceptable, with a symbol that, when linked, ensures that this
registration happens.
</pre>
</div>
</content>
</entry>
<entry>
<title>make thread list lock a recursive lock</title>
<updated>2019-02-22T07:29:21+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-02-22T07:29:21+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=7865d569de7b29dd90b94b5680ec7a2a86ed27af'/>
<id>7865d569de7b29dd90b94b5680ec7a2a86ed27af</id>
<content type='text'>
this is a prerequisite for factoring the membarrier fallback code into
a function that can be called from a context with the thread list
already locked or independently.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
this is a prerequisite for factoring the membarrier fallback code into
a function that can be called from a context with the thread list
already locked or independently.
</pre>
</div>
</content>
</entry>
</feed>
