-
-
Notifications
You must be signed in to change notification settings - Fork 61
Resource Magement #127
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
base: master
Are you sure you want to change the base?
Resource Magement #127
Conversation
To do this, we implement an API where every resource can be opened, read from, written to, and closed using the same syscalls. Through this design, the kernel is kept small, whilst also letting new resources be added in the future with minimal change to both kernel and user code. | ||
|
||
## Resource Abstractation | ||
First, we can begin by defining a list of resource types: |
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.
One of the main reason I started with the notes, is because I'm not a big fan of tutorials that starts paragraphs with just a bunch of code, without specifying why, how, it's purpose. Etc.
For example, even if it could be trivial, we declared two structures.
But why?
What is the enum for?
What is the purpose of them.
I know in some part we are doing the same, but the key of those notes is trying to explain all the information missing. And also I haven't found a good resource so far that explains resource management and device drivers design, so let's try to have it as easy to understand and complete as possible.
resource_t* resource_table[MAX_RESOURCES]; | ||
} process_t; | ||
``` | ||
Now each process has a resource table that is a map of integers, called handles, to the kernel resource objects. A handle is simply an identifier returned by the kernel when opening a resource that is later used by the user to inform what resource the operation should be performed upon. This way, the resource structure is not exposed to userspace. Because of this, the same handle number in different processes can refer to different resources. For example, in Unix, handles `0`, `1`, and `2` refer to stdio for each process. |
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.
i think that handles should be Italic (since is a name of a concept)
|
||
With this, we can also define a supporting function allowing the kernel to fetch a resource by handle: | ||
``` | ||
resource_t* get_resource(process_t* proc, int handle) { |
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 another thing, let's try to not provide too much ready to write code, and where possible some pseudocode, and otherwise just explain what should be the purpose of the function.
Anyway this was my approach in the notes most of the time.
Something like I did for the memory management section.
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.
I'm writing those comment as long as I read this PR, so maybe they don't apply everywhere, takte them more as guidelines. Anyway this function I think is Ok.
## Generic API | ||
The generic interface for a resource consists of four primary functions: `open`, `read`, `write`, and `close`. These functions form the minimum required API that every resource type must support. To begin the implementation of this, our `resource_t` needs extending to support these operations: | ||
``` | ||
typedef struct resource { |
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.
since we are expanding the original structure, i noticed in the book we keep the previous fields (especially when they are not big) so maybe let's keep consistent with it?
``` | ||
Operations are defined to be blocking by default, meaning that if a resource is not ready (for example, no data to read), the process is suspended until the operation can complete. Each resource type can override these generic operations to provide behavior specific to that resource. For example, a file resource can replace the write function with one that writes data to disk, while an IPC message resource could implement write to enqueue a message, allowing the same API call to behave differently depending on the resource. | ||
|
||
It has been left as an exercise to the user to decide on how they want to handle extending this design for extra resource-specific functionality (ie, renaming a file). There are two (of many) ways to do this, each with its own trade-off. Firstly, a simpler design would be to just add more syscalls to handle this; however, this means the ABI grows as your kernel manages more resources. Another approach would be to pass an additional `size_t flags` parameter and let the resource-specific operation handle it, which would keep the original four operations but with added complexity. |
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.
maybe reader instead of user? :D
|
||
It has been left as an exercise to the user to decide on how they want to handle extending this design for extra resource-specific functionality (ie, renaming a file). There are two (of many) ways to do this, each with its own trade-off. Firstly, a simpler design would be to just add more syscalls to handle this; however, this means the ABI grows as your kernel manages more resources. Another approach would be to pass an additional `size_t flags` parameter and let the resource-specific operation handle it, which would keep the original four operations but with added complexity. | ||
|
||
The dispatch code would be as follows: |
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.
Too much code, and too little expalanation! And too ready to copy and paste :)
Here's the base write-up. Once settled on the design, I will go through and mix this in with the files and IPC.
Can discuss here or on the Discord, whatever is easier.