Conversation
There was a problem hiding this comment.
Summary of Changes
Hello @kamilaboba123, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request significantly enhances the operating system's synchronization capabilities by integrating futexes. The primary goal is to boost the performance of existing mutex implementations by minimizing costly kernel transitions, thereby making inter-process and inter-thread communication more efficient. This is a foundational change that provides a low-level primitive for building more performant synchronization mechanisms.
Highlights
- New Feature: Futexes: I've introduced the core implementation of Futexes (Fast Userspace Mutexes) to improve synchronization performance by reducing the number of kernel-mode context switches for common mutex operations. This includes the definition of futex structures and their associated sleep queue management.
- New Syscalls: Two new syscalls,
futex_waitandfutex_wakeup, have been added to allow userspace processes to interact with the new futex mechanism. These syscalls enable threads to wait on a futex address and to wake up threads waiting on a specific futex address, respectively. - Process and Thread Integration: The
process_tstructure has been extended to include an array offutex_sleepqueue_tto manage futex waits per process. Additionally, a newproc_threadSleep2function was introduced inthreads.cto provide a more granular sleep mechanism for futex operations, allowing the rawerrnofrom rescheduling to be returned. - Build System Update: The
proc/Makefilehas been updated to include the newfutex.oobject file, ensuring the futex implementation is compiled and linked into the system.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
8ca0353 to
6029fe3
Compare
24d3ff7 to
6d26238
Compare
b3aea9c to
4194625
Compare
b0cba44 to
9caff4e
Compare
678318f to
c15f0bf
Compare
c15f0bf to
09f272a
Compare
47aa3a5 to
c5b8000
Compare
proc/futex.c
Outdated
| LIST_REMOVE(&sleepqueue->waitctxs, wc); | ||
| tmp = atomic_load(&wc->thread); | ||
| atomic_store(&wc->thread, NULL); | ||
| if (proc_threadWakeupOne(tmp)) { |
There was a problem hiding this comment.
What if this thread was killed while it was still waiting? Are we handling that case properly here?
c5b8000 to
198d23b
Compare
fc4bd9a to
5d194f6
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces futexes to the kernel, a significant feature that should improve synchronization performance. The implementation includes new syscalls for futex operations and refactors user-level interrupt handling to use futexes instead of condition variables. The old mutex and condition variable syscalls have been correctly removed.
Overall, the changes are well-structured. However, I've identified a critical bug in the proc_futexWakeup function that would cause it to wake up an incorrect number of threads. I've also included a comment on a potential design limitation regarding the fixed size of the futex hash table.
| #define FUTEX_SLEEPQUEUES_BITS 6 | ||
| #define FUTEX_SLEEPQUEUES_SIZE (1U << FUTEX_SLEEPQUEUES_BITS) | ||
| #define FUTEX_SLEEPQUEUES_MASK (FUTEX_SLEEPQUEUES_SIZE - 1) |
There was a problem hiding this comment.
The size of the futex sleep queue hash table is fixed at 64 entries per process. If a process uses more than 64 distinct futexes concurrently, _proc_allocFutexSleepQueue will fail, and futex operations will return -ENOMEM. While this might be sufficient for many use cases, it could be a limitation for complex applications with many synchronization objects.
Consider if this size should be larger or configurable to avoid this potential resource exhaustion.
6b06aa6 to
33bd2eb
Compare
003ec29 to
580ed66
Compare
proc/userintr.c
Outdated
| #include "futex.h" | ||
|
|
||
|
|
||
| #define COND_BROADCAST (((u32)-1) / 2) |
There was a problem hiding this comment.
[clang-format-pr] reported by reviewdog 🐶
suggested fix
| #define COND_BROADCAST (((u32)-1) / 2) | |
| #define COND_BROADCAST (((u32) - 1) / 2) |
Darchiv
left a comment
There was a problem hiding this comment.
I would prefer this change to be split into: 1) a commit which adds futex syscalls in a backward-compatible manner (provides just the new waiting mechanism); 2) a commit which makes current sync mechanisms (mutex etc.) use futexes. This way it will be easier to test futexes alone, without forcing the whole system to use them.
| ID(sys_uname) \ | ||
| \ | ||
| ID(phFutexWait) \ | ||
| ID(phFutexWakeup) |
There was a problem hiding this comment.
FYI: You remove syscalls, so it doesn't matter if you add new ones in a backward compatible manner (as last) or not, because it is already a breaking change which requires a rebuild. phFutexWait etc. can be placed by similar primitive syscalls, e.g. phInterrupt.
proc/futex.c
Outdated
|
|
||
| key = address >> 3; | ||
| key ^= key >> FUTEX_SLEEPQUEUES_BITS; | ||
| idx = key & FUTEX_SLEEPQUEUES_MASK; |
There was a problem hiding this comment.
Not obvious what this bit-mangling does. Add a comment which describes that this is a simple hash-table implementation or something.
Or make generic macros which will contain these operations (and deduplicate with _proc_getFutexSleepQueue()), with a self-documenting name (as we all love self-documenting code) - this way a comment will not be necessary. Yes, the implementation should be comprehensible by just looking at the code.
proc/futex.h
Outdated
|
|
||
| int proc_futexWait(_Atomic(u32) *address, u32 value, time_t timeout, int clockType); | ||
| int proc_futexWakeup(struct _process_t *process, _Atomic(u32) *address, u32 wakeCount); | ||
| futex_sleepqueue_t *_proc_getFutexSleepQueue(struct _process_t *process, addr_t address); |
There was a problem hiding this comment.
Why export if not used outside of futex.c?
proc/futex.c
Outdated
| int err = EOK; | ||
| time_t waitTime = 0, offs; | ||
|
|
||
| if (clockType != PH_CLOCK_REALTIME && clockType != PH_CLOCK_RELATIVE && clockType != PH_CLOCK_MONOTONIC) { |
There was a problem hiding this comment.
This can be replaced by just adding a default case for the switch-case below.
clockType is used only when timeout != 0, so it makes sense to only check it in this case (performance + code size). Also, if not using timeout, the user should be able to use this function without looking up valid values for clockType, i.e. just pass 0 or -1. If PH_CLOCK_* values were completely arbitrary and did not include 0, then the user would be forced to use a specific PH_CLOCK_* value even if not using timeout or an additional value would have to be added (e.g. PH_CLOCK_NONE).
| hal_spinlockSet(¤t->process->futexSqSpinlock, &sqSc); | ||
| sq = _proc_getFutexSleepQueue(current->process, (addr_t)address); | ||
| if (sq == NULL) { | ||
| sq = _proc_allocFutexSleepQueue(current->process, (addr_t)address); |
There was a problem hiding this comment.
So, basically, once we allocate a sleep queue, we never free it.
I assume that you wanted to mimic futex syscall from other OSes, but can't we actually have a futexCreate syscall which will allocate a sleep queue (kernel side of futex, not including the userspace context) on idtree and release it via resourcesDestroy()?
580ed66 to
f6fd125
Compare
proc/futex.c
Outdated
| #include "futex.h" | ||
|
|
||
|
|
||
| u32 _proc_futexTableHash(addr_t address) |
There was a problem hiding this comment.
Not exported, used internally. Should be static
proc/futex.c
Outdated
|
|
||
| if (atomic_load(address) != value) { | ||
| err = -EAGAIN; | ||
| goto done; |
There was a problem hiding this comment.
Please avoid using goto (see: coding convention on docs). If you really need to use the non-structured paradigm (or it vastly increases readability), consider using a do-while. For example:
phoenix-rtos-kernel/posix/unix.c
Lines 407 to 463 in e35fd78
But it seems an overkill for just one branch (goto).
77b0b56 to
0e79cfc
Compare
JIRA: RTOS-1074
TODO: - Remove condition variables and mutexes from resources and their implementations (proc/mutex.c, proc/cond.c) - Remove syscall implementations for phMutexCreate, phMutexLock, mutexTry, mutexUnlock, phCondCreate, phCondWait, condSignal, condBroadcast from syscalls.c JIRA: RTOS-1074
0e79cfc to
ac4f6a1
Compare
Implement futexes
Description
Implement futexes, add new syscalls: futex_wait(), futex_wakeup()
Motivation and Context
Futexes fix performance issues with the current mutex implementation, by reducing
the amount of syscalls.
Types of changes
How Has This Been Tested?
ia32-generic-qemu
Checklist:
Special treatment