I've hit a tough problem in using the real-time scheduling capabilities in the Mach kernel, and wonder if anyone out there can help. Here's the issue: If our primary application thread does not use the "real-time" thread scheduling API offered by the Mach kernel, that is, if a competing process lauches, for example another application is launched, our thread is stopped entirely. The scheduler just doesn't let us run until the competing process completes and/or releases resources. Using the real-time API for the Mach kernel (set_thread_priority(...)), we are able to guarantee our application thread enough of the CPU to run fairly smoothly even when another process is competing. However, now the behavior we observe is that when our process has run smoothly for a while at high CPU usage (approx 70-80% for example), it will be suddenly "demoted" by the scheduler to a very low CPU%. Piecing together background from the kernel programming documentation on Apple's developer site, I believe that this "demotion" effect happens because the scheduler automatically demotes processes deemed to be taking too much of the CPU. What's surprising is that we are using "reasonable" thread_time_constraint_policy settings. We have experimented with a range of values based on examples from Apple and other "real-time" applications such as audio and video players. We are taking a high but still reasonable percentage of the CPU. So the basic question is, is there a way that we can guarantee that our process will not be completely stopped when competing processes launch other than using the real-time API? And if we need to use the real-time API, is there a way we can avoid the demotion effect, for example, yield to other processes when necessary? I have researched all of the Mac OS X programming texts and the Apple documentation but have found no additional information on how to use the real-time APIs beyond basic examples, and would appreciate any advice. Below is a snippet of the code we are using to set our main application thread policy. Many thanks in advance. Michelle void thread_priority_init() { struct thread_time_constraint_policy ttcpolicy; int ret, bus_speed, mib [2] = { CTL_HW, HW_BUS_FREQ }; size_t len; len = sizeof( bus_speed); ret = sysctl (mib, 2, &bus_speed, &len, NULL, 0); if (ret < 0) { err("sysctl query bus speed failed, errno=%d", errno); return; } /* The period is the number of cycles over which we are guaranteed a number of clock cycles equal to the second argument (the computation). The third argument (the constraint) is the maximum number of cycles to complete. */ // from esound example: (160, 3300, 2200) cdaudio example: (120, 1440, 720) ttcpolicy.period=bus_speed/160; ttcpolicy.computation=bus_speed/3300; ttcpolicy.constraint=bus_speed/2200; ttcpolicy.preemptible=1; if ((ret=thread_policy_set(mach_thread_self(), THREAD_TIME_CONSTRAINT_POLICY, (int *)&ttcpolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT)) != KERN_SUCCESS) { err("Apple real time policy setting failure, errno=%d", errno); } else { dbg("Apple real time: %d of %d cycles, %d constraint, bus speed=%d(Hz)", ttcpolicy.computation, ttcpolicy.period, ttcpolicy.constraint, bus_speed); } } _______________________________________________ darwin-kernel mailing list | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.