Subj : Solaris real-time thread capabilities To : comp.unix.solaris,comp.programming.threads From : capnwhit Date : Fri Sep 02 2005 08:37 pm ======== QUESTION ======== How can I get 10 millisecond timing reliably on a 2 CPU UltraSPARC-II 450MHz system? ================= PROBLEM STATEMENT ================= I have a Solaris application in which I need a thread to process packages approximately every 10 milliseconds. The thread should be woken up every 10 ms to send the queued packages and the thread should then "sleep" until the next 10 ms interval. There is a jitter buffer at the other end, so I don't need _EXACTLY_ 10 ms... even if I get woken up within 20 ms it is OK... but being off by 100 ms would be bad. ======= SUMMARY ======= I have tried but I can't get the required timing despite using "hires_tick", and despite creating a RT (realtime) thread, and despite creating a processor set and allocating one entire CPU to said thread on a 2 CPU machine. I have read everything I can get my hands on and I have tried every trick in my book, but I have failed to maintain the required timing... I tried using SIGALRM to get the required timing, I tried nanosleep, and I even tried a spin loop, and nothing works... any help would be appreciated. =========== DESCRIPTION =========== I have tried many, many different combinations of the different strategies shown below... None have yielded adequate results. Anybody have any other hints or tricks? (A) Thread priority ------------------------------------- I have tried increasing the priority of the given thread using "pthread_attr_setschedparam". Even after setting the maximum priority, the thread still does not get woken up in time. (B) Using high resolution timers ------------------------------------- I have tried enabling "hires_tick" in /etc/system, as follows: ---------- set hires_tick = 1 ---------- Even after setting "hires_tick" my thread does not get woken up reliably every 10 ms. (C) Using RT (realtime) class ------------------------------------- I have tried using a Solaris realtime thread using "priocntl"... This type of thread will not get preempted by the operating system (and you need root access to create one of these threads). This did not help either. (D) Using processor sets ------------------------------------- I have created a processor set using "psrset", and I have allocated the second processor (processor 2) to the processor set: ---------- root@vulcan:/> psrset user processor set 1: processor 2 ---------- I have allocated only 1 (one) thread to the processor set. In other words, only my realtime LWP is running on processor #2 (nothing else is running on said processor). Even with an entire CPU at it's disposal, the thread still does not get woken up in time. (E) Using processor NO-INTERRUPT mode ------------------------------------- I have prevented processor 2 from being interrupted by I/O devices by setting it to "no-interrupt" mode: ---------- root@vulcan:/> psrinfo 0 on-line since 08/26/05 16:17:01 2 no-intr since 08/26/05 17:19:48 ---------- Even if the processor is set to "no-intr", the thread still does not maintain reliable timing. (F) Using SIGALRM ------------------------------------- My initial attempt was to use SIGALRM to deliver the required timing, but under Solaris 8 this did not work reliably. (G) Using nanosleep ------------------------------------- I have tried using "nanosleep" to sleep the prescribed amount of time. Most of the time nanosleep wakes up my thread reliably, but once in a while the thread is woken up too late (i.e. more than 100 ms have elapsed). (H) Using spin loop ------------------------------------- In desperation I have also tried using a spin loop using "gethrtime()" in order to _NOT_ call nanosleep, as shown conceptually below: ---------- t2 = gethrtime(); while(t2 < target_time) { t1 = gethrtime(); t2 = gethrtime(); diff = t2 - t1; [...cut...] } ---------- In the above loop, the average difference between t1 and t2 is about 1000 nanoseconds (this is good), but once in a while the difference between t1 and t2 is 300,000,000 nanoseconds (this is bad)!!! (H) I am out of ideas... ------------------------------------- Anybody have any suggestions? Is there any way to get reliable 10 millisecond resolution from Solaris? ====================== HARDWARE CONFIGURATION ====================== System Configuration: Sun Enterprise 220R CPU: 2 X UltraSPARC-II 450MHz System clock frequency: 113 MHz Memory size: 2048 Megabytes Thanks! .