Opened 16 years ago
Last modified 10 years ago
#3533 new enhancement
Messaging Service: Improve Kernel<->Userland Communication
Reported by: | bonefish | Owned by: | bonefish |
---|---|---|---|
Priority: | normal | Milestone: | R1 |
Component: | System/Kernel | Version: | R1/pre-alpha1 |
Keywords: | Cc: | rgollent@… | |
Blocked By: | Blocking: | ||
Platform: | All |
Description
Improvements:
- Make the shared areas read-only for the userland side.
- Make locking the area contents superfluous.
Implementation hints:
- Move the command management out of the areas themselves. Both kernel and userland need to do that in their own structures.
- Use a separate shared area containing an atomic counter (total command count) read-/writable by both sides. Whenever one side detects the other side has changed the counter, the local area structures need to be adjusted.
Change History (4)
follow-up: 2 comment:1 by , 16 years ago
Cc: | added |
---|
comment:2 by , 16 years ago
Replying to anevilyak:
To make sure I understand this correctly, a single counter that spans all areas would be used?
Yep.
If so, it seems somewhat non-obvious as to how to correctly track what number of commands are in each area since they're variable size. Ergo if two new commands come in, one fits in the current area, but the other requires allocating an additional one, how does the other side, which might not get scheduled until both commands have been added, know that the 2 added commands are split up this way?
Just to avoid misunderstandings, I haven't really planned all the details; this is more a rough idea and might need adjustments. One definitely needs an indicator where the list of commands in an area ends. I assumed the next_command
link would be sufficient, but there's probably a race condition when the last command is read, whether the kernel side considers the area full and starts a continues to write into the current one. So I guess one needs an explicit list termination structure, i.e. a command header indicating the end of the list. When the registrar notices that the global command counter has been increased, it would read at max that many new commands from the last area or until hitting the terminator. In the latter case further commands apparently have been written to a new area, so it would continue there with the remaining command count.
So the algorithms would look like this.
Writing a command in the kernel:
if (command counter has changed) { consider the space for the read commands free; drop any empty area save the last one; } if (not enough space in the last area) create and append new last area; overwrite the area's command list terminator with the new command; write a new list terminator; increment the global command counter; if (command counter was 0) release command semaphore; if (command counter has changed) { consider the space for the read commands free; drop any empty area save the last one; }
Reading commands in the registrar:
while (true) { read global command count; if (command count == 0) { wait for command count semaphore; continue; } while (command count > 0) { check command list terminator of the last known area; if (!next command) { clone and append new area; delete previous area; continue; } process command; decrement global command counter; update cached command count; } }
comment:3 by , 10 years ago
Milestone: | R1 → Unscheduled |
---|
To make sure I understand this correctly, a single counter that spans all areas would be used? If so, it seems somewhat non-obvious as to how to correctly track what number of commands are in each area since they're variable size. Ergo if two new commands come in, one fits in the current area, but the other requires allocating an additional one, how does the other side, which might not get scheduled until both commands have been added, know that the 2 added commands are split up this way?