-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
Comments for "https://os.phil-opp.com/async-await/" #768
Comments
The thing I was trying to wrap my head around for quite some time, thanks for so detailed explanation! Two minor points:
if !self.waker_cache.contains_key(&task_id) {
self.waker_cache.insert(task_id, self.create_waker(task_id));
}
let waker = self.waker_cache.get(&task_id).expect("should exist"); - why not use the Entry API instead? |
The statemachine in https://os.phil-opp.com/async-await/#the-async-await-pattern fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
loop {
match self { // TODO: handle pinning
ExampleStateMachine::Start(state) => {…}
ExampleStateMachine::WaitingOnFooTxt(state) => {…}
ExampleStateMachine::WaitingOnFooTxt(state) => {…}
ExampleStateMachine::End(state) => {…}
}
}
} Contains the state edit: Fix in #769 |
Excellent! Looking forward to the next article |
@Cerberuser Great to hear that the post is useful to you!
Good question! I tried using it, but it leads to borrowing errors here because we need to borrow
Thanks for reporting! Fixed in f32ee7f. |
@jounathaen Thanks for reporting and providing the fix! |
@senseiod I already started working on it :). |
I'm surprised that on x86 you need to re-enable interrupts before doing a hlt. On cortex m you can do: So the CPU will wake from wfi even with the interrupts disabled. Ofcourse the interrupt handler will only be executed when the interrupts are re-enabled. |
@p2mate Yeah, I think the approach of ARM is definitely better. As far as I know, there is no equivalent to the |
thank you , it's very detailed/clear and very useful. |
Thank you very much for the detailed lesson, and I look forward to continuing. |
There is a repetition typo: "have to have to" in the first paragraph of Thanks for a fascinating article. |
Isn't the uniqueness of TaskId not be guaranteed for zero-sized futures? Box would give the same address for multiple "instances" of the zero sized type. Edit: See this playground link for an example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=72f510e1edcb7657ce46becab9179977 |
Great article! Thank you so much :) |
Thank you all for the nice feedback :).
Thanks for reporting! Fixed in b6d09c8. |
Very good catch! While zero-sized futures are rare in practice, we should still ensure that they can be used without problems. I opened #782 and #783 to create task IDs using a static counter instead. |
https://doc.rust-lang.org/std/future/trait.Future.html doesn't seem to suggest that when you are returning ready that you must use the waker to say you are ready. I have found future impl's (like https://docs.rs/futures-util/0.3.4/src/futures_util/future/future/map.rs.html#42) that pass the cx down to a lower future, but don't actually call wake themselves. Are they assuming a lower future will call wake? Should an executor have a timeout after which if it hasn't gotten a .wake() from a task, it polls the future anyways? |
I'm not sure if I understand your question. You don't need to do anything with the waker if you're returning
Yes, exactly. Only the futures at the lowest level need to handle the
This might be a good idea for robustness, but normally you should be able to rely on the waker notification. |
Thanks for the great post. In "The Problem with Self-Referential Structs"
should this address be edit: array in diagram starts at |
Isn’t going from cooperative multitasking to preemptive multitasking as simple and straightforward here as locking each |
^ Oops, I meant adding a |
@realKennyStrawn93 I'm not quite sure what you mean with adding a |
Why do we use an Arc, instead of an Rc wrapper? Everything runs on the same thread so how do atomic operations help us? It might have something to do with the asynchronicity of interrupts but I am not sure how this is relevant. Then again, I have gotten quite rusty, no pun intended, with low level asynchronous programming. edit: I now realize that Arc is probably used because of how Wake uses it in the blanket implementation. |
@Mandragorian The Apart from the type system requirements, using a waker type that isn't |
The code block under "The |
If I understand correctly, you push the task ID to |
@SnowyCoder Great to hear that you like the blog!
It's been a while since I wrote that code, so I don't remember my exact reasons for using a separate waker cache anymore. I know that I changed the executor design a few times while writing this post, so maybe the reasons for keeping it separate don't exist anymore with the current design.
Yes, this should be possible. The It's also worth mentioning that there is ongoing work on adding support for heap allocations in constants in Rust itself, which might at some point allow to mark the |
It's also worth mentioning that there is ongoing work on adding support for heap allocations in constants in Rust itself, which might at some point allow to mark the ArrayQueue::new function as const without removing the allocation. Then we could directly initialize a static at compile time and the Rust compiler would automatically transform the allocation to a static memory region.
Did you mean that compiler will optimize the allocation away and we won't need a dynamic allocator for this?
|
@RMuskovets This is only about Normal |
Oh, that's really cool! But will it work in environment like fn function() {
const foo: &String = &String::from("test");
} |
It doesn't matter where you define a Lazy static evaluates expressions lazily at runtime, so it would still perform a normal dynamic allocation at runtime. |
Hey, super duper amazing series. You'r AWESOME. Can't wait for more. :) Btw, in: [dependencies.crossbeam-queue]
version = "0.2.1" it does not work if you pump it up to the newest "0.3.0" version as I first did. Just a warning if someone wastes any time on it like me. |
@Gabriel-Alves-Cunha That's because Crossbeam changed its |
I'm still confused on how to make asynchronous tasks. from what I've
read I just do:
```rust
async fn func_name(args...) -> ret_value {
// code...
}
```
But my executor still runs each task in sequence. I'm not very good at
async programming, so I don't know how to explicitly indiate to the
executor that I'm busy doing something and it can switch to another
one and things like that. (I need to work on my ATA Routines... Ugh.)
…On 12/3/20, jedel1043 ***@***.***> wrote:
@Gabriel-Alves-Cunha That's because Crossbeam changed its ```pop()``` api
from ```Ok(val)``` to ```Some(val)```. Just change that and it should work
on ver. 0.3.x
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
#768 (comment)
--
Signed,
Ethin D. Probst
|
Thanks a lot, I'm glad that you like it :). Tasks are only paused at |
I would just like to point out that |
@brightly-salty Thanks for reporting! Yes I'm aware of that and I try to update it when I have time. |
@phil-opp I know. But how do I explicitly get a task to return
Poll::Pending? I'd love to be able to do that on demand, for example
if I'm waiting for an NVM format to finish.
…On 12/28/20, Philipp Oppermann ***@***.***> wrote:
@brightly-salty Thanks for reporting! Yes I'm aware of that and I try to
update it when I have time.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#768 (comment)
--
Signed,
Ethin D. Probst
|
You will need to implement |
Excellent! |
Hi and congratulations for the post! Hi found a little error in the paragraph 'The Problem with Self-Referential Structs'. |
Good catch, thanks! Fixed in cd8e139. |
Try to make disk support next mbr or gpt and finally: exfat, fat32 fat16 and fat12 file systems support. This can be very good!!! |
@TANDEXX We might cover disk access and file systems at some point, but there are some other topics that I plan to cover before that (threads, processes, userspace, etc). |
maybe in the future you could do guis?? 🤔 |
I'm currently working on a new edition of the blog, which will use a pixel-based framebuffer for display output. This makes it possible to set individual pixels and also create some GUI if you like. For the blog, I plan to only cover a simple shell and some games at the beginning, but as soon as we have support for userspace processes, a GUI might make sense. (This won't happen in the near future though.) |
I have problem while compiling system. this throws linking with cc failed with many arguments and next output is: |
You need to compile the project for a bare-metal target, e.g. by passing a |
To be fair about the disk access, disk access is a fairly complicated
topic and requires (a lot) of code. As someone who's working on an
NVMe driver, my implementation already spans at least nearly 3k LoC,
and I haven't even started reading and writing the media yet -- I'm
just implementing the admin command set right now. The PCIe code is
another 400-500 lines, though that just might be the way I did it. But
either way, it would undoubtedly take at least 10-15 blog posts to
cover raw disk IO alone -- and we haven't even gotten on file systems.
So I definitely understand why there's no rush there, and I'd even go
as far as to say to leave it out and let the reader figure it out;
we're not trying to write a book about OS development, after all, just
a path that newcomers can travel to get going. Right?
…On 2/23/21, Philipp Oppermann ***@***.***> wrote:
You need to compile the project for a bare-metal target, e.g. by passing a
`--target` argument.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#768 (comment)
--
Signed,
Ethin D. Probst
|
When I run the kerenl, I get the warning: Here is my github repo: /~https://github.com/nanoproductions/dwn-os Thanks! |
Okay, so I'm trying to make it possible to spawn tasks when the executor is not owned by any function. As it is right now, I have it like this: let mut executor = Executor::new();
executor.spawn(AsyncTask::new(gdt::init()));
executor.spawn(AsyncTask::new(interrupts::init_stage2()));
executor.spawn(AsyncTask::new(pci::init()));
executor.spawn(AsyncTask::new(rtc::init()));
executor.run(); However, not only does |
Wow, thanks |
so I rewrited this to basic shell and here is download link: https://drive.google.com/file/d/1uDwCqCpfBzrz93v9AGXWjQ2xp2aVAitF/view?usp=sharing. messages displayed before modification are not deleted and this isn't finished because my linux on pendrive was broken and finally I wanted to make my own system (file system also was broken and I writed my own system in virtual machine because I just can't write |
I didn't understand why we need handle multiple tasks in executor. Is it possible to combine all futures in one, for example using join_all? I think one task executer is way simpler, with same result. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
This is a general purpose comment thread for the Async/Await post.
The text was updated successfully, but these errors were encountered: