haiku/headers/private
Augustin Cavalier 6f3f29c7dd user_mutex: Refactor locking and unblocking mechanism.
Suppose the following scenario:

1. Thread A holds a mutex.

2. Thread B goes to acquire the mutex, winds up in kernel waiting.

3. Thread A unlocks; first unsets the LOCKED flag.
   As WAITING is set, it calls the kernel; but instead of processing
   this immediately, the thread is suspended for any reason (locks,
   reschedule, etc.)

4. Thread B hits a timeout, or a signal. It then unblocks in the kernel,
   which causes the WAITING flag to be unset.

5. Thread C goes to acquire the lock. It sets the LOCKED flag.
   It sees the WAITING flag is not set, so it returns at once,
   having successfully acquired the lock.

6. Thread A, suspended back in step 3, resumes.

Now we encounter the problem. Under the previous code, the following
would occur.

7. Thread A sees that no threads are waiting. It thus unsets the LOCKED
   flag, and returns from the kernel. Now we have a mutex theoretically
   held by thread C but which (illegally) has no LOCKED flag set!

8. Some other thread tries to acquire the lock, and succeeds, for LOCKED
   is not set. We now have one lock owned by two separate threads.
   That's very bad!

The solution, in this commit, is to (1) switch from using "atomic_or"
to lock mutexes, to using "atomic_test_and_set", and (2) mandate that
_kern_unblock_mutex must be invoked with the mutex already unlocked.

Trying to solve the problem with (2) but without (1) produces other
complications and would overall be more complicated. For instance,
all existing userland code expected that it would set LOCKED, but then
check LOCKED|WAITING. If _kern_mutex_unlock does not unset LOCKED,
then whichever thread sets LOCKED when it was previously unset is
now the mutex's undisputed owner, and if it fails to notice this,
would deadlock.

That could have been solved with extra checks at all lock points, but
then that would mean locks would not be acquired "fairly": it would
be possible for any thread to race with an unlocking thread, and
acquire the lock before the kernel had a chance to wake anyone up.

Given how fast atomics can be, and how slow invoking the kernel is
comparatively, that would probably make our mutexes extremely "unfair."
This would not violate the POSIX specification, but it does seem like
a dangerous choice to make in implementing these APIs.

Linux's "futex" API, which our API bears some similarities to, requires
at least one atomic test-and-set for an uncontended acquisition,
and multiple atomics more for even the simplest case of contended
acquisition. If it works for them, it should work for us, too.

Fixes #18436.

Change-Id: Ib8c28acf04ce03234fe738e41aa0969ca1917540
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6537
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
2023-06-08 16:49:05 +00:00
..
app BFont: allow loading of user fonts from disk or memory 2022-12-17 12:32:09 +00:00
audio audio: Move hmulti_audio driver API to private audio headers 2018-10-23 16:33:19 +02:00
binary_compatibility BControl: Add icon support 2013-12-22 02:48:25 +01:00
bluetooth Bluetooth Pref: Inactiveate button and things that don't do anything. 2021-04-10 20:28:43 +00:00
debug Move comment to correct function. 2013-05-01 19:52:00 -04:00
debugger Add (void*) casts to memcpy/memset invocations to appease GCC 8. 2019-05-24 14:21:37 -04:00
device acpi_battery: support for _BIX method. 2020-03-10 13:14:09 +00:00
drivers poke: use phys_addr_t for mem_map_args's physical_address field 2023-01-02 15:02:32 +00:00
file_systems file_systems/fs_ops_support: Add open_mode_to_access. 2023-01-27 23:53:53 -05:00
firewire Minor tweaks to fix the build after the last commit. 2019-03-26 20:06:09 -04:00
fs_shell kernel/util: Clean-ups to DoublyLinkedList insertion routines. 2023-04-01 12:31:39 -04:00
graphics intel_extreme: check another register when finding out hw_cdclk on Haswell/Broadwell 2022-11-26 12:56:08 +00:00
i2c i2c: add acquire_bus/release_bus hooks 2020-04-12 16:55:52 +00:00
index_server Add a CLucene full-text add-on. 2010-10-28 15:22:52 +00:00
input ps2 synaptics: implement 'extended W' mode. 2023-01-28 14:57:53 +00:00
interface View: provide the transform between different coordinate spaces 2022-11-13 04:04:30 +00:00
kernel user_mutex: Refactor locking and unblocking mechanism. 2023-06-08 16:49:05 +00:00
libroot libroot: Disambiguate parameters of ICUCollateData::Strxfrm. 2023-04-08 14:17:15 -04:00
locale locale kit: allow creating a catalog without entry_ref 2020-09-01 18:14:57 +00:00
mail build: Cleanup of libgnuregex usage. 2018-03-07 18:04:31 -05:00
media media_kit: Dynamic allocation of ChunkCache based on media 2021-01-03 20:51:37 +00:00
midi Midi: Remove some duplicated code 2015-08-27 11:51:57 +02:00
mount
net net_interface & datalink: Fix MTU handling. 2022-05-27 16:36:12 -04:00
netservices netservices: remove all old conditional code 2021-09-11 13:08:11 +01:00
netservices2 NetServices: format code using haiku-format 2022-10-29 22:53:57 +01:00
notification Notification_Server: Added ability to choose position of notifications 2017-12-24 12:02:38 +01:00
package Package Kit: Use an object_cache in kernel mode for decompression buffers. 2023-02-28 13:49:00 -05:00
preferences Fix glitch in Screen prefs when changing background color. 2017-04-30 10:29:39 +02:00
print Game & Print Kits: Fix GCC 11 warnings. 2021-11-17 18:45:58 -05:00
runtime_loader runtime_loader: dlopen() should respect RPATH of the loading module 2021-03-18 08:19:55 +00:00
screen_saver ScreenSaver: Rename BuildScreenSaverDefaultSettingsView 2016-04-13 15:50:30 -07:00
shared Move BarberPole from HaikuDepot to libshared 2023-04-29 16:11:43 +00:00
storage Disk Device Manager: checks the raw content_name when editing a partition 2022-09-30 17:10:39 +00:00
support ZstdCompressionAlgorithm: 22 is now "best" in libzstd. 2021-10-26 16:47:50 -04:00
syslog_daemon syslog_daemon: Converted to BServer. 2015-07-22 20:40:47 +02:00
system user_mutex: Refactor locking and unblocking mechanism. 2023-06-08 16:49:05 +00:00
textencoding
tracker Tracker: Use BControlLook::ComposeIconSize. 2022-08-25 16:48:56 -04:00
usb_vision some copyright headers clean up 2010-04-12 21:02:09 +00:00
userlandfs userlandfs: implement get_fs_info using ioctl 2022-09-13 18:51:12 +00:00
virtio virtio: add VIRTIO_FEATURE_ANY_LAYOUT in virtio.h 2022-02-18 21:27:47 +00:00
vmdk
wmi wmi: add ACPI WMI implementation 2020-04-20 14:56:59 +00:00