Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 494
rust: update Ref to use the kernel's refcount_t.#377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -14,7 +14,7 @@ use kernel::{ | ||
| linked_list::List, | ||
| pages::Pages, | ||
| prelude::*, | ||
| sync::{Guard, Mutex, Ref, RefCount, RefCounted}, | ||
| sync::{Guard, Mutex, Ref}, | ||
| user_ptr::{UserSlicePtr, UserSlicePtrReader}, | ||
| Error, | ||
| }; | ||
| @@ -275,7 +275,6 @@ impl ProcessNodeRefs { | ||
| pub(crate) struct Process { | ||
| ctx: Arc<Context>, | ||
| ref_count: RefCount, | ||
| // TODO: For now this a mutex because we have allocations in BTreeMap and RangeAllocator while | ||
| // holding the lock. We may want to split up the process state at some point to use a spin lock | ||
| @@ -293,22 +292,23 @@ unsafe impl Sync for Process {} | ||
| impl Process { | ||
| fn new(ctx: Arc<Context>) -> Result<Ref<Self>> { | ||
| let mut proc_ref = Ref::try_new(Self { | ||
| ref_count: RefCount::new(), | ||
| ctx, | ||
| // SAFETY: `inner` is initialised in the call to `mutex_init` below. | ||
| inner: unsafe { Mutex::new(ProcessInner::new()) }, | ||
| // SAFETY: `node_refs` is initialised in the call to `mutex_init` below. | ||
| node_refs: unsafe { Mutex::new(ProcessNodeRefs::new()) }, | ||
| })?; | ||
| let process = Ref::get_mut(&mut proc_ref).ok_or(Error::EINVAL)?; | ||
| // SAFETY: `inner` is pinned behind the `Arc` reference. | ||
| let pinned = unsafe { Pin::new_unchecked(&process.inner) }; | ||
| kernel::mutex_init!(pinned, "Process::inner"); | ||
| // SAFETY: `node_refs` is pinned behind the `Arc` reference. | ||
| let pinned = unsafe { Pin::new_unchecked(&process.node_refs) }; | ||
| kernel::mutex_init!(pinned, "Process::node_refs"); | ||
| Ok(proc_ref) | ||
| Ref::try_new_and_init( | ||
| Self { | ||
| ctx, | ||
| // SAFETY: `inner` is initialised in the call to `mutex_init` below. | ||
| inner: unsafe { Mutex::new(ProcessInner::new()) }, | ||
| // SAFETY: `node_refs` is initialised in the call to `mutex_init` below. | ||
| node_refs: unsafe { Mutex::new(ProcessNodeRefs::new()) }, | ||
| }, | ||
| |process| { | ||
| // SAFETY: `inner` is pinned behind the `Ref` reference. | ||
| let pinned = unsafe { Pin::new_unchecked(&process.inner) }; | ||
| kernel::mutex_init!(pinned, "Process::inner"); | ||
| // SAFETY: `node_refs` is pinned behind the `Ref` reference. | ||
| let pinned = unsafe { Pin::new_unchecked(&process.node_refs) }; | ||
| kernel::mutex_init!(pinned, "Process::node_refs"); | ||
| }, | ||
| ) | ||
| } | ||
| /// Attemps to fetch a work item from the process queue. | ||
| @@ -337,7 +337,7 @@ impl Process { | ||
| Either::Right(Registration::new(self, thread, &mut inner)) | ||
| } | ||
| fn get_thread(&self, id: i32) -> Result<Arc<Thread>> { | ||
| fn get_thread(self: &Ref<Self>, id: i32) -> Result<Arc<Thread>> { | ||
| // TODO: Consider using read/write locks here instead. | ||
| { | ||
| let inner = self.inner.lock(); | ||
| @@ -347,7 +347,7 @@ impl Process { | ||
| } | ||
| // Allocate a new `Thread` without holding any locks. | ||
| let ta = Thread::new(id, Ref::new_from(self))?; | ||
| let ta = Thread::new(id, self.clone())?; | ||
| let mut inner = self.inner.lock(); | ||
| @@ -366,7 +366,7 @@ impl Process { | ||
| self.inner.lock().push_work(work) | ||
| } | ||
| fn set_as_manager(&self, info: Option<FlatBinderObject>, thread: &Thread) -> Result { | ||
| fn set_as_manager(self: &Ref<Self>, info: Option<FlatBinderObject>, thread: &Thread) -> Result { | ||
wedsonaf marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| let (ptr, cookie, flags) = if let Some(obj) = info { | ||
| ( | ||
| // SAFETY: The object type for this ioctl is implicitly `BINDER_TYPE_BINDER`, so it | ||
| @@ -390,7 +390,7 @@ impl Process { | ||
| } | ||
| pub(crate) fn get_node( | ||
| &self, | ||
| self: &Ref<Self>, | ||
| ptr: usize, | ||
| cookie: usize, | ||
| flags: u32, | ||
| @@ -406,7 +406,7 @@ impl Process { | ||
| } | ||
| // Allocate the node before reacquiring the lock. | ||
| let node = Arc::try_new(Node::new(ptr, cookie, flags, Ref::new_from(self)))?; | ||
| let node = Arc::try_new(Node::new(ptr, cookie, flags, self.clone()))?; | ||
| let mut inner = self.inner.lock(); | ||
| if let Some(node) = inner.get_existing_node_ref(ptr, cookie, strong, thread)? { | ||
| @@ -693,7 +693,11 @@ impl Process { | ||
| ret | ||
| } | ||
| pub(crate) fn request_death(&self, reader: &mut UserSlicePtrReader, thread: &Thread) -> Result { | ||
| pub(crate) fn request_death( | ||
| self: &Ref<Self>, | ||
| reader: &mut UserSlicePtrReader, | ||
| thread: &Thread, | ||
| ) -> Result { | ||
| let handle: u32 = reader.read()?; | ||
| let cookie: usize = reader.read()?; | ||
| @@ -716,9 +720,8 @@ impl Process { | ||
| } | ||
| // SAFETY: `init` is called below. | ||
| let death = death.commit(unsafe { | ||
| NodeDeath::new(info.node_ref.node.clone(), Ref::new_from(self), cookie) | ||
| }); | ||
| let death = death | ||
| .commit(unsafe { NodeDeath::new(info.node_ref.node.clone(), self.clone(), cookie) }); | ||
| // SAFETY: `death` is pinned behind the `Arc` reference. | ||
| unsafe { Pin::new_unchecked(death.as_ref()) }.init(); | ||
| info.death = Some(death.clone()); | ||
| @@ -766,9 +769,14 @@ impl Process { | ||
| } | ||
| impl IoctlHandler for Process { | ||
| type Target = Self; | ||
| fn write(this: &Self, _file: &File, cmd: u32, reader: &mut UserSlicePtrReader) -> Result<i32> { | ||
| type Target = Ref<Process>; | ||
| fn write( | ||
| this: &Ref<Process>, | ||
| _file: &File, | ||
| cmd: u32, | ||
| reader: &mut UserSlicePtrReader, | ||
| ) -> Result<i32> { | ||
| let thread = this.get_thread(unsafe { rust_helper_current_pid() })?; | ||
| match cmd { | ||
| bindings::BINDER_SET_MAX_THREADS => this.set_max_threads(reader.read()?), | ||
| @@ -782,7 +790,7 @@ impl IoctlHandler for Process { | ||
| Ok(0) | ||
| } | ||
| fn read_write(this: &Self, file: &File, cmd: u32, data: UserSlicePtr) -> Result<i32> { | ||
| fn read_write(this: &Ref<Process>, file: &File, cmd: u32, data: UserSlicePtr) -> Result<i32> { | ||
| let thread = this.get_thread(unsafe { rust_helper_current_pid() })?; | ||
| match cmd { | ||
| bindings::BINDER_WRITE_READ => thread.write_read(data, file.is_blocking())?, | ||
| @@ -795,12 +803,6 @@ impl IoctlHandler for Process { | ||
| } | ||
| } | ||
| unsafe impl RefCounted for Process { | ||
| fn get_count(&self) -> &RefCount { | ||
| &self.ref_count | ||
| } | ||
| } | ||
| impl FileOpener<Arc<Context>> for Process { | ||
| fn open(ctx: &Arc<Context>) -> Result<Self::Wrapper> { | ||
| let process = Self::new(ctx.clone())?; | ||
| @@ -893,15 +895,15 @@ impl FileOperations for Process { | ||
| } | ||
| } | ||
| fn ioctl(this: &Process, file: &File, cmd: &mut IoctlCommand) -> Result<i32> { | ||
| fn ioctl(this: &Ref<Process>, file: &File, cmd: &mut IoctlCommand) -> Result<i32> { | ||
| cmd.dispatch::<Self>(this, file) | ||
| } | ||
| fn compat_ioctl(this: &Process, file: &File, cmd: &mut IoctlCommand) -> Result<i32> { | ||
| fn compat_ioctl(this: &Ref<Process>, file: &File, cmd: &mut IoctlCommand) -> Result<i32> { | ||
| cmd.dispatch::<Self>(this, file) | ||
| } | ||
| fn mmap(this: &Process, _file: &File, vma: &mut bindings::vm_area_struct) -> Result { | ||
| fn mmap(this: &Ref<Process>, _file: &File, vma: &mut bindings::vm_area_struct) -> Result { | ||
| // TODO: Only group leader is allowed to create mappings. | ||
| if vma.vm_start == 0 { | ||
| @@ -919,7 +921,7 @@ impl FileOperations for Process { | ||
| this.create_mapping(vma) | ||
| } | ||
| fn poll(this: &Process, file: &File, table: &PollTable) -> Result<u32> { | ||
| fn poll(this: &Ref<Process>, file: &File, table: &PollTable) -> Result<u32> { | ||
| let thread = this.get_thread(unsafe { rust_helper_current_pid() })?; | ||
| let (from_proc, mut mask) = thread.poll(file, table); | ||
| if mask == 0 && from_proc && !this.inner.lock().work.is_empty() { | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -21,6 +21,7 @@ | ||
| const_panic, | ||
| const_raw_ptr_deref, | ||
| const_unreachable_unchecked, | ||
| receiver_trait, | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feature is not meant to eventually be stabilized. It doesn't have a tracking issue and Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that we are going to have a in-tree copy of Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To add some more context to what Gary already said: we had a technical meeting on the A replacement for | ||
| try_reserve | ||
| )] | ||
| #![deny(clippy::complexity)] | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the support for an initialization closure only there to support easy initialization of
Pinned structures? Or do you believe it's more generally useful? Just asking out of general interest.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See wedsonaf@61397b0 -- this allows us to obviate
get_mut, which allows us to safely claim thatRefis in fact pinned.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see ! Yes, getting rid of
get_mut()looks very good. Not sure why you'd need amutclosure for initialization, though?Arcalso provides shared references only, but we are still able to initialize theMutexes inside of it?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See wedsonaf@e201bf1 -- allowing
initon just&self(as opposed to&mut self) was an oversight that leads to unsafety (e.g., someone callinginiton a synchronisation primitive that is in use).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Holy smoke! I was already wondering about that, but I'm coming from profound ignorance on
Pinning and everything around it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The best way to avoid
get_mutis through a wrapper type likeUniqueArchttps://doc.servo.org/servo_arc/struct.UniqueArc.htmlThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PS do we have an Issue to keep track of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I like it.
Something for another PR though. (The reason I'm removing
get_mutin this PR is that we don't have arefcount_tfunction with the right barriers forget_mutand I want this code to be simple wrappers aroundrefcount_t).I don't think so. Feel free to open one.