Re: USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY
Re: USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY
- Subject: Re: USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY
- From: Vyacheslav Matyushin <email@hidden>
- Date: Mon, 19 Dec 2011 05:15:50 -0800 (PST)
Another observation:
In the book "Mac OS X Internals: A Systems Approach" there is an example program:
"It creates a thread that performs a periodic computation that involves
sleeping for a fixed duration followed by processing for a fixed duration.
We use mach_absolute_time() to measure the approximate difference
between the time the thread wished to sleep for and the actual sleeping time.
If the difference is more than a predefined threshold, we increment an error count.
If the program is run with no command-line arguments, it will not modify the thread's scheduling policy.
If one or more command-line arguments are provided,
the program will set the policy to THREAD_TIME_CONSTRAINT_POLICY using predefined parameters."
The code is at the bottom of this post.
The book claims:
$ ./thread_time_constraint # thread priority is ordinary
waiting 10 seconds...
117 errors in 189 samples
$ ./thread_time_constraint enable_real_time # requested real-time priority using THREAD_TIME_CONSTRAINT_POLICY
waiting 10 seconds...
0 errors in 200 samples
But on my system (Mac OS X 10.6.8) I see another behaviour.
When the system is NOT under load, the output of repeating launches of "./thread_time_constraint arg" is:
11 errors in 199 samples
10 errors in 199 samples
8 errors in 199 samples
6 errors in 199 samples
9 errors in 199 samples
6 errors in 199 samples
10 errors in 199 samples
Here I launch my streaming, which creates system load. I can also add something like yes > /dev/null to increase it.
1 errors in 199 samples
2 errors in 199 samples
1 errors in 199 samples
2 errors in 199 samples
3 errors in 199 samples
1 errors in 199 samples
0 errors in 200 samples
1 errors in 199 samples
0 errors in 199 samples
Here I stop the streaming and decrease the system load:
11 errors in 199 samples
11 errors in 199 samples
13 errors in 199 samples
13 errors in 199 samples
12 errors in 199 samples
6 errors in 199 samples
16 errors in 199 samples
In all cases the thread is created using THREAD_TIME_CONSTRAINT_POLICY.
So when the system is not under load, THREAD_TIME_CONSTRAINT_POLICY behaves worse than when under load!
I'll be glad if anybody explains such behaviour.
I guess this can be related to the weirdness described in my previous post.
Thanks,
Vyacheslav Matyushin.
// thread_time_constraint_policy.c#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <pthread.h>#include <mach/mach.h>#include <mach/mach_time.h>#include <mach/thread_policy.h>#define PROGNAME "thread_time_constraint_policy"#define SLEEP_NS 50000000 // sleep for 50 ms// if actual sleeping time differs from SLEEP_NS by more than this amount,// count it as an error#define ERROR_THRESH_NS ((double)50000) // 50 usstatic double abs2clock;static unsigned long long nerrors = 0, nsamples = 0;static struct timespec rqt = { 0, SLEEP_NS };// before exiting, print the information we collectedvoidatexit_handler(void){ printf("%llu errors in %llu samples\n", nerrors, nsamples);}void *timestamper(void *arg){ int ret; double diff_ns; u_int64_t t1, t2, diff; while (1) { t1 = mach_absolute_time(); // take a high-resolution timestamp ret = nanosleep(&rqt, NULL); // sleep for SLEEP_NS seconds t2 = mach_absolute_time(); // take another high-resolution timestamp if (ret != 0) // if sleeping failed, give up exit(1); diff = t2 - t1; // how much did we sleep? // the "error" (in nanoseconds) in our sleeping time diff_ns = ((double)SLEEP_NS) - (double)diff * abs2clock; if (diff_ns < 0) diff_ns *= -1; if (diff_ns > ERROR_THRESH_NS) nerrors++; nsamples++; } return NULL;}intmain(int argc, char **argv){ int ret; kern_return_t kr; pthread_t t1; static double clock2abs; mach_timebase_info_data_t tbinfo; thread_time_constraint_policy_data_t policy; ret = pthread_create(&t1, (pthread_attr_t *)0, timestamper, (void *)0); ret = atexit(atexit_handler); (void)mach_timebase_info(&tbinfo); abs2clock = ((double)tbinfo.numer / (double)tbinfo.denom); // if any command-line argument is given, enable real-time if (argc > 1) { clock2abs = ((double)tbinfo.denom / (double)tbinfo.numer) * 1000000; policy.period = 50 * clock2abs; // 50 ms periodicity policy.computation = 1 * clock2abs; // 1 ms of work policy.constraint = 2 * clock2abs; policy.preemptible = FALSE; kr = thread_policy_set(pthread_mach_thread_np(t1), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&policy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); if (kr != KERN_SUCCESS) { mach_error("thread_policy_set:", kr); goto OUT; } } ret = pthread_detach(t1); printf("waiting 10 seconds...\n"); sleep(10);OUT: exit(0);} _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden