Skip to content

Commit 87e3dee

Browse files
authored
Merge pull request #191 from wedsonaf/list
Move list implementation to `kernel` crate.
2 parents a52b8d4 + 858c5bd commit 87e3dee

File tree

9 files changed

+232
-79
lines changed

9 files changed

+232
-79
lines changed

drivers/android/node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ use core::{
66
sync::atomic::{AtomicU64, Ordering},
77
};
88
use kernel::{
9+
linked_list::{GetLinks, Links, List},
910
prelude::*,
1011
sync::{Guard, LockedBy, Mutex, Ref, SpinLock},
1112
user_ptr::UserSlicePtrWriter,
1213
};
1314

1415
use crate::{
1516
defs::*,
16-
linked_list::{GetLinks, Links, List},
1717
process::{Process, ProcessInner},
1818
thread::{BinderError, BinderResult, Thread},
1919
DeliverToRead,

drivers/android/process.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use core::{
99
use kernel::{
1010
bindings, c_types,
1111
file_operations::{File, FileOpener, FileOperations, IoctlCommand, IoctlHandler, PollTable},
12+
linked_list::List,
1213
pages::Pages,
1314
prelude::*,
1415
sync::{Guard, Mutex, Ref, RefCount, RefCounted},
@@ -20,11 +21,10 @@ use crate::{
2021
allocation::Allocation,
2122
context::Context,
2223
defs::*,
23-
linked_list::List,
2424
node::{Node, NodeDeath, NodeRef},
2525
range_alloc::RangeAllocator,
2626
thread::{BinderError, BinderResult, Thread},
27-
DeliverToRead, Either,
27+
DeliverToRead, DeliverToReadListAdapter, Either,
2828
};
2929

3030
// TODO: Review this:
@@ -62,7 +62,7 @@ pub(crate) struct ProcessInner {
6262
is_dead: bool,
6363
threads: BTreeMap<i32, Arc<Thread>>,
6464
ready_threads: List<Arc<Thread>>,
65-
work: List<Arc<dyn DeliverToRead>>,
65+
work: List<DeliverToReadListAdapter>,
6666
mapping: Option<Mapping>,
6767
nodes: BTreeMap<usize, Arc<Node>>,
6868

drivers/android/range_alloc.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
use alloc::boxed::Box;
44
use core::ptr::NonNull;
5-
use kernel::{prelude::*, Error};
6-
7-
use crate::linked_list::{CursorMut, GetLinks, Links, List};
5+
use kernel::{
6+
linked_list::{CursorMut, GetLinks, Links, List},
7+
prelude::*,
8+
Error,
9+
};
810

911
pub(crate) struct RangeAllocator<T> {
1012
list: List<Box<Descriptor<T>>>,

drivers/android/rust_binder.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,20 @@
99

1010
use alloc::{boxed::Box, sync::Arc};
1111
use core::pin::Pin;
12-
use kernel::{cstr, miscdev::Registration, prelude::*, user_ptr::UserSlicePtrWriter};
12+
use kernel::{
13+
cstr,
14+
linked_list::{GetLinks, GetLinksWrapped, Links},
15+
miscdev::Registration,
16+
prelude::*,
17+
user_ptr::UserSlicePtrWriter,
18+
};
1319

1420
mod allocation;
1521
mod context;
1622
mod defs;
17-
mod linked_list;
1823
mod node;
1924
mod process;
2025
mod range_alloc;
21-
mod raw_list;
2226
mod thread;
2327
mod transaction;
2428

@@ -53,26 +57,33 @@ trait DeliverToRead {
5357
fn cancel(self: Arc<Self>) {}
5458

5559
/// Returns the linked list links for the work item.
56-
fn get_links(&self) -> &linked_list::Links<dyn DeliverToRead>;
60+
fn get_links(&self) -> &Links<dyn DeliverToRead>;
5761
}
5862

59-
impl linked_list::GetLinks for Arc<dyn DeliverToRead> {
63+
struct DeliverToReadListAdapter {}
64+
65+
impl GetLinks for DeliverToReadListAdapter {
6066
type EntryType = dyn DeliverToRead;
61-
fn get_links(obj: &dyn DeliverToRead) -> &linked_list::Links<dyn DeliverToRead> {
62-
obj.get_links()
67+
68+
fn get_links(data: &Self::EntryType) -> &Links<Self::EntryType> {
69+
data.get_links()
6370
}
6471
}
6572

73+
impl GetLinksWrapped for DeliverToReadListAdapter {
74+
type Wrapped = Arc<dyn DeliverToRead>;
75+
}
76+
6677
struct DeliverCode {
6778
code: u32,
68-
links: linked_list::Links<dyn DeliverToRead>,
79+
links: Links<dyn DeliverToRead>,
6980
}
7081

7182
impl DeliverCode {
7283
fn new(code: u32) -> Self {
7384
Self {
7485
code,
75-
links: linked_list::Links::new(),
86+
links: Links::new(),
7687
}
7788
}
7889
}
@@ -87,7 +98,7 @@ impl DeliverToRead for DeliverCode {
8798
Ok(true)
8899
}
89100

90-
fn get_links(&self) -> &linked_list::Links<dyn DeliverToRead> {
101+
fn get_links(&self) -> &Links<dyn DeliverToRead> {
91102
&self.links
92103
}
93104
}

drivers/android/thread.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use core::{alloc::AllocError, mem::size_of, pin::Pin};
55
use kernel::{
66
bindings,
77
file_operations::{File, PollTable},
8+
linked_list::{GetLinks, Links, List},
89
prelude::*,
910
sync::{CondVar, Ref, SpinLock},
1011
user_ptr::{UserSlicePtr, UserSlicePtrWriter},
@@ -14,11 +15,10 @@ use kernel::{
1415
use crate::{
1516
allocation::{Allocation, AllocationView},
1617
defs::*,
17-
linked_list::{GetLinks, Links, List},
1818
process::{AllocationInfo, Process},
1919
ptr_align,
2020
transaction::Transaction,
21-
DeliverCode, DeliverToRead, Either,
21+
DeliverCode, DeliverToRead, DeliverToReadListAdapter, Either,
2222
};
2323

2424
pub(crate) type BinderResult<T = ()> = Result<T, BinderError>;
@@ -81,7 +81,7 @@ struct InnerThread {
8181
/// Determines whether the work list below should be processed. When set to false, `work_list`
8282
/// is treated as if it were empty.
8383
process_work_list: bool,
84-
work_list: List<Arc<dyn DeliverToRead>>,
84+
work_list: List<DeliverToReadListAdapter>,
8585
current_transaction: Option<Arc<Transaction>>,
8686
}
8787

drivers/android/transaction.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
use alloc::sync::Arc;
44
use core::sync::atomic::{AtomicBool, Ordering};
5-
use kernel::{bindings, prelude::*, sync::Ref, user_ptr::UserSlicePtrWriter};
5+
use kernel::{bindings, linked_list::Links, prelude::*, sync::Ref, user_ptr::UserSlicePtrWriter};
66

77
use crate::{
88
defs::*,
9-
linked_list::Links,
109
node::NodeRef,
1110
process::Process,
1211
ptr_align,

rust/kernel/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ pub mod file_operations;
4343
pub mod miscdev;
4444
pub mod pages;
4545

46+
pub mod linked_list;
47+
mod raw_list;
48+
4649
#[doc(hidden)]
4750
pub mod module_param;
4851

drivers/android/linked_list.rs renamed to rust/kernel/linked_list.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3+
//! Linked lists.
4+
//!
5+
//! TODO: This module is a work in progress.
6+
37
use alloc::{boxed::Box, sync::Arc};
48
use core::ptr::NonNull;
59

610
pub use crate::raw_list::{Cursor, GetLinks, Links};
711
use crate::{raw_list, raw_list::RawList};
812

913
// TODO: Use the one from `kernel::file_operations::PointerWrapper` instead.
14+
/// Wraps an object to be inserted in a linked list.
1015
pub trait Wrapper<T: ?Sized> {
16+
/// Converts the wrapped object into a pointer that represents it.
1117
fn into_pointer(self) -> NonNull<T>;
18+
19+
/// Converts the object back from the pointer representation.
20+
///
21+
/// # Safety
22+
///
23+
/// The passed pointer must come from a previous call to [`Wrapper::into_pointer()`].
1224
unsafe fn from_pointer(ptr: NonNull<T>) -> Self;
25+
26+
/// Returns a reference to the wrapped object.
1327
fn as_ref(&self) -> &T;
1428
}
1529

@@ -55,7 +69,9 @@ impl<T: ?Sized> Wrapper<T> for &T {
5569
}
5670
}
5771

72+
/// A descriptor of wrapped list elements.
5873
pub trait GetLinksWrapped: GetLinks {
74+
/// Specifies which wrapper (e.g., `Box` and `Arc`) wraps the list entries.
5975
type Wrapped: Wrapper<Self::EntryType>;
6076
}
6177

@@ -87,29 +103,50 @@ impl<T: GetLinks + ?Sized> GetLinks for Arc<T> {
87103
}
88104
}
89105

106+
/// A linked list.
107+
///
108+
/// Elements in the list are wrapped and ownership is transferred to the list while the element is
109+
/// in the list.
90110
pub struct List<G: GetLinksWrapped> {
91111
list: RawList<G>,
92112
}
93113

94114
impl<G: GetLinksWrapped> List<G> {
115+
/// Constructs a new empty linked list.
95116
pub fn new() -> Self {
96117
Self {
97118
list: RawList::new(),
98119
}
99120
}
100121

122+
/// Returns whether the list is empty.
101123
pub fn is_empty(&self) -> bool {
102124
self.list.is_empty()
103125
}
104126

127+
/// Adds the given object to the end (back) of the list.
128+
///
129+
/// It is dropped if it's already on this (or another) list; this can happen for
130+
/// reference-counted objects, so dropping means decrementing the reference count.
105131
pub fn push_back(&mut self, data: G::Wrapped) {
106132
let ptr = data.into_pointer();
133+
134+
// SAFETY: We took ownership of the entry, so it is safe to insert it.
107135
if !unsafe { self.list.push_back(ptr.as_ref()) } {
108136
// If insertion failed, rebuild object so that it can be freed.
137+
// SAFETY: We just called `into_pointer` above.
109138
unsafe { G::Wrapped::from_pointer(ptr) };
110139
}
111140
}
112141

142+
/// Inserts the given object after `existing`.
143+
///
144+
/// It is dropped if it's already on this (or another) list; this can happen for
145+
/// reference-counted objects, so dropping means decrementing the reference count.
146+
///
147+
/// # Safety
148+
///
149+
/// Callers must ensure that `existing` points to a valid entry that is on the list.
113150
pub unsafe fn insert_after(&mut self, existing: NonNull<G::EntryType>, data: G::Wrapped) {
114151
let ptr = data.into_pointer();
115152
let entry = &*existing.as_ptr();
@@ -119,6 +156,12 @@ impl<G: GetLinksWrapped> List<G> {
119156
}
120157
}
121158

159+
/// Removes the given entry.
160+
///
161+
/// # Safety
162+
///
163+
/// Callers must ensure that `data` is either on this list or in no list. It being on another
164+
/// list leads to memory unsafety.
122165
pub unsafe fn remove(&mut self, data: &G::Wrapped) -> Option<G::Wrapped> {
123166
let entry_ref = Wrapper::as_ref(data);
124167
if self.list.remove(entry_ref) {
@@ -128,26 +171,39 @@ impl<G: GetLinksWrapped> List<G> {
128171
}
129172
}
130173

174+
/// Removes the element currently at the front of the list and returns it.
175+
///
176+
/// Returns `None` if the list is empty.
131177
pub fn pop_front(&mut self) -> Option<G::Wrapped> {
132178
let front = self.list.pop_front()?;
179+
// SAFETY: Elements on the list were inserted after a call to `into_pointer `.
133180
Some(unsafe { G::Wrapped::from_pointer(front) })
134181
}
135182

183+
/// Returns a cursor starting on the first (front) element of the list.
136184
pub fn cursor_front(&self) -> Cursor<'_, G> {
137185
self.list.cursor_front()
138186
}
139187

188+
/// Returns a mutable cursor starting on the first (front) element of the list.
140189
pub fn cursor_front_mut(&mut self) -> CursorMut<'_, G> {
141190
CursorMut::new(self.list.cursor_front_mut())
142191
}
143192
}
144193

194+
impl<G: GetLinksWrapped> Default for List<G> {
195+
fn default() -> Self {
196+
Self::new()
197+
}
198+
}
199+
145200
impl<G: GetLinksWrapped> Drop for List<G> {
146201
fn drop(&mut self) {
147202
while self.pop_front().is_some() {}
148203
}
149204
}
150205

206+
/// A list cursor that allows traversing a linked list and inspecting & mutating elements.
151207
pub struct CursorMut<'a, G: GetLinksWrapped> {
152208
cursor: raw_list::CursorMut<'a, G>,
153209
}
@@ -157,23 +213,32 @@ impl<'a, G: GetLinksWrapped> CursorMut<'a, G> {
157213
Self { cursor }
158214
}
159215

216+
/// Returns the element the cursor is currently positioned on.
160217
pub fn current(&mut self) -> Option<&mut G::EntryType> {
161218
self.cursor.current()
162219
}
163220

221+
/// Removes the element the cursor is currently positioned on.
222+
///
223+
/// After removal, it advances the cursor to the next element.
164224
pub fn remove_current(&mut self) -> Option<G::Wrapped> {
165225
let ptr = self.cursor.remove_current()?;
226+
227+
// SAFETY: Elements on the list were inserted after a call to `into_pointer `.
166228
Some(unsafe { G::Wrapped::from_pointer(ptr) })
167229
}
168230

231+
/// Returns the element immediately after the one the cursor is positioned on.
169232
pub fn peek_next(&mut self) -> Option<&mut G::EntryType> {
170233
self.cursor.peek_next()
171234
}
172235

236+
/// Returns the element immediately before the one the cursor is positioned on.
173237
pub fn peek_prev(&mut self) -> Option<&mut G::EntryType> {
174238
self.cursor.peek_prev()
175239
}
176240

241+
/// Moves the cursor to the next element.
177242
pub fn move_next(&mut self) {
178243
self.cursor.move_next();
179244
}

0 commit comments

Comments
 (0)