implementing a threads package in user space - c

So is it possible to implement a threads package in user space while the operating system does not have anything like the select system call to see in advance if it is safe to read from a file, pipe, or device, but it does allow alarm clocks to be set that interrupt blocked system calls?

Related

How does select() monitor without using cpu cycles to poll

While I understand that select call basically puts the process in wait until one of the file descriptors passed to monitor is ready.
In contrast to constantly checking the file descriptor until it is ready, the select call provides better performance as it doesn't use any cpu cycles for checking the file descriptors.
But how does it really work underneath? How does the monitoring part work without constantly checking the file descriptor's status? In case of file descriptor being a socket, the NIC could trigger an interrupt but how would it work for regular files or stdin or stdout streams?
The core of select is a system call. It tells the operating system the process wants to wait for activity on the file descriptors. The operating system updates its records to show the process is in a waiting state, not ready to run, and it does not run the process until something happens.
Then the operating system goes on to do other things. It runs other processes on the processor(s), it responds to device interrupts, and so on. When a time comes that there is nothing for the system to do—no processes are ready to run (that are not already running on one of the processors) and all interrupts have been serviced, the operating system executes some sort of wait or sleep instruction that lets the processor go dormant for a time.
When the processor is in a wait or sleep state, the hardware will wake it when an interrupt arrives.

Does signal sent from kernel to user space real time?

I am writing a driver and try sending something from kernel to user space, what I gonna to(which is the only way I know), is to send a signal from kernel to user space, and call signal(...) somewhere in user space, which will catch it and use ioctl(...), now is time kernel send things to user space.
My question is, when signal sent, it has to wait util user space call signal(), and then do something?
And is there any other ways to talk between kernel and user space?
Did you consider having your driver just send some bytes on a file descriptor (e.g some socket(7) or pipe(7) or character device..)? Or using netlink(7) ? Or interact with systemd ?
A common way would be to have some helper process in user land (started at boot time) handling that file descriptor. That program would probably use some multiplexing system call like poll(2).
Beware that when your driver is running (and you try to send some signal), the current task might not be a process using your driver. So sending signals from kernel land could be tricky.

How does Linux kernel interrupt the application?

First of all, I am a device driver guy. This is my first time to handle an user mode program.
I used to have an interrupt service routine to response a hardware interrupt.
In other word, the hardware uses interrupt service routine to notify the driver to service.
I use ioctl to be a channel to communicate between the application and device driver now and poll it to wait the response.
Are there other ways that a device driver can notify an application when it finishes some task?
Any comments are welcome.
Thanks,
There are several mechanisms for this. First approach: user-space application makes poll() or select() system call, waiting for some event from kernel. Second approach is to use Netlink sockets. There are also others like mmap() or signals. Google by kernel user-space IPC and you will see the whole list.
As for your case (drivers development), I'd say go with next approach. Create sysfs file in your driver, and do sysfs_notify() (and maybe wait_for_completion_interruptible_timeout() or something like that). In user-space do select() system call for your driver sysfs file. See how line discipline installed from user-space for example.
Typically, the kernel never notifies an application unless the application requests the notification and is waiting for the notification. On unix systems, this will typically be done using the select or similar routines. One supplies select with a set of file descriptors and select will then wait until there is activity on one of the file descriptors at which time it returns.
Given that on unix all devices are files, you should be able to make use of this mechanism to wake an application when an interrupt comes in on some hardware device.
There are plenty of kernel-userspace communication interfaces in addition to ioctl (signals, sockets, etc). Please, refer to Kernel Space - User Space Interfaces tutorial for detailed explanation.

multiple unrelated process synchronisation UART

I want to use a shared library with multiple processes running concurrently. My library contains UART open/write/read/close, Each process writes a specific UART command and expects related response. Application calls APIs in LIB, Inside API open UART port, writes command to UART and read response from UART, process response buffer and send back to user [API takes 2 to 3 seconds for execution].
I have 30 such APIs and 5 processes running concurrently using these APIs.
How can I provide synchronisation across all these processes, such that only one process uses UART at a time and all other blocks on UART.
Regards & Thanks,
Anil.
You're asking a very general question about how to co-ordinate multiple processes. This is a vast and deep subject, and there are lots of routes you could take. Here are some ideas:
1) create a lock file in /var/lock. This will work with other programs that use the serial port. When one program is done, the others will race to create the lock, and a random one will win.
2) have your library create a shared memory segment. In the shared memory segment, write down who has the 'lock'. As with lock files, you'll want to write down the PID, so the others can steal the lock if the owner dies. This has the least amount of overhead.
3) Split your serial code into a "UART control daemon" and a client library that calls the daemon. The daemon listens on a unix socket (or TCP/UDP, or other IPC) and handles the serial port exclusively. (You can easily find 'chat server' code written in any language). This has several advantages:
The daemon can tell callers how many requests are "in the queue"
The daemon can try to maintain the FIFO order, or handle priority requests if it wants.
The daemon can cache responses when multiple clients are asking the same question at once.
If you don't want the daemon running all the time, you can have xinetd start it. (Make sure it's in singe-server mode.)
Instead of each process having to be linked to a serial library, it uses the simpler standard unix sockets (or TCP).
Your API calling programs become much easier to test (no need for hardware, you can simulate responses)
If an API calling program dies, the UART isn't left in a bad state

Executing a user-space function from the kernel space

Im writing a custom device driver in linux that has to be able to respond very rapidly on interrupts. Code to handle this already exists in a user-space implementation but that is too slow as it relies on software constantly checking the state of the interrupt line. After doing some research, I found that you can register these interrupt lines from a kernel module, and execute a function given by a function pointer. However the code we want to execute is in the user-space, is there a way to call a function in the user-space from a kernel space module?
You are out of luck with invoking user-space functions from the kernel since the kernel doesn't and isn't supposed to know about individual user-space application functions and logic, not to mention that each user-space application has its own memory layout, that no other process nor the kernel is allowed to invade in that way (shared objects are the exception here, but still you can't tap into that from the kernel space). What about the security model, you aren't supposed to run user-space code (which is automatically considered unsafe code in the kernel context) in the kernel context in the first place since that will break the security model of a kernel right there in that instant. Now considering all of the above mentioned, plus many other motives you might want to reconsider your approach and focus on Kernel <-> User-space IPC and Interfaces, the file system or the user-mode helper API(read bellow).
You can invoke user space apps from the kernel though, that using the usermode-helper API. The following IBM DeveloperWorks article should get you started on using the usermode-helper Linux kernel API:
Kernel APIs, Part 1: Invoking user-space applications from the kernel
I think the easiest way is to register a character device which becomes ready when the device has some data.
Any process which tries to read from this device, then gets put to sleep until the device is ready, then woken up, at which point it can do the appropriate thing.
If you just want to signal readyness, a reader could just read a single null byte.
The userspace program would then just need to execute a blocking read() call, and would be blocked appropriately, until you wake it up.
You will need to understand the kernel scheduler's wait queue mechanism to use this.
Sounds like your interrupt line is already available to userspace via gpiolib? (/sys/class/gpio/...)
Have you benchmarked if gpio edge triggering and poll() is fast enough for you? That way you don't have to poll the status from the userspace application but edge triggering will report it via poll(). See Documentation/gpio.txt in kernel source.
If the edge triggering via sysfs is not good enough, then the proper way is to develop a kernel driver that takes care of the time critical part and exports the results to userspace via a API (sysfs, device node, etc).
I am also facing the same problem, I read this document http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-6.html, so planning to use signals. In my case there is no chance of losing signals, because
1. the system is closed loop, after signals executed then only I will get another signal.
2. And I am using POSIX real-time signals.

Resources