OK, so we've learned that we really don't want any blocking or any I/O while we're processing. After we get a service request that should ideally all be done up front. Maybe with something like a DMA that just puts the data we need in memory for us. But it's pretty clear that we might not always be lucky enough to have that situation. We may have a request for service and then have to go get some data and wait to get it from a device. Or we may have to have minor amounts small I/O while we're executing after we have already acquired the major portion of our data. But either way that's going to either impact our execution efficiency or introduce some intermediate blocking where our service runs and that's a challenge. So RMA really would like to consider that, when the services requested, the only thing we need is a CPU, right? So we need to deal with this. This is a major assumption of RMA that we need to work around, so will first start out with a small problem. Minor amount of I/O blocking and issues with execution efficiency. In other words, we need to do things like maybe read some memory mapped registers, or we've got some slow memory or things like that. But not major kinds of blocking events on I/O devices or shared memory. I will cover that next so as we said, this is our assume timeline and the only thing we really have is interference by higher priority task. If we have blocking that would undoubtedly come in the middle of our execution, we would request some sort of I/O here? And that might cause us to block. And then we would have a big chunk of time that we come out here that would be blocking essentially waiting on I/O. And that would be bad. What we want to do is wait on all the I/O upfront here and at the end. So let's talk about what happens if it's a small amount of I/O like, really, things like memory mapped, registers or basic simple memory mapped I/O. So short I/O requests, things like registers and so forth, or perhaps different types of memory mapped I/O. So in other words input that we can just read by dereferencing a pointer in C code for example, in the loop or something like that. And that will slow down our execution, but not dramatically, not as much as waiting for, say, a DMA to complete that hasn't even been started or something like that. Or waiting on a mutex, a mutual exclusion semaphore to gain access to shared memory. Those things would be major blocking I/O events, so we're talking about minor ones here that just impact our execution efficiency. In fact, it looks like we're executing the entire time, if we look at something like each top, but were being stalled, our execution is stalling the processor pipeline and slowing this down perhaps. So if we have CPU pipeline stalls that are due to hazards like memory mapped I/O for example like we're talking about now, or just missing cache and having to go to a slow memory. Go to slow memory and that's going to clearly increase our WCET, right? Like it gets longer, close up and data pansies, memory mapped registers, et cetera. So during service execution, maybe off-chip memory, being loading cache after a DMA completion, et cetera. Lots of possibilities there, and we know most likely you're familiar with the idea of pipeline processing for microprocessors where we fetch an instruction, we decode that instruction, we execute it, we right back results. And the nice thing is we basically complete instruction every single Clock. So if we just look at Clock, 1, 2, 3, 4 down to N we have a CPI equal to 1, CPI equals 1. You can also talk about instructions per Clock, so IPC equals 1 just depends which way you want to do your ratio. If you tend to have multiple Clocks for instruction then we normally talk CPI. If you can normally get multiple instructions done per Clock with something like VLIW or super scaler, then we talked about instructions per Clock. But that's a computer architecture discussion. For now it's sufficient just to know that normally we can get an instruction done on every Clock unless were stalling waiting on something like, a access to a slower memory device. Memory mapped registers, simple I/O, but simple I/O that can make our execution time longer. The good news is this isn't really going to mess up our RMA, it's just going to make our WCET longer. So it's more of an execution efficiency problem than it is really an intermediate I/O blocking problem. But I can still give us some trouble, so we should look at it. So the WCET should be whatever our CPI is in the best case, tends longest path in our service. Loop where we do processing before we go back and wait on the semaphore again. And how would we determine that? Well, we could look at the assembly code so we could compile it and give minus caps to GCC. So if you give