Interrupts in C/C++??? How are they implemented / coded? - c++

Having programmed microcontrollers before and being interested in trying my hand at building an NES emulator at some point, I was really wondering how interrupts are implemented in C++?
How, for example, does a program know how to react when I speak into my mic or move my mouse? Is it constantly polling these ports?
When emulating an interrupt for a hardware device (say, for an NES emulator), do you have to constantly poll or is there another way to do this?

This is an implementation-specific question, but broad strokes: direct access to hardware via interrupts is generally limited to the OS (specifically, to the kernel.) Your code will not have such access on any modern system. Rather, you'd use OS-specific APIs to access hardware.
In short: desktop operating systems do not behave like embedded, microcontrolled devices.
User input is generally handled on modern systems by something called an event loop. Your application does something like this, the specific implementation varying between OSes:
int main(int argc, char *argv[]) {
Event *e = NULL;
while (e = App::GetNextEvent()) {
switch (e->getType()) {
case E_MOUSEUP:
case E_RIGHTMOUSEDOWN:
case E_KEYDOWN:
// etc.
}
}
return EXIT_SUCCESS;
}
In this example, App::GetNextEvent() doesn't busy-wait: it simply sits and does nothing until signalled internally by the OS that an event has arrived. In this way, no constant polling is required and the OS can dole out time slices to processes more efficiently.
However... the NES is not a modern system; emulating one means you need to emulate the interrupts and hardware of the NES. Doing so is a very large undertaking and has no relation to the underlying hardware or interrupts of the host operating system. The 6502 processor in the NES is very simple by modern standards; there are books available that discuss emulating similar simple processors, though titles escape me at the moment.
Does that help?

Related

How can I distinguish between high- and low-performance cores/threads in C++?

When talking about multi-threading, it often seems like threads are treated as equal - just the same as the main thread, but running next to it.
On some new processors, however, such as the Apple "M" series and the upcoming Intel Alder Lake series not all threads are equally as performant as these chips feature separate high-performance cores and high-efficiency, slower cores.
It’s not to say that there weren’t already things such as hyper-threading, but this seems to have a much larger performance implication.
Is there a way to query std::thread‘s properties and enforce on which cores they’ll run in C++?
How to distinguish between high- and low-performance cores/threads in C++?
Please understand that "thread" is an abstraction of the hardware's capabilities and that something beyond your control (the OS, the kernel's scheduler) is responsible for creating and managing this abstraction. "Importance" and performance hints are part of that abstraction (typically presented in the form of a thread priority).
Any attempt to break the "thread" abstraction (e.g. determine if the core is a low-performance or high-performance core) is misguided. E.g. OS could change your thread to a low performance core immediately after you find out that you were running on a high performance core, leading you to assume that you're on a high performance core when you are not.
Even pinning your thread to a specific core (in the hope that it'll always be using a high-performance core) can/will backfire (cause you to get less work done because you've prevented yourself from using a "faster than nothing" low-performance core when high-performance core/s are busy doing other work).
The biggest problem is that C++ creates a worse abstraction (std::thread) on top of the "likely better" abstraction provided by the OS. Specifically, there's no way to set, modify or obtain the thread priority using std::thread; so you're left without any control over the "performance hints" that are necessary (for the OS, scheduler) to make good "load vs. performance vs. power management" decisions.
When talking about multi-threading, it often seems like threads are treated as equal
Often people think we're still using time-sharing systems from the 1960s. Stop listening to these fools. Modern systems do not allow CPU time to be wasted on unimportant work while more important work waits. Effective use of thread priorities is a fundamental performance requirement. Everything else ("load vs. performance vs. power management" decisions) is, by necessity, beyond your control (on the other side of the "thread" abstraction you're using).
Is there any way to query std::thread‘s properties and enforce on which cores they’ll run in C++?
No. There is no standard API for this in C++.
Platform-specific APIs do have the ability to specify a specific logical core (or a set of such cores) for a software thread. For example, GNU has pthread_setaffinity_np.
Note that this allows you to specify "core 1" for your thread, but that doesn't necessarily help with getting the "performance" core unless you know which core that is. To figure that out, you may need to go below OS level and into CPU-specific assembly programming. In the case of Intel to my understanding, you would use the Enhanced Hardware Feedback Interface.
No, the C++ standard library has no direct way to query the sub-type of CPU, or state you want a thread to run on a specific CPU.
But std::thread (and jthread) does have .native_handle(), which on most platforms will let you do this.
If you know the threading library implementation of your std::thread, you can use native_handle() to get at the underlying primitives, then use the underlying threading library to do this kind of low-level work.
This will be completely non-portable, of course.
iPhones, iPads, and newer Macs have high- and low-performance cores for a reason. The low-performance cores allow some reasonable amount of work to be done while using the smallest possible amount of energy, making the battery of the device last longer. These additional cores are not there just for fun; if you try to get around them, you can end up with a much worse experience for the user.
If you use the C++ standard library for running multiple threads, the operating system will detect what you are doing, and act accordingly. If your task only takes 10ms on a high-performance core, it will be moved to a low-performance core; it's fast enough and saves battery life. If you have multiple threads using 100% of the CPU time, the high-performance cores will be used automatically (plus the low-performance cores as well). If your battery runs low, the device can switch to all low-performance cores which will get more work done with the battery charge you have.
You should really think about what you want to do. You should put the needs of the user ahead of your perceived needs. Apart from that, Apple recommends assigning OS-specific priorities to your threads, which improves behaviour if you do it right. Giving a thread the highest priority so you can get better benchmark results is usually not "doing it right".
You can't select the core that a thread will be physically scheduled to run on using std::thread. See here for more. I'd suggest using a framework like OpenMP, MPI, or you will have dig into the native Mac OS APIs to select the core for your thread to execute on.
macOS provides a notion of "Quality of Service" for tasks, task queues and run loops, and threads. If you use libdispatch/GCD then the queue priorities map to the QoS as well. This article describes the QoS system in detail.
Using the macOS pthreads interface you can set a thread QoS before creating a thread, query a thread's QoS, or temporarily override a thread's QoS level (not visible in the query function though) using the non-portable functions in pthread/qos.h
This system by no means offers guarantees about how your threads will be scheduled, but can be used to make a hint to the scheduler.
I'm not aware of any way to get a similar interface on other systems, but that doesn't mean they don't exist. I imagine they'll become more widely discussed as these hybrid CPUs befome more common.
EDIT: Intel provides information here about how to query this information for their hybrid processors on Windows and for the current CPU using cpuid, haven't had a chance to play with this though.

Send interrupt to cpu as keyboard do?

Is it possible to simulate hardware interrupts somehow from user program?
I've seen this question posted many times, but always not answered.
I want to know about low-level interrupts (for example simulate situation when key pressed on keyboard, so that keyboard driver would interrupt interrupt).
High level events and APIs are outside scope, and question is rather theoretical than practical (to prevent "why" discussions :)
Yes and no.
On an x86 CPU (for one example) there's an int instruction that generates an interrupt. Once the interrupt is generated, the CPU won't necessarily1 distinguish between an interrupt generated by hardware and one generated by software. For one example, in the original PC BIOS, IBM chose an interrupt that would cause the print-screen command to execute. The interrupt they chose (interrupt 5) was one that wasn't then in use, but which Intel had said was reserved for future use. Intel eventually did put that interrupt to use -- in the 286 they added a bound instruction that checks that a value is within bounds, and generates an interrupt if it's not. The bound instruction is essentially never used though, because it generates interrupt 5 if a value is out of bounds. This means (if you're running something like MS-DOS that allows it) executing the bound instruction with a value that's out of bounds will print the screen.
On a modern OS, however, this won't generally be allowed. All generation and handling of interrupts happens in the kernel. The hardware had 4 levels of protection ("rings") and support for specifying the ring at which the int instruction can be executed. If you try to execute it from code running at ring 3, it won't execute directly -- instead, execution will switch to the OS kernel, which can treat it as it chooses.
This allows (for example) Windows to emulate MS-DOS, so MS-DOS programs (which do use the int instruction) can execute in a virtual machine, with virtualized input and output, so even though they "think" they're working directly with the keyboard and screen hardware, they're actually using emulations of them provided by software.
For "native" programs, however, using most int instructions (i.e. any but a tiny number of interrupts intended for communication with the kernel) will simply result in the program being shut down.
So, bottom line: yes, the hardware supports it -- but the hardware also supports prohibiting it, and nearly every modern OS does exactly that, at least for most code outside the OS kernel itself.
Though, with typical hardware, the interrupt handler can read data from the programmable interrupt controller (PIC) chip that will tell it whether the interrupt came through the PIC (i.e., hardware interrupt) or not (software interrupt). Most hardware also supports at least a few interrupts that can be generated only by hardware, such as NMI on the x86. These are usually reserved for fairly narrow uses though (e.g., NMI on a PC is normally used for things like memory parity errors).

Need help to choose real-time OS and Hardware

I heard and read that Windows/Linux OS machines are not real-time.
I have read this article. It listed WindowsCE is one of RTOS. That's kind of confusing to me since I always thought WindowsCE is for a mobile or embeded device.
I need a real-time application running 24/7 and processing signals various sensors from each quick moving object to db and monitor by running several machine learning algorithms.
What would be proper real-time hardware and OS for this kind of applications? Development environment would be MFC or Qt C++. I really need opinions from experienced developers. Thanks
QNX has served me well in the past. I should warn you that it was only for training purposes (real-time industrial process control), and that I have implemented real time control programs with this OS by I've never really deployed one.
The first rule with real-time systems is to specify your real-time constraints, such as:
the system must be able to process up to 600 signals per minute; or
the system must spend no more than 1/10 second per signal.
The difference is subtle, but these are different constraints.
Just keep in mind that there is absolutely no way to decide if any hardward/OS/library combination is good enough for you unless you specify these constraints
For that, you think QNX might be proper? What would be its advantages over Windows/Linux systems with high priority setting?
If you look at the QNX documentation for many POSIX systems calls, you will notice they specify extra constraints on performance, which are possibly required to guarantee your real-time constraints. The OS is specifically designed to match these constraints. You won't get this on a system that is not officially an RTOS. If you are going to write real-time software, I recommend that you buy a good book on the subject. There is considerable literature given that the subject is very sensitive.
Get yourself a good book on real-time system design to get a feel of what questions to ask, and then read the technical documentation of each product you will use to see if it can match your constraints. Example of things to look in software libraries like Qt is when they allocate memory. If this is not documented in each class interface, there is no way to guarantee meeting your constraints since there is hidden algorithmic complexity.
Development environment would be MFC or Qt C++.
I would think that Qt compiles on QNX, but I'm not sure if Qt provides the guarantees required to match your real-time constraints. Libraries that abstract away too much stuff are risk since it's difficult to determine if they satisfy your requirements. Hidden memory management is often problematic, but there are other questions you should ask about too.
It seems to me that people say Real-time systems == embedded systems. Am I wrong?
Real-time system definitely does not equal "embedded system", though many embedded systems have real-time constraints.
How real time do you need?
Remember real time is about responsiveness, not speed. In fact most RTOS will be slower on average than general OS.
Do you need to guarrantee a certain average number of transactions/second or do you need to always respond within n seconds of an event?
Do you have custom hardware or are you relying on inputs over ethernet, USB, etc?
Are drivers for the hardware available on the RTOS or will you have to write them yourself ?
Windows and linux are possible RTOS. Windows embedded allows you to turn off services to give much more reliable response rate and there are both realtime kernels and realtime add-ons to Linux which give pretty much the same real time performance as something like VxWorks.
It also depends on how many tasks you need to handle. A lot of the complexity of true RTOS (like VxWorks) is that they can control many tasks at the same time while allowing each a guaranteed latency and CPU share - important for a Mars rover but not for a single data collection PC

How to program in Windows 7.0 to make it more deterministic?

My understanding is that Windows is non-deterministic and can be trouble when using it for data acquisition. Using a 32bit bus, and dual core, is it possible to use inline asm to work with interrupts in Visual Studio 2005 or at least set some kind of flags to be consistent in time with little jitter?
Going the direction of an RTOS(real time operating system): Windows CE with programming in kernel mode may get too expensive for us.
Real time solutions for Windows such as LabVIEW Real-time or RTX are expensive; a stand-alone RTOS would often be less expensive (or even free), but if you need Windows functionality as well, you are perhaps no further forward.
If cost is critical, you might run a free or low-cost RTOS in a virtual machine. This can work, though there is no cooperation over hardware access between the RTOS and Windows, and no direct communication mechanism (you could use TCP/IP over a virtual (or real) network I suppose.
Another alternative is to perform the real-time data acquisition on stand-alone hardware (a microcontroller development board or SBC for example) and communicate with Windows via USB or TCP/IP for example. It is possible that way to get timing jitter down to the microsecond level or better.
There are third-party realtime extensions to Windows. See, e. g. http://msdn.microsoft.com/en-us/library/ms838340(v=winembedded.5).aspx
Windows is not an RTOS, so there is no magic answer. However, there are some things you can do to make the system more "real time friendly".
Disable background processes that can steal system resources from you.
Use a multi-core processor to reduce the impact of context switching
If your program does any disk I/O, move that to its own spindle.
Look into process priority. Make sure your process is running as High or Realtime.
Pay attention to how your program manages memory. Avoid doing thigs that will lead to excessive disk paging.
Consider a real-time extension to Windows (already mentioned).
Consider moving to a real RTOS.
Consider dividing your system into two pieces: (1) real time component running on a microcontroller/DSP/FPGA, and (2) The user interface portion that runs on the Windows PC.

Schedule task on precise periods in Linux or Windows

I have this weird question.
I would like to know if it is possible to make a program in C/C++ that will run on Linux or Windows and will hook interrupt handler on a system timer set to specific period (2000 times per second, for example) and I want this interrupt to be with highest priority, meaning that it has to be executed every half millisecond and while executing it must not be interrupted.
This we have done with MS-DOS with Borland Turbo C 3.1. We have an interface card (our own) that runs on ISA slot. Every half millisecond, our program reads the state of electronics that is controlling an industrial process thru the interface. This has worked for us in the past 15 years, but we are running out of motherboards that have ISA slot, so we are looking for new solutions.
We also have solution based on PIC microcontrollers, but our horizons will be widened with general purpose processor.
My guess is that there are some customized Linux kernels for embedded applications, so I am looking for some sources with which we can start experimenting.
Yes, you can do that in MS-DOS because it is not a multi-user or multi-tasking operating system. However, the same thing will not work in Windows because it is a mult-user and multi-tasking operating system. It's also not real-time, which means there's no guarantee that your task will be executed exactly when you ask for it to be executed. Everything is pre-emptively scheduled, meaning that any number of other processes and tasks (either user-mode or system-level) could effectively "bump" your process down the priority list and force it to wait to be executed until those other tasks completed or were themselves interrupted to give your process a chance to run for a while.
I don't know about Linux, but I imagine most of the major distributions are written similarly to Windows.
You will need to find a real-time, single-user operating system to do this. A Unix-derivative is probably the best place to start looking, but I won't be the person able to suggest one.
Alternatively, you could continue using MS-DOS (or alternatives such as FreeDOS), but switch to a different interface technology that is available on newer boards. There's no reason to update something that works for you, especially if the updates are counter-productive to your goal.
A typical OS such as a standard Linux or Windows is not designed to, and will not be able to perform to that degree of real-time accuracy and availability.
It sounds to me like you need to be investigating Real-Time Linux, or similar.
RTLinux is a modified version of the Linux Kernel which is designed to perform in real-time, precicely for applications such as this.
Hope that helps.
Personal and affordable computing has increased in performance incredibly over the years, except in one area, low latency. Latency has actually increased in many use cases when you compare a 486 and a modern desktop CPU.
That said, have a look at this paper, where the authors come to the conclusion that sub-millisecond scheduling is possible in Linux on commodity hardware.