On 2010-02-17, at 6:37 PM, James Long wrote:
Second, I tried statprof. It's great. I was able to get some decent output in my compiled program. I pumped up the thread heartbeat to 1/1000 instead of 1/100. However, strangely enough, when I tried running it straight on my iPhone, I got only ONE entry, the high-level function which runs everything, and of course it said 100%.
My guess is that Mac OS X has a broken implementation of setitimer. I've send bug reports to Apple but never heard from them. Bug report attached below.
Marc
/* * File: "timer.c". * * This program was written by Marc Feeley (feeley@iro.umontreal.ca). * * This program exhibits a problem with the ITIMER_VIRTUAL timer on * Mac OS X. It seems that some of the signals that should be generated * are lost. If the ITIMER_REAL timer is used instead, the signals * are generated in a timely manner. Moreover, when the ITIMER_VIRTUAL * timer is used, it seems that generating events (such as moving the * mouse, pressing the shift key on the keyboard, etc) causes the * signals to be generated for a moment. Below is a trace of the execution. * The program should write one V on stdout every 1/10 of a second. * * $ gcc -DUSE_ITIMER_VIRTUAL timer.c * $ time ./a.out * VVVV^C * * real 0m9.489s * user 0m9.470s * sys 0m0.010s * $ gcc -DUSE_ITIMER_REAL timer.c * $ time ./a.out * RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR^C * * real 0m6.737s * user 0m6.590s * sys 0m0.000s * $ uname -a * Darwin bambi.iro.umontreal.ca 7.8.0 Darwin Kernel Version 7.8.0: Wed Dec 22 14:26:17 PST 2004; root:xnu/xnu-517.11.1.obj~1/RELEASE_PPC Power Macintosh powerpc */
#include <sys/time.h> #include <signal.h> #include <stdio.h> #include <unistd.h>
void heartbeat_interrupt_handler (int sig) { #ifdef USE_ITIMER_REAL write (STDOUT_FILENO, "R", 1); #else write (STDOUT_FILENO, "V", 1); #endif }
int main (int argc, char *argv[]) { struct itimerval tv; int secs = 0; int usecs = 100000;
#ifdef USE_ITIMER_REAL int HEARTBEAT_ITIMER = ITIMER_REAL; int SIG = SIGALRM; #else int HEARTBEAT_ITIMER = ITIMER_VIRTUAL; int SIG = SIGVTALRM; #endif
struct sigaction act; act.sa_handler = heartbeat_interrupt_handler; act.sa_flags = 0; #ifdef SA_INTERRUPT act.sa_flags |= SA_INTERRUPT; #endif sigemptyset (&act.sa_mask); sigaction (SIG, &act, 0);
tv.it_interval.tv_sec = secs; tv.it_interval.tv_usec = usecs; tv.it_value.tv_sec = secs; tv.it_value.tv_usec = usecs; setitimer (HEARTBEAT_ITIMER, &tv, 0); getitimer (HEARTBEAT_ITIMER, &tv);
for (;;) { /* keep CPU 100% busy */ }
return 0; }