How do registers quickly store and retrieve data on a context switch? - cpu-registers

Registers are the fastest type of memory. On a context switch, registers have to save their data somewhere and then they have to load the right data into the registers for that particular context. This could be a slow process if the registers aren't storing and retrieving their data from other registers.
But I'm not sure what registers use to store and retrieve data for context switches. I don't think they use other registers. What do they use?
Also, about how often does a context switch take place?

A bit of googling yields this fairly in-depth wiki article on context switching.
How often this happens depends on the operating system; on Linux, it depends on what scheduler algorithm is in fashion this week, and what parameters it's been compiled with.

Related

Sharing data between PAM app and PAM module

I have a PAM application that makes use of a particular PAM module for authentication chores. My question is, what is the best for the module to share an arbitrary string of bytes with the application?
My understanding of the PAM API is that, in general, the application must use the pam_get_item() call in order to obtain data from the module. However, the item types that can be shared are very limited, and they do not seem to accommodate for what I need - with the possible exception of the PAM_CONV item type. If anybody in this forum has experience with this kind of thing their feedback would be much appreciated.
After some experimentation I think I found the answer. In essence, the application has to define a PAM conversation callback in which a pointer to a data buffer is provided. The PAM module has to invoke the callback at the appropriate time, and copy the appropriate data into that buffer. The application will simply obtain the desired data by reading the contents of the buffer.
This will of course have to be carefully choreographed by the application, and the module may have to be modified to invoke the callback at the right time. The idea is simple though.
I am learning a lot as a result of posting to this forum, even if I don't seem to be getting any feedback when it comes to PAM-related questions.
I think you can use PAM_CONV. as it says:
The PAM library uses an application-defined callback to allow a direct
communication between a loaded module and the application. This
callback is specified by the struct pam_conv passed to pam_start(3) at
the start of the transaction.

Hardware and Sotfware saves during Context Switch in xv6

I'm studying the xv6 context switch on Operating Systems: Three Easy Pieces book. I can not fully understand the Saving and Restoring Context section of Chapter 6 (page 8).
Why there are two types of register saves/restore that happen during the Context Switch protocol?
What is the difference between the mentioned user registers and kernel registers?
What is the meaning of:
By switching stacks, the kernel enters the call to the switch code in the context of one process (the one that was interrupted) and returns in the context of another (the soon-to-be-executing one).
Why there are two types of register saves/restore that happen during the Context Switch protocol?
Assuming you are talking about p. 10. The text is a bit misleading (but not as nearly bad as I have seen in some books). They are comparing register save in interrupts those to context switches. It's really not a good comparison.
Register saves in interrupt handling is done the same way as you do it in a function call (and not like it is done in a context switch). You have to preserve any register values you are going to muck with at the start interrupt handling then restore them before the interrupt handler return. You are only dealing with general purpose registers as well (ie not process control registers).
Register save in context switches are done en-masse. All the process's registers get saved at once. An interrupt service routine might save 4 registers while a context switch might save more than 30.
What is the difference between the mentioned user registers and kernel registers?
Some registers are accessible and modifiable in user mode. The general purpose registers would certainly be user registers. The processor status is a mixed bag because it can be read in user mode, it can be modified in some ways in user mode by executing instructions but it is generally read only in user mode. You might call that a user register or might not.
There are other registers that are only accessible in kernel mode. For example, there will be registers that define the process's page table. Other registers will define the system dispatch table.
Note here the only some of the kernel mode registers are process registers (e.g. those setting up page tables) and need to be saved and restored with the process. Other kernel registers are system wide (e.g. those for timers and the system dispatch table). Those do not change with the process.
By switching stacks, the kernel enters the call to the switch code in the context of one process (the one that was interrupted) and returns in the context of another (the soon-to-be-executing one).
This is a little bit misleading in the excerpt but might make more sense if I read the book carefully.
A process context switch requires changing all the per-process registers to a block whose structure is defined by the CPU. What I find misleading in your excerpt is that the context switch involves more than just switching stacks.
Typically a context change looks something like:
SAVE_PROCESS_CONTEXT_INSTRUCTION address_of_the_current_process_context_block
LOAD_PROCESS_CONTEXT_INSTRUCTION address_of_the_next_process_context_block
As soon as you load a process context you are in the new process. That switch includes changing the kernel mode stack.
Some operating systems use terminology in their documentation that implies interrupts (especially) and (sometimes) exceptions being handlers are not done in the context of a process. In fact, the CPU ALWAYS executes in the context of a process.
As soon as you execute the context switch instruction you are in the new process BUT in an exception or interrupt handler in kernel mode. The change in the kernel stack causes the return from the exception or interrupt to resume the new process's user mode code.
So you are already in the context of the process with the PCB switch.The resulting change in the kernel mode stack pointer (ie establishing a new kernel mode stack) causes return from the exception or interrupt to pick up where the new process was before it entered kernel mode (via exception or interrupt)

Caching of data in a text file — Better options

I am working on an application at the moment that is using as a caching strategy the reading and writing of data to text files in a read/write directory within the application.
My gut reaction is that this is sooooo wrong.
I am of the opinion that these values should be stored in the ASP.NET Cache or another dedicated in-memory cache such as Redis or something similar.
Can you provide any data to back up my belief that writing to and reading from text files as a form of cache on the webserver is the wrong thing to do? Or provide any data to prove me wrong and show that this is the correct thing to do?
What other options would you provide to implement this caching?
EDIT:
In one example, a complex search is performed based on a keyword. The result from this search is a list of Guids. This is then turned into a concatenated, comma-delimited string, usually less than 100,000 characters. This is then written to a file using that keyword as its name so that other requests using this keyword will not need to perform the complex search. There is an expiry - I think three days or something, but I don't think it needs to (or should) be that long
I would normally use the ASP.NET Server Cache to store this data.
I can think of four reasons:
Web servers are likely to have many concurrent requests. While you can write logic that manages file locking (mutexes, volatile objects), implementing that is a pain and requires abstraction (an interface) if you plan to be able to refactor it in the future--which you will want to do, because eventually the demand on the filesystem resource will be heavier than what can be addressed in a multithreaded context.
Speaking of which, unless you implement paging, you will be reading and writing the entire file every time you access it. That's slow. Even paging is slow compared to an in-memory operation. Compare what you think you can get out of the disks you're using with the Redis benchmarks from New Relic. Feel free to perform your own calculation based on the estimated size of the file and the number of threads waiting to write to it. You will never match an in-memory cache.
Moreover, as previously mentioned, asynchronous filesystem operations have to be managed while waiting for synchronous I/O operations to complete. Meanwhile, you will not have data consistent with the operations the web application executes unless you make the application wait. The only way I know of to fix that problem is to write to and read from a managed system that's fast enough to keep up with the requests coming in, so that the state of your cache will almost always reflect the latest changes.
Finally, since you are talking about a text file, and not a database, you will either be determining your own object notation for key-value pairs, or using some prefabricated format such as JSON or XML. Either way, it only takes one failed operation or one improperly formatted addition to render the entire text file unreadable. Then you either have the option of restoring from backup (assuming you implement version control...) and losing a ton of data, or throwing away the data and starting over. If the data isn't important to you anyway, then there's no reason to use the disk. If the point of keeping things on disk is to keep them around for posterity, you should be using a database. If having a relational database is less important than speed, you can use a NoSQL context such as MongoDB.
In short, by using the filesystem and text, you have to reinvent the wheel more times than anyone who isn't a complete masochist would enjoy.

Qt and RTI DDS interaction---Need some guidance

I am making a GUI where I have multiple forms on QStackedWIdget. Now I want the data in these forms to be updated as and when available. The data will be recieved through RTI DDS. Can some one suggest me some examples or links where the GUI data is updated from Non GUI thread.
Thank You.
You have several options at your disposal. I will explain the one that seems to suit your situation best, as far as I can assess from your question.
First you need to know that on the subscriber side, there are three different possible kinds of interaction between your application and the DDS DataReaders: polling, listeners and waitsets. Polling basically means that your application queries the DataReader when it deems necessary, for example at a fixed rate. Using listeners means that your application provides the middleware with some callback functions which get invoked whenever new data has arrived. Waitsets are similar to a socket select, where your application thread is blocked until data arrives, or a time-out occurs -- typically followed by an action to access the DataReader.
For GUI applications, it is common to use a polling mechanism as opposed to a listener approach that you are probably using. In stead of reading the data as it arrives, and immediately updating the GUI widgets, you can let your GUI read or take data from the DataReaders at a fixed rate, for example at 5 Hz.
With that approach, you take control over when you access DDS and you can do it at the exact rate required, no matter how fast the data gets updated inside your DataReader. Additionally, your question of data being updated by a non-GUI thread is resolved, because you access the DDS DataReader from your own context.
A potential disadvantage of using polling could be that the updating of the widgets happens with some delay, for example if you poll at 5 Hz, your maximum extra delay will be 200 msec. That is usually not a problem for GUI applications though.

Data sharing - SQLite vs Shared Memory IPC

I would like to get your opinion regarding a design implementation for data sharing.
I am working on Linux embedded device (mips 200 Mhz) and I want to have some sort of data sharing between multiple processes which can either read or write multiple parameters at once.
This data holds ~200 string parameters which are updated every second.
Process may access to data around ~10 times in 1 second.
I would very much like to try and make the design efficient (CPU / Mem).
This data is not required to be persistent and will be recreated every reboot.
Currently, I am considering two options:
Using shard memory IPC (SHM) + semaphore (locking on all SHM).
To use SQLite memory based DB.
For either option, I will supply a C interface library which will perform all the logic of DB operation.
For SHM, this mean locking/unlocking the semaphore and access the parameters which can be referred as an indexed array.
For SQLite, my library will be a wrapper for the SQLite interface library, so the process will not have to know SQL syntax, (some parsing should be done for queries and reply).
I believe that shared memory is more efficient:
No need to use and parse SQL, and it is accessed as an array.
Saying that, there are some pros as well for using SQLite:
Already working and debugged (DB level).
Add flexibility.
Used widely in many embedded systems.
Getting to the point,
Performance wise, I have no experience with SQLite, I would appreciate if you can share your opinions and experience.
Thanks
SQLite's in-memory databases cannot be shared between processes, but you could put the DB file into tmpfs.
However, SQLite does not do any synchronization between processes. It does lock the DB file to prevent update conflicts, but if one process finds the file already locked, it just waits for a random amount of time.
For efficient communication between processes, you need to use a mechanism like SHM/semaphores or pipes.

Resources