_DEBUGGING REAL-TIME SYSTEMS_ by Gurjot Singh, Moses Joseph, and Dave Barnett [LISTING ONE] /* simulate.c -- Simulate a real-time system and measure and/or record. ** 1. Device interrupt response time; 2. Device driver interrupt service ** time; 3. Task response time ** Each measured time is exagerated by a constant amount of time equal to the ** length of time it takes to make the measurement. */ #include #include #define PRODUCER_PRIO 17 extern void producer(); extern void display(); extern void record(); struct { void (*f)(); /* task entry point */ int p_bias; /* priority relative to producer (always negative) */ } consumers = { { display, -1 }, { record, -1 } }; #define NCONSUMERS (sizeof consumers / sizeof consumers[0]) main(argc, argv) int argc; char *argv[]; { int i; if (argc != 2) { fprintf(stderr, "Usage: %s timer_device\n", argv[0]); exit(1); } init_data(NCONSUMERS); for (i = 0; i < NCONSUMERS; i++) { pthread_attr_t attr; pthread_t tid; pthread_attr_create(&attr); pthread_attr_setinheritsched(&attr, PTHREAD_DEFAULT_SCHED); pthread_attr_setprio(&attr, PRODUCER_PRIO + consumers[i].p_bias); if (pthread_create(&tid, attr, consumers[i].f, i) == -1) { perror("pthread_create"); exit(1); } } init_timer(argv[1]); producer(); exit(0); } /* producer.c */ #define wait_for_interrupt() sleep(5) #define record_trt() #define record_tct() void producer() { for (;;) { wait_for_interrupt(); record_trt(); signal_consumers(); wait_for_consumers(); record_tct(); } } /* consumer1 */ void display(id) int id; { for (;;) { wait_for_producer(id); signal_producer(id); } } /* synch.c */ #include #include #include static pthread_mutex_t mutex; static pthread_cond_t write_cond; /* O.K. to write */ static pthread_cond_t read_cond; /* O.K. to read */ static int readers_done; int *done; static int num_readers; void init_data(readers) int readers; { int i; if (pthread_mutex_init(&mutex, pthread_mutexattr_default) == -1) { perror("pthread_mutex_init"); exit(1); } if (pthread_cond_init(&write_cond, pthread_condattr_default) == -1) { perror("pthread_cond_init"); exit(1); } if (pthread_cond_init(&read_cond, pthread_condattr_default) == -1) { perror("pthread_cond_init"); exit(1); } num_readers = readers; readers_done = num_readers; if (!(done = (int *)malloc(num_readers * sizeof(int)))) { perror("malloc"); exit(1); } for (i = 0; i < num_readers; i++) done[i] = 1; } void wait_for_consumers() { pthread_mutex_lock(&mutex); if (readers_done != num_readers) { pthread_cond_wait(&write_cond, &mutex); } pthread_mutex_unlock(&mutex); } void signal_consumers() { int i; pthread_mutex_lock(&mutex); readers_done = 0; for (i = 0; i < num_readers; i++) done[i] = 0; pthread_cond_broadcast(&read_cond); pthread_mutex_unlock(&mutex); } void signal_producer(id) int id; { pthread_mutex_lock(&mutex); readers_done++; if (readers_done == num_readers) { pthread_cond_signal(&write_cond); } done[id] = 1; pthread_mutex_unlock(&mutex); } void wait_for_producer(id) int id; { pthread_mutex_lock(&mutex); if (done[id]) pthread_cond_wait(&read_cond, &mutex); pthread_mutex_unlock(&mutex); }