8
votes

I have a project with some soft real-time requirements. I have two processes (programs that I've written) that do some data acquisition. In either case, I need to continuously read in data that's coming in and process it.

The first program is heavily threaded, and the second one uses a library which should be threaded, but I have no clue what's going on under the hood. Each program is executed by the user and (by default) I see each with a priority of 20 and a nice value of 0. Each program uses roughly 30% of the CPU.

As it stands, both processes have to contended with a few background processes, and I want to give my two programs the best shot at the CPU as possible. My main issue is that I have a device that I talk to that has a 64 byte hardware buffer, and if I don't read from it in time, I get an overflow. I have noted this condition occurring once every 2-3 hours of run time.

Based on my research (http://oreilly.com/catalog/linuxkernel/chapter/ch10.html) there appear to be three ways of playing around with the priority:

  1. Set the nice value to a lower number, and therefore give each process more priority. I can do this without any modification to my code (or use the system call) using the nice command.

  2. Use sched_setscheduler() for the entire process to a particular scheduling policy.

  3. Use pthread_setschedparam() to individually set each pthread.

I have run into the following roadblocks:

  1. Say I go with choice 3, how do I prevent lower priority threads from being starved? Is there also a way to ensure that shared locks cause lower priority threads to be promoted to a higher priority? Say I have a thread that's real-time, SCHED_RR and it shared a lock with a default, SCHED_OTHER thread. When the SCHED_OTHER thread gets the lock, I want it to execute @ higher priority to free the lock. How do I ensure this?

  2. If a thread of SCHED_RR creates another thread, is the new thread automatically SCHED_RR, or do I need to specify this? What if I have a process that I have set to SCHED_RR, do all its threads automatically follow this policy? What if a process of SCHED_RR spawns a child process, is it too automatically SCHED_RR?

  3. Does any of this matter given that the code only uses up 60% of the CPU? Or are there still issues with the CPU being shared with background processes that I should be concerned with and could be caused my buffer overflows?

Sorry for the long winded question, but I felt it needed some background info. Thanks in advance for the help.

1
The 64 byte hardware buffer should not matter because the driver should have much more buffer space than that. How are you communicating with the driver?Martin James
The chip itself is an i2c to uart bridge, and will only hold 64 bytes of UART data. Currently I am continously polling the chip by opening the /dev/i2c file. As far as I know, there is not a better driver available and I'm under a time crunch and won't have the time to put something better together.It'sPete
A highest-priority blocking read is not quick enough?Martin James
For the 99% case it is, but I get 1 FIFO overflow every couple of hours. I've actually increased the nice level of my program to -20 and I haven't seen an issue yet, but more testing might be required. I know that I'm doing the I/O equivalent of trying to cure a brain tumor with some pain killers, but it looks like it did it.It'sPete

1 Answers

2
votes

(1) pthread_mutex_setprioceiling

(2) A newly created thread inherits the schedule and priority of its creating thread unless it's thread attributes (e.g. pthread_attr_setschedparam / pthread_attr_setschedpolicy) are directed to do otherwise when you call pthread_create.

(3) Since you don't know what causes it now it is in fairness hard for anyone say with assurance.