an event is when you click on something, and code is run right away
polling is when the application constantly checks if your mouse button is held down, and if it's held down in a certain spot, code is run
do events really exist in computing, or is it all a layer built on polling?
This is a complicated question, and the answer depends on how far down you go (in abstraction layers) to answer it. Ultimately, your USB keyboard device is being polled once per millisecond by the computer to ask what keys are being held down. This information gets passed to the keyboard driver through a CPU interrupt when the USB device (in the computer) gets a packet of data from the keyboard. From then on, interrupts are used to pass the data from process to process (through the GUI framework) and eventually reach your application.
As Marc Cohen said in his answer, CPU interrupts are also raised to signal I/O completion. This is an example of something which has no polling until you get to the hardware level, where checks are performed (perhaps once per clock cycle? Someone with more experience with computer architecture should answer) to see if the event has taken place.
It's a common technique to simulate events by polling but that's often very inefficient and leads to a dilemma where you have a tradeoff between event resolution and polling overhead but that doesn't mean true events don't exist.
A CPU interrupt, which could be raised to signal an external event, like I/O completion, is an example of an event all the way down at the hardware layer.
Well, both operating system and application level depend on events not polling. Polling is usually possible where states cannot be maintained. On desktop applications and OS levels however, applications have states; so, they use events for their processes, not polling.
Related
I am preparing to write some code for a master controller that communicates (via CANbus) with multiple nodes in a product. Each node monitors its own sensors (i.e. voltages, currents, fault flags, etc.) and can be started/stopped by the master controller. The master controller also sends the data to a display.
I am using an STM32H7B3I-EVAL board and using the STM32CubeIDE environment to write the code. I am trying to determine some good practices for writing this code, but I am inexperienced in CAN communication. I wanted to get people's opinions on the following high-level questions:
If we want to be constantly monitoring, should all the code for transmitting and receiving data be in a never-ending while loop?
Is it better to transmit all data then receive all data, or transmit data when needed and have an interrupt for received messages?
What are the pros/cons in using an RXBUFFER vs RXFIFO?
First of all, you need to invent an application tier CAN protocol unless you have one already. This isn't entirely trivial and requires some experience of CAN. Here you first of all need to take bus load in account, which in turn depends on the amounts of nodes and data allowed, as well as the baudrate. How to design this also depends on if it's a control system (hard realtime, milliseconds) or just some industrial sensor network (hundreds of milliseconds or seconds).
If we want to be constantly monitoring, should all the code for transmitting and receiving data be in a never-ending while loop?
Probably not. Regarding RX, depending on what CAN controller you have, there will at least be some manner of RX FIFO. Modern controllers also support dedicated "mailbox" slots for individual messages, which is more powerful and easier to work with. Your only requirement for never losing data is that you empty the FIFO at least as often as FIFO size times the time it takes to send the minimum package size (DLC=0). Unless your program is very busy, this is usually not a tough realtime deadline to meet.
Regarding TX, again it depends on the controller, but here it is usually sufficient to see that the previously send message has been send before attempting a new one. And unless you are really competing hard for bus access during a time of heavy bus load, this shouldn't be happening. Sensible CAN application protocols have some simple scheduling requirements such as "this gets sent after x ms in relation to that". Re-sending messages lost due to errors is handled by the controller hardware.
Is it better to transmit all data then receive all data, or transmit data when needed and have an interrupt for received messages?
TX and RX buffers work independently of each other. Also what you are saying doesn't really make sense, since CAN is semi-duplex and one node's TX is another node's RX.
What are the pros/cons in using an RXBUFFER vs RXFIFO?
Those terms are pretty much synonymous. I suppose they may have some special meaning given a specific CAN controller, but you don't mention one (STM32 have several, one old and really bad "bxCAN" and one newer which I don't know much about. And some stubbornly insist on the horrible solution of using external controllers, particularly the Arduino kids).
Anyway, it is better to have neither, using a CAN controller with mailboxes is the best option. Unless the amount of expected identifiers are more than you have mailbox slots - in that case you have to direct low priority messages to a RX FIFO and use mailbox slots for high priority messages.
I understand that using Hardware support for implementing preemptive scheduling is great for efficiency.
I want to know, What are practical ways we can do preemptive scheduling without taking support from hardware? I think one of way is Software Timers.
Also, Other way in multiprocessor system is using the one processor acting as master keep looking at slave processor's processor.
Consider, I'm fine with non-efficient way.
Please, elaborate all ways you think / know can work. Also, preferably but not necessarily works for single processor system.
In order to preempt a process, the operating system has to somehow get control of the CPU without the process's cooperation. Or viewed from the other perspective: The CPU has to somehow decide to stop running the process's code and start running the operating system's code.
Just like processes can't run at the same time as other processes, they can't run at the same time as the OS. The CPU executes instructions in order, that's all it knows. It doesn't run two things at once.
So, here are some reasons for the CPU to switch to executing operating system code instead of process code:
A hardware device sends an interrupt to this CPU - such as a timer, a keypress, a network packet, or a hard drive finishing its operation.
The software running on a different CPU sends an inter-processor interrupt to this CPU.
The running process decides to call a function in the operating system. Depending on the CPU architecture, it could work like a normal call, or it could work like a fake interrupt.
The running process executes an instruction which causes an exception, like accessing unmapped memory, or dividing by zero.
Some kind of hardware debugging interface is used to overwrite the instruction pointer, causing the CPU to suddenly execute different code.
The CPU is actually a simulation and the OS is interpreting the process code, in which case the OS can decide to stop interpreting whenever it wants.
If none of the above things happen, OS code doesn't run. Most OSes will re-evaluate which process should be running, when a hardware event occurs that causes a process to be woken up, and will also use a timer interrupt as a last resort to prevent one program hogging all the CPU time.
Generally, when OS code runs, it has no obligation to return to the same place it was called from. "Preemption" is simply when the OS decides to jump somewhere other than the place it was called from.
I am trying to profile an Akka app that is constantly at or near 100% CPU usage. I took a CPU sample using visualvm. The sample indicates that there are 2 threads that make up 98.9% of CPU usage. 79% of the cpu time was spent on a method called sun.misc.Unsafe. Other answers on SO say that it just means that a thread is waiting but in the native implementation layer (outside of the jvm).
In questions similar to mine, people have been told to look elsewhere without being given specifics. Where should I look to figure out what's causing the cpu spike?
The application is a server that primarily uses Akka IO to listen for TCP socket connections.
Without seeing any of the source code, or even knowing what IO channel you are talking about (sockets, files, etc), there is very little insight that anyone here can give you.
I do have some rather general suggestions though.
First, you should be using reactive techniques and reactive IO in your application. This issue could be occurring because you are polling the status of some resource in a tight loop, or using a blocking call when you should be using a reactive one. This tends to be an anti-pattern and a performance drain exactly because you can spend CPU cycles doing nothing but "actively waiting". I recommend double checking for:
resource polling
blocking calls
system calls
disk flushes
waiting on a Future when it would be appropriate to map it instead
Second, you should NOT be using Mutexes or other thread synchronization in your application. If so, then you might be suffering from a live-lock. Unlike dead-locks, live-locks manifest with symptoms like 100% CPU usage as threads constantly lock and unlock concurrency primitives in an attempt to "catch them all". Wikipedia has a nice technical description of what a live lock looks like. With Akka in place you shouldn't have any need to use Mutexes or any thread synchronization primitives. If you are then you probably need to re-design your application.
Third, you should be throttling IO (as well as error handling like reconnection attempts). This issue could be occurring because your system lacks effective throttling. Often with data channels we leave their bandwidth unconstrained. However this can become an issue when that channel reaches 100% saturation and begins to steal resources from other parts of the system. This can happen, for example, if you are moving large files around without a reasonable limit.
Alternatively, you also need to throttle connection retries when you encounter any errors, rather than retrying immediately. Lots of systems will attempt to reconnect to a server if they lose their connection. While normally desirable, this can lead to problematic behavior if you use a naive reconnection strategy. For example, imagine a network client that was written this way:
class MyClient extends Client {
... other code...
def onDisconnect() = {
reconnect()
}
}
Every time the Client disconnects for ANY reason it will attempt to reconnect. You can see how this would cause a tight loop between the error handling code and the Client if the Wifi cut-out or a network cable was unplugged.
Fourth, your application should have well defined data sources and sinks. Your issue could be caused by a "data loop", that is some set of Akka actors that are just sending messages to the next actor in the chain, with the last actor sending the message back to the first actor in the chain. Make sure you have a clear and definite way for messages to enter and exit your system.
Fifth, use appropriate profiling and instrumentation for your application. Instrument your application using Kamon or Coda Hale's Metrics library.
Finding an appropriate profiler will be more difficult, since we as a community have far to go to develop mature tools for reactive applications. Personally I have found visualvm useful, but not always overwhelmingly helpful for detecting code paths that are CPU bound. The issue is that sampling profilers are only able to collect data when the JVM reaches a safepoint. This has the potential to bias certain code paths. The fix is to use a profiler that supports AsyncGetStackTrace.
Best of luck! And please add more context if you can.
I am working on implementing a VM and trying to model all the different hardware components as accurately as possible, just for pure learning purposes.
My question is, how does a DMA device handle multiple concurrent transfer requests? From what I understand a DMA device has several registers to set the location in memory, the type of operation (read or write) and the number of bytes, so what happens when the CPU requests an operation from DMA, puts the thread to sleep and then the next thread that runs also requests a DMA operation while the previous one is still in progress? Is this even supported?
Unless you're talking about ancient, ISA-era hardware, DMA nowadays is handled by the device itself taking ownership of the bus and requesting the data directly from the RAM. See the Wikipedia article on Bus Mastering for more information.
Therefore, it is really up to any individual device how to handle DMA, so not much can be said for the general case. However, most simple devices just support a single DMA operation at a time; if the host wants to submit two DMA operations, it would simply wait for the first DMA to complete (being notified by an interrupt) and then instruct the device to do the second one, the OS putting the requesting thread to sleep while the first DMA is in progress. There are certainly variations, however, such as using a command-buffer that can specify multiple (DMA-involving or not) operations for the device to do in sequence without interrupting the CPU between each.
I doubt there are very many devices at all that try to carry out multiple transfers simultaneously, however, seeing as how interleaving DRAM accesses would just hurt performance anyway. But I wouldn't exclude their existence, especially if the operations involve very large transfers.
In the end, you'll just have to read up on the particular device you're trying to emulate.
I recently learnt about precise interrupt and imprecise interrupt in computer architecture class. Is precise interrupt important from software's point of view? If so why is it so?
A precise interrupt leaves the processor in a well-defined state. The consequence is that the running program can be resumed with no risk of error. Resuming will usually be a simple and cheap operation (return from interrupt, or something similar). Most device interrupts fall into this category.
Any other kind of interrupt means that the running program cannot be safely or easily resumed. If it can be resumed at all, the steps to do so are likely to be complex and time-consuming. If it cannot be resumed, then the running program (and perhaps the system) will have to be terminated. A 'panic' interrupt triggered by failing hardware would fit into this category.
The concept is familiar, but I'm not sure these particular terms are in widespread use. Be careful when you use them that your audience understands what you mean.