Commit graph

37 commits

Author SHA1 Message Date
Tom Cherry
c6b5bcd182 Add _monotonic_np versions of timed wait functions
As a follow up to Ibba98f5d88be1c306d14e9b9366302ecbef6d534, where we
added a work around to convert the CLOCK_REALTIME timeouts to
CLOCK_MONOTONIC for pthread and semaphore timed wait functions, we're
introducing a set of _monotonic_np versions of each of these functions
that wait on CLOCK_MONOTONIC directly.

The primary motivation here is that while the above work around helps
for 3rd party code, it creates a dilemma when implementing new code
that would use these functions: either one implements code with these
functions knowing there is a race condition possible or one avoids
these functions and reinvent their own waiting/signaling mechanisms.
Neither are satisfactory, so we create a third option to use these
Android specific _monotonic_np functions that completely remove the
race condition while keeping the rest of the interface.

Specifically this adds the below functions:
pthread_mutex_timedlock_monotonic_np()
pthread_cond_timedwait_monotonic_np()
pthread_rwlock_timedrdlock_monotonic_np()
pthread_rwlock_timedwrlock_monotonic_np()
sem_timedwait_monotonic_np()

Note that pthread_cond_timedwait_monotonic_np() previously existed and
was removed since it's possible to initialize a condition variable to
use CLOCK_MONOTONIC.  It is added back for a mix of reasons,
1) Symmetry with the rest of the functions we're adding
2) libc++ cannot easily take advantage of the new initializer, but
   will be able to use this function in order to wait on
   std::steady_clock
3) Frankly, it's a better API to specify the clock in the waiter function
   than to specify the clock when the condition variable is
   initialized.

Bug: 73951740
Test: new unit tests
Change-Id: I23aa5c204e36a194237d41e064c5c8ccaa4204e3
2018-03-20 18:41:22 -07:00
Yabin Cui
9651fdf93a Check using destroyed mutexes.
For apps built for Android < P, return EBUSY.
For apps built for Android >= P, abort.

This is to keep old apps work, and help debugging
apps built for >= P.

Bug: http://b/74632097
Test: run bionic-unit-tests.
Test: run bionic-benchmark.

Change-Id: I5271565a1a6ad12678f85d558a7f862a2b7aab4b
2018-03-15 10:44:30 -07:00
Yabin Cui
2dec3d7021 Avoid abort when calling pthread_mutex_destroy more than once.
Bug: http://b/72878088
Test: run bionic-unit-tests.
Change-Id: I0c3a6c5a625d187d5f32ec8c821cfdd5e807a671
2018-02-02 15:45:24 -08:00
Yabin Cui
5a00ba7c1c Support priority inheritance mutex in 32-bit programs.
Add fast path calling PIMutexTryLock() in pthread_mutex_lock.
Add trace for pi mutex waiting.

Bug: http://b/29177606
Test: run bionic-unit-tests.
Test: run bionic-benchmarks.

Change-Id: I30b6436692d5ea6b63ca9905df745edb843b5528
2018-02-01 16:01:46 -08:00
Yabin Cui
6b9c85b36d Support priority inheritance mutex in 64bit programs.
Bug: http://b/29177606
Test: run bionic-unit-tests on walleye.
Test: run bionic-unit-tests-glibc on host.
Change-Id: Iac349284aa73515f384e7509445f87434757f59e
2018-01-24 16:11:07 -08:00
Dan Albert
baa2a973bd Use clang's nullability instead of nonnull.
http://clang.llvm.org/docs/AttributeReference.html#nonnull

_Nonnull is similar to the nonnull attribute in that it will instruct
compilers to warn the user if it can prove that a null argument is
being passed. Unlike the nonnull attribute, this annotation indicated
that a value *should not* be null, not that it *cannot* be null, or
even that the behavior is undefined. The important distinction is that
the optimizer will perform surprising optimizations like the
following:

    void foo(void*) __attribute__(nonnull, 1);

    int bar(int* p) {
      foo(p);

      // The following null check will be elided because nonnull
      // attribute means that, since we call foo with p, p can be
      // assumed to not be null. Thus this will crash if we are called
      // with a null pointer.
      if (src != NULL) {
        return *p;
      }
      return 0;
    }

    int main() {
      return bar(NULL);
    }

Note that by doing this we are no longer attaching any sort of
attribute for GCC (GCC doesn't support attaching nonnull directly to a
parameter, only to the function and naming the arguments
positionally). This means we won't be getting a warning for this case
from GCC any more. People that listen to warnings tend to use clang
anyway, and we're quickly moving toward that as the default, so this
seems to be an acceptable tradeoff.

Change-Id: Ie05fe7cec2f19a082c1defb303f82bcf9241b88d
2016-05-05 17:11:54 -07:00
Elliott Hughes
dd586f2ebd sem_timedwait with a null timeout doesn't mean "forever".
It actually means "crash immediately". Well, it's an error. And callers are
much more likely to realize their mistake if we crash immediately rather
than return EINVAL. Historically, glibc has crashed and bionic -- before
the recent changes -- returned EINVAL, so this is a behavior change.

Change-Id: I0c2373a6703b20b8a97aacc1e66368a5885e8c51
2015-12-16 15:15:58 -08:00
Yabin Cui
74ed96d597 Merge "Use FUTEX_WAIT_BITSET to avoid converting timeouts." 2015-11-21 01:50:29 +00:00
Yabin Cui
c9a659c57b Use FUTEX_WAIT_BITSET to avoid converting timeouts.
Add unittests for pthread APIs with timeout parameter.

Bug: 17569991

Change-Id: I6b3b9b2feae03680654cd64c3112ce7644632c87
2015-11-19 13:42:03 -08:00
Yabin Cui
0307eee293 Avoid tsan warning about pthread_mutex_destroy.
If calling pthread_mutex_trylock from pthread_mutex_destroy, tsan
warns about an attempt to destroy a locked mutex.

Bug: 25392375
Change-Id: I5feee20e7a0d0915adad24da874ec1ccce241381
2015-11-17 16:17:44 -08:00
Christopher Ferris
511cfd9dc8 Allow NULL in pthread_mutex_lock/unlock.
The pthread_mutex_lock and pthread_mutex_unlock were allowed to
fail silently on L 32 bit devices when passed a NULL. We changed
this to a crash on 32 bit devices, but there are still games that make
these calls and are not likely to be updated. Therefore, once again
allow NULL to be passed in on 32 bit devices.

Bug: 19995172
Change-Id: If7e8860075ecd63c0064d80f64e226fad7bd3c26
2015-06-09 18:46:15 -07:00
Yabin Cui
f796985923 Fix bug for recursive/errorcheck mutex on 32-bit devices.
Bug: 19216648
Change-Id: I3b43b2d18d25b9bde352da1e35f9568133dec7cf
2015-04-03 19:01:17 -07:00
Yabin Cui
e69c24543d Refactor pthread_mutex to support 32-bit owner_tid on 64-bit devices.
Bug: 19216648
Change-Id: I765ecacc9036659c766f5d1f6600e1a65364199b
2015-04-01 21:12:22 -07:00
Yabin Cui
17393b06ba Hide internal of pthread_mutex_t.
Bug: 19249079
Change-Id: Iffb79c8d861b698d474f212dc80c638fc2cf1620
2015-03-25 17:54:17 -07:00
Yabin Cui
ecbfb25c50 Fix build: pthread_mutex/pthread_detach.
Change-Id: I9c7b6297d3bf3ab8004d05d44cc4c95159315c9e
2015-03-17 11:37:51 -07:00
Yabin Cui
5b8e7cd957 Remove duplication in pthread_mutex.cpp.
Also add unit tests about thread woken up by pthread_mutex_unlock.

Bug: 19216648

Change-Id: I8bde8105b00186c52a2f41d92458ae4a5eb90426
2015-03-12 21:54:41 -07:00
Yabin Cui
140f3678f0 Add test about pthread_mutex_t owner tid limit.
Bug: 19216648
Change-Id: I7b12955bdcad31c13bf8ec2740ff88ba15223ec0
2015-02-03 12:20:46 -08:00
Yabin Cui
86fc96f733 Switch pthread_mutex_t from bionic atomics to <stdatomic.h>.
Bug: 17574456
Change-Id: I5ce3d3dc07e804e9ce55c42920f47531b56e04de
2015-02-02 15:00:01 -08:00
Elliott Hughes
5b1111a694 POSIX says pthread_mutex_trylock returns EBUSY, not EDEADLK.
Found by unit test.

Change-Id: Iffbd2f04213616927fbd7b5419460031f7a078e9
2014-10-24 19:33:11 -07:00
Elliott Hughes
3d773274ad Revert "Work around a bug in Immersion's libImmEmulatorJ.so."
This reverts commit 7d3f553f98.

Change-Id: I8909b6aa1d97e9a61dbe95a2d91b9fbe336b58f0
2014-10-07 23:31:06 +00:00
Elliott Hughes
7d3f553f98 Work around a bug in Immersion's libImmEmulatorJ.so.
This library calls pthread_mutex_lock and pthread_mutex_unlock with a NULL
pthread_mutex_t*. This gives them (and their users) one release to fix things.

Bug: 17443936
Change-Id: I3b63c9a3dd63db0833f21073e323b3236a13b47a
2014-10-07 16:02:11 -07:00
Elliott Hughes
04303f5a8a Add semaphore tests, fix sem_destroy.
Bug: https://code.google.com/p/android/issues/detail?id=76088
Change-Id: I4a0561b23e90312384d40a1c804ca64ee98f4066
2014-09-19 17:37:06 -07:00
Brigid Smith
a406ee6d5f Added a bionic systrace class and tracing to pthread_mutex.cpp.
bionic_systrace.h contains an implementation of tracing that
can be used with systrace.py and its associated viewer.  pthread_mutex
now uses this tracing to track pthread_mutex contention, which can be
enabled by using the "bionic" command line option to systrace.

Bug: 15116468
Change-Id: I30ed5b377c91ca4c36568a0e647ddf95d4e4a61a
2014-07-28 19:38:08 -07:00
Elliott Hughes
624996026b Minor style cleanup of some code I had to look at.
(It turns out that this is the only place we're saying __inline in C++.)

Change-Id: I8095e67a385087817c47caab9a621f82f8e0cfc8
2014-05-28 20:30:40 -07:00
Brigid Smith
ff03a7aaad Updated ambiguous comment in pthread_mutex_lock.
The comment used the phrase "normal case" when it more specifically refers to the "recursive case," so I changed it to that.

Change-Id: I8335cce4dee933c6a463aee653b28bd986b5b5e4
2014-05-28 11:48:49 -07:00
Elliott Hughes
2ea60ff0b4 Remove unnecessary #includes of <sys/atomics.h>.
Bug: 14903517
Change-Id: I7b5bcebe58774a441da986cc02376dd88e00ea0e
2014-05-22 11:00:21 -07:00
Elliott Hughes
07f1ded139 Remove the broken pthread deadlock prediction.
This hasn't built in over one release cycle and no one even noticed.
art does this the right way and other projects should do the same.

Change-Id: I7d1fb84c4080e008f329ee73e209ce85a36e6d55
2014-05-14 11:38:22 -07:00
Elliott Hughes
b676aafad0 Remove unnecessary #includes.
Change-Id: Ie7e0c9ea03f35517c7dcf09fc808c12e55262bc1
2014-04-10 17:50:06 -07:00
Elliott Hughes
39b644a0e2 Remove dead NULL checks from pthread code.
GCC is removing these checks anyway because it knows the arguments
must be non-null, so leaving this code around is just confusing.

We know from experience that people were shipping code with locking
bugs because they weren't checking for error returns. Failing hard
like glibc does seems the better choice. (And it's what the checked
in code was already doing; this patch doesn't change that. It just
makes it more obvious that that's what's going on.)

Change-Id: I167c6d7c0a296822baf0cb9b43b97821eba7ab35
2014-03-04 10:55:39 -08:00
Elliott Hughes
0e714a5b41 Implement POSIX pthread_mutex_timedlock.
This replaces the non-standard pthread_mutex_lock_timeout_np, which we have
to keep around on LP32 for binary compatibility.

Change-Id: I098dc7cd38369f0c1bec1fac35687fbd27392e00
2014-03-04 10:27:58 -08:00
Elliott Hughes
9e79af3b61 Small style cleanup.
Change-Id: Ib45a4a2296232968296f9bd7cc3592ba46fd412d
2013-12-18 10:05:42 -08:00
Elliott Hughes
611b903ca7 Merge "Properly detect timeout in pthread_mutex_lock_timeout_np_impl" 2013-12-18 17:56:22 +00:00
Ken Mixter
4fae14f333 Properly detect timeout in pthread_mutex_lock_timeout_np_impl
Previously we were checking against a positive errno which
would not be returned from a system call.

Change-Id: I8e3a36f6fbf5ccc2191a152a1def37e2d6f93124
2013-12-17 14:26:01 -08:00
Elliott Hughes
dff7203ee9 Remove harmful attempts to be helpful in pthread_mutex functions.
Most callers won't check for EINVAL, so it's best to fail early.
GCC takes the nonnull attribute as a guarantee that an argument
won't be NULL, so these hacks were already ineffective, which is
how we found that at least one commercial game was using NULL
as if it's a mutex, but actually getting no-op behavior.

Bug: 11971278
Change-Id: I89646e043d931778805a8b692e07a34d076ee6bf
2013-12-11 14:54:00 -08:00
Elliott Hughes
36d6188f8c Clean up forking and cloning.
The kernel now maintains the pthread_internal_t::tid field for us,
and __clone was only used in one place so let's inline it so we don't
have to leave such a dangerous function lying around. Also rename
files to match their content and remove some useless #includes.

Change-Id: I24299fb4a940e394de75f864ee36fdabbd9438f9
2013-11-19 14:08:54 -08:00
Elliott Hughes
66759d6041 Move the pthread debugging flags to the right place.
Change-Id: Ie805bd837d1f72cdf1818e056c0baeb0857e4e84
2013-10-31 14:09:39 -07:00
Elliott Hughes
c3f114037d <pthread.h> fixes and pthread cleanup.
<pthread.h> was missing nonnull attributes, noreturn on pthread_exit,
and had incorrect cv qualifiers for several standard functions.

I've also marked the non-standard stuff (where I count glibc rather
than POSIX as "standard") so we can revisit this cruft for LP64 and
try to ensure we're compatible with glibc.

I've also broken out the pthread_cond* functions into a new file.

I've made the remaining pthread files (plus ptrace) part of the bionic code
and fixed all the warnings.

I've added a few more smoke tests for chunks of untested pthread functionality.

We no longer need the libc_static_common_src_files hack for any of the
pthread implementation because we long since stripped out the rest of
the armv5 support, and this hack was just to ensure that __get_tls in libc.a
went via the kernel if necessary.

This patch also finishes the job of breaking up the pthread.c monolith, and
adds a handful of new tests.

Change-Id: Idc0ae7f5d8aa65989598acd4c01a874fe21582c7
2013-10-31 12:31:16 -07:00
Renamed from libc/bionic/pthread.c (Browse further)