mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
rust_binder: Update looper_flags bitmaps to use kernel::impl_flags!
Thread looper states are currently represented as raw integers and manipulated via bitwise operations. This lacks type safety, making it possible to mix up different flag types without compile-time warnings. Use kernel::impl_flags! to migrate looper_flags to a strongly-typed bitmask, enforcing compile-time safety. Key changes: - Define `LooperFlags(u32)` and `LooperFlag` enum with 7 variants. - Change `InnerThread.looper_flags` type to `LooperFlags`. - Update looper state transitions and checks to use type-safe methods. - Convert `looper_flags` to `u32` for hex formatting in `debug_print`. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Jahnavi MN <jahnavimn@google.com> Link: https://patch.msgid.link/20260719-b4-rust_binder_impl_flags-v3-1-f8d0b3ea1b87@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
19183c0ef0
commit
d6e8b74fe7
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
use kernel::{
|
||||
bindings,
|
||||
bits::bit_u32,
|
||||
fs::LocalFile,
|
||||
list::{AtomicTracker, List, ListArc, ListLinks, TryNewListArc},
|
||||
prelude::*,
|
||||
|
|
@ -245,7 +246,7 @@ fn is_ok(&self) -> bool {
|
|||
struct InnerThread {
|
||||
/// Determines the looper state of the thread. It is a bit-wise combination of the constants
|
||||
/// prefixed with `LOOPER_`.
|
||||
looper_flags: u32,
|
||||
looper_flags: LooperFlags,
|
||||
|
||||
/// Determines whether the looper should return.
|
||||
looper_need_return: bool,
|
||||
|
|
@ -272,13 +273,23 @@ struct InnerThread {
|
|||
extended_error: ExtendedError,
|
||||
}
|
||||
|
||||
const LOOPER_REGISTERED: u32 = 0x01;
|
||||
const LOOPER_ENTERED: u32 = 0x02;
|
||||
const LOOPER_EXITED: u32 = 0x04;
|
||||
const LOOPER_INVALID: u32 = 0x08;
|
||||
const LOOPER_WAITING: u32 = 0x10;
|
||||
const LOOPER_WAITING_PROC: u32 = 0x20;
|
||||
const LOOPER_POLL: u32 = 0x40;
|
||||
kernel::impl_flags!(
|
||||
/// Represents multiple looper flags.
|
||||
#[derive(Debug, Clone, Default, Copy, PartialEq, Eq)]
|
||||
pub struct LooperFlags(u32);
|
||||
|
||||
/// Represents a single looper flag.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum LooperFlag {
|
||||
Registered = bit_u32(0),
|
||||
Entered = bit_u32(1),
|
||||
Exited = bit_u32(2),
|
||||
Invalid = bit_u32(3),
|
||||
Waiting = bit_u32(4),
|
||||
WaitingProc = bit_u32(5),
|
||||
Poll = bit_u32(6),
|
||||
}
|
||||
);
|
||||
|
||||
impl InnerThread {
|
||||
fn new(pid: i32) -> Result<Self> {
|
||||
|
|
@ -288,7 +299,7 @@ fn next_err_id() -> u32 {
|
|||
}
|
||||
|
||||
Ok(Self {
|
||||
looper_flags: 0,
|
||||
looper_flags: LooperFlags::default(),
|
||||
looper_need_return: false,
|
||||
is_dead: false,
|
||||
process_work_list: false,
|
||||
|
|
@ -316,7 +327,7 @@ fn push_work(&mut self, work: DLArc<dyn DeliverToRead>) -> PushWorkRes {
|
|||
}
|
||||
self.work_list.push_back(work);
|
||||
self.process_work_list = true;
|
||||
if self.looper_flags & LOOPER_POLL != 0 {
|
||||
if self.looper_flags.contains(LooperFlag::Poll) {
|
||||
PushWorkRes::OkNotifyPoll
|
||||
} else {
|
||||
PushWorkRes::Ok
|
||||
|
|
@ -380,26 +391,27 @@ fn pop_transaction_replied(&mut self, transaction: &DArc<Transaction>) -> bool {
|
|||
}
|
||||
|
||||
fn looper_enter(&mut self) {
|
||||
self.looper_flags |= LOOPER_ENTERED;
|
||||
if self.looper_flags & LOOPER_REGISTERED != 0 {
|
||||
self.looper_flags |= LOOPER_INVALID;
|
||||
self.looper_flags |= LooperFlag::Entered;
|
||||
if self.looper_flags.contains(LooperFlag::Registered) {
|
||||
self.looper_flags |= LooperFlag::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
fn looper_register(&mut self, valid: bool) {
|
||||
self.looper_flags |= LOOPER_REGISTERED;
|
||||
if !valid || self.looper_flags & LOOPER_ENTERED != 0 {
|
||||
self.looper_flags |= LOOPER_INVALID;
|
||||
self.looper_flags |= LooperFlag::Registered;
|
||||
if !valid || self.looper_flags.contains(LooperFlag::Entered) {
|
||||
self.looper_flags |= LooperFlag::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
fn looper_exit(&mut self) {
|
||||
self.looper_flags |= LOOPER_EXITED;
|
||||
self.looper_flags |= LooperFlag::Exited;
|
||||
}
|
||||
|
||||
/// Determines whether the thread is part of a pool, i.e., if it is a looper.
|
||||
fn is_looper(&self) -> bool {
|
||||
self.looper_flags & (LOOPER_ENTERED | LOOPER_REGISTERED) != 0
|
||||
self.looper_flags
|
||||
.contains_any(LooperFlag::Entered | LooperFlag::Registered)
|
||||
}
|
||||
|
||||
/// Determines whether the thread should attempt to fetch work items from the process queue.
|
||||
|
|
@ -411,7 +423,7 @@ fn should_use_process_work_queue(&self) -> bool {
|
|||
}
|
||||
|
||||
fn poll(&mut self) -> u32 {
|
||||
self.looper_flags |= LOOPER_POLL;
|
||||
self.looper_flags |= LooperFlag::Poll;
|
||||
if self.process_work_list || self.looper_need_return {
|
||||
bindings::POLLIN
|
||||
} else {
|
||||
|
|
@ -477,7 +489,7 @@ pub(crate) fn debug_print(self: &Arc<Self>, m: &SeqFile, print_all: bool) -> Res
|
|||
m,
|
||||
" thread {}: l {:02x} need_return {}\n",
|
||||
self.id,
|
||||
inner.looper_flags,
|
||||
u32::from(inner.looper_flags),
|
||||
inner.looper_need_return,
|
||||
);
|
||||
}
|
||||
|
|
@ -550,9 +562,9 @@ fn get_work_local(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn Deliv
|
|||
return Ok(Some(work));
|
||||
}
|
||||
|
||||
inner.looper_flags |= LOOPER_WAITING;
|
||||
inner.looper_flags |= LooperFlag::Waiting;
|
||||
let signal_pending = self.work_condvar.wait_interruptible_freezable(&mut inner);
|
||||
inner.looper_flags &= !LOOPER_WAITING;
|
||||
inner.looper_flags &= !LooperFlag::Waiting;
|
||||
|
||||
if signal_pending {
|
||||
return Err(EINTR);
|
||||
|
|
@ -604,9 +616,9 @@ fn get_work(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn DeliverToRe
|
|||
return Ok(Some(work));
|
||||
}
|
||||
|
||||
inner.looper_flags |= LOOPER_WAITING | LOOPER_WAITING_PROC;
|
||||
inner.looper_flags |= LooperFlag::Waiting | LooperFlag::WaitingProc;
|
||||
let signal_pending = self.work_condvar.wait_interruptible_freezable(&mut inner);
|
||||
inner.looper_flags &= !(LOOPER_WAITING | LOOPER_WAITING_PROC);
|
||||
inner.looper_flags &= !(LooperFlag::Waiting | LooperFlag::WaitingProc);
|
||||
|
||||
if signal_pending || inner.looper_need_return {
|
||||
// We need to return now. We need to pull the thread off the list of ready threads
|
||||
|
|
@ -1649,7 +1661,7 @@ pub(crate) fn poll(&self) -> Result<(bool, u32)> {
|
|||
/// Make the call to `get_work` or `get_work_local` return immediately, if any.
|
||||
pub(crate) fn exit_looper(&self) {
|
||||
let mut inner = self.inner.lock();
|
||||
let should_notify = inner.looper_flags & LOOPER_WAITING != 0;
|
||||
let should_notify = inner.looper_flags.contains(LooperFlag::Waiting);
|
||||
if should_notify {
|
||||
inner.looper_need_return = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user