Page 1 of 1
Do you really need RPC? (and Interrupts)
Posted: Wed Feb 16, 2011 7:03 pm
by cxzuk
Hello all,
This is the first kernel ive written, and id like to get some information from experienced coders here
.
Its actually two questions; Firstly, I want to group Interrupts into groups. Secondly, I want to get rid of Remote Procedure Calls (RPC), or atleast understand -why- you would need them.
From my understanding, there is only two real separate concepts (The Von Neumann Architecture?), and thats memory and processing.
Because hardware can not block, and so inform a request call that its finished, it uses interrupts, is that right?
So surely an Interrupt's role is either to inform you that a function has completed (processing), or data that was requested is ready or streaming (memory).
e.g.
Keyboard Interrupt - I have data ready for you.
Clock Interrupt - You asked me to wait x seconds, I've finished waiting. - Even with scheduling it can be seen like this. (Wait x seconds, but while i wait run this process).
However, as i have not written drivers before, Im not sure if all hardware can be grouped like this.
If it can be then I can build special buffers in the kernel to handle hardware "memory" interrupts, and when the driver is ready to read more data, just reads from the buffers.
As for "processing" interrupts, Sync and Async would be specific to hardware the driver is for, The interrupt would basically just be forwarded to the app. Either the app is in a wait state (sync) for this interrupt or it'll a stub function thats called (async).
As for question two, I am writing my kernel and operating system in a client-server way and specifically MVC. Basically, The idea is that data is shared and synchronised between processes only. All function's are run locally to the process (client). There is no such thing as asking another process to execute a function. Can anyone give me examples where you -may- require RPC or need to execute a function in another process?
This last bit is pretty important as one of my main goals is for apps to not be aware of any other processes running.
Thanx for your time!
Mike Brown
Re: Do you really need RPC? (and Interrupts)
Posted: Thu Feb 17, 2011 1:37 am
by Combuster
In any client-server configuration, if the client asks the server a question, the server will respond to that and will in the process execute some code to generate that response. The more interesting question would be what you consider an instance of RPC. Does it include peering, server-client communication, and (behold, same fundamental idea) interrupts?
On another note: you can often replace interrupts with polling systems, but it's slow.
Re: Do you really need RPC? (and Interrupts)
Posted: Thu Feb 17, 2011 4:23 am
by cxzuk
Heya.
I see RPC as a message to change a processes control flow, e.g to execute a function.
An interrupt is a prime example.
Consider a CD-ROM driver. With the eject() function. A process may have to send a RPC call to execute the CD-ROM eject function (as its driver specific)?
I would tho have a shared memory location, and would change a byte to the state that i want the CD-ROM drive in...
e.g.
Driver =
var CDROM = {
tray = 'closed',
// these functions would most likely not be subroutines but part of the watch function.
open = function() { tray = 'opening'; somefunction; tray = 'opened'},
close = function() { tray = 'closing'; somefunction; tray = 'closed' }
};
watch(CDROMDRAW, function(prop, old, new) {
if ((old == "closed") && (new == "opened")) {
CDROM.open(); <- This can block, or be non-blocking with a callback
} elseif ((old == "opened") && (new == "closed")) {
CDROM.close();
}
});
main() { // IPC loop listening for reads and writes on my shared memory 'cdrom.tray'
IPC.share(CDROM.tray, permissions);
}
And a client would be..
tray_status = IPC.read("/kernel/driver/cdrom/tray", permissions);
if (tray_status == "closed") {
IPC.write("/kernel/driver/cdrom/tray", "opened" , permissions);
} else {
alert ("tray already open.");
}
Whats the difference? - well, watch() is taken away from the IPC, it does not affect the servers code flow. The server deals with it when it in its own time. An interrupt does break the servers flow. The IPC call does not directly change the 'tray' value, and infact the example above is just a Compare And Swap operation, where the merge (or swap) function is not changing memory by is talking to the hardware and opening the CD-ROM tray.
---
Can you tell me more about polling for interrupts? Do you basically have a structure that alters when an interrupt fires? Then poll this structure?
while i understand it may be slow, server->client stuff is not very scalable. And if the interrupt polling is as above, then the interrupt would be an optimisation of that design, and i can make a compiler option to optimise out the poll in favour for the "push", which will keep the coding design principles im after?
Mike
Re: Do you really need RPC? (and Interrupts)
Posted: Thu Feb 17, 2011 11:46 am
by Jezze
An interrupt is what it says on the tin. It just stops whatever is running, executes your interruphandler and when done restores the state before the interrupt occured. Polling would be to disable the interupt for a particular device and instead loop over a port or memory address until some value change which is a waste of processing power.
An RPC is something other than what you think it is. Do you mean a syscall? That is simply an interrupt triggered from software.
Re: Do you really need RPC? (and Interrupts)
Posted: Thu Feb 17, 2011 1:08 pm
by Brendan
Hi,
cxzuk wrote:Can you tell me more about polling for interrupts? Do you basically have a structure that alters when an interrupt fires? Then poll this structure?
There's interrupt controllers for controlling the delivery of IRQs to the CPU/s. For polling there's 2 options - you either disable the CPU's ability to receive IRQs from the interrupt controllers and poll the interrupt controller/s to see which IRQs occurred; or you don't use the interrupt controller/s at all and poll each device's status instead.
There's also 2 extremes. The first extreme is using 100% of all CPU time constantly polling, which is very bad for performance because of the huge amount of CPU time you waste for no reason (you severely cripple CPU bound tasks). The other extreme is to poll very rarely (e.g. in between doing useful work), which is very bad for performance because it can take a long time before you notice that a device needed attention (you severely cripple IO bound tasks). In general, polling must be a compromise between these extremes - you know it will suck badly, but you get to decide why.
Then there's power management. When there's nothing to do you want the CPU/s to go to sleep to save power (and reduce heat, minimise unnecessary CPU fan noise, preserve laptop battery life, etc); and when something happens (e.g. an IRQ occurs) you want the CPU/s to wake up, handle the IRQ and do any extra work that became possible (e.g. an IRQ from the keyboard could result in an application doing something and updating the screen). For polling you can't do that - a CPU can't poll while it's asleep.
IRQs are used by hardware (devices) to request attention from software (drivers). In a similar way, inter-process communication (IPC) can be seen as a way for software to request attention from other software. For IPC you don't want tasks (processes, threads, whatever) that constantly check to see if they received anything via. IPC when they haven't, because that would suck badly (for the same reason polling sucks badly for IRQs). You also want tasks to be able to tell the scheduler they don't need any CPU time (which is sort of like a CPU going to sleep) and you want the task to be woken up again if/when it receives something via. IPC (which is sort of like an IRQ waking up a CPU).
For IPC there's only a few decisions that really matter. The most important decision is the general type of IPC:
- Disruptive (receiving IPC disrupts the receiver's normal program flow).
- Examples:
Characteristics:
- Can be fast
- Can cause major hassles due to reentrancy concerns
- Synchronous (sender can't send until receiver is ready to receive).
- Examples:
Characteristics:
- Can be fast
- Doesn't scale very well
- Asynchronous (sender can send regardless of if receiver is ready to receive or not).
- Examples:
- asynchronous messaging
- pipes
- sockets
Characteristics:
- Can scale extremely well
- Typically slower (some buffering required)
Cheers,
Brendan
Re: Do you really need RPC? (and Interrupts)
Posted: Fri Feb 18, 2011 2:04 am
by rdos
The are some examples of hardware devices where the decision to use interrupts is not clean-cut. Especially for USB devices, that has a fixed time-schedule. It might be faster to just use a timer to check all the lists of completed requests instead of receiving interrupts after each completion that will generate a massive amount of interrupts when USB devices are sending lots of data. I initially used the timer concept for USB devices because of their APIC IRQ-setups (which I couldn't handle), but I'm not sure if I will switch back to an interrupt scheme ones this is solved.
Regarding RPC, and "software IRQs", my OS uses the same primitive to signal completion of ISRs as to signal completion to a thread waiting for any other event. The Signal primitive will set a flag in a thread's control-block, and will then wake it up if it is waiting. This is an atomic operation that works from ISRs and on multiple cores. Then there is the ClearSignal function that will clear the signalled flag, and the WaitForSignal function that will wait until the flag is set (and will not wait at all if it is already set). The flag is automatically cleared when the WaitForSignal completes. WaitForSignal is atomic so if another signal is sent it will not be missed under any circumstances. This primitive can be used to implement any type of more complex RPCs. It is used to implement the multiple-wait objects that RDOS has. Signal/WaitForSignal is extremely fast, yet does not require the receiver to be waiting. It is used for things like waking up server-threads for various hardware drivers, like for hard discs or ethernet. When Windows and Linux runs the TCP/IP protocol stack partly on ISRs, RDOS runs all this code as an usual kernel thread with above average priority. This means I can easily debug it, including single-stepping code.
RDOS has three basic multitasking primitives:
* The above Signal/WaitForSignal
* EnterSection/LeaveSection, which are used to synchronize software and can be used to implement semaphores and similar
* Asynchonous timers that are fired from an hardware ISR (PIT or APIC timer), which are used to implement delays and timeouts.
Re: Do you really need RPC? (and Interrupts)
Posted: Fri Feb 18, 2011 5:49 am
by cxzuk
thank you guy's some great information! I have one final question. Specific to x86. How do i connect an interrupt source to the apic? I think its hardcoded?
Re: Do you really need RPC? (and Interrupts)
Posted: Fri Feb 18, 2011 9:05 am
by Combuster
You can't change the physical wiring - the devices are always connected. You can however tell various chips how to translate electrical signals to interrupt numbers.