/* the serial control thread: */ static void _tme_posix_serial_th_ctrl(struct tme_posix_serial *serial) { int modem_state, modem_state_out; unsigned int ctrl; /* loop forever: */ for (;;) { /* get the modem state of the input device: */ if (ioctl(serial->tme_posix_serial_fd_in, TIOCMGET, &modem_state) < 0) { modem_state = 0; } /* if the output device is different, get the modem state of the output device and merge it in: */ if (serial->tme_posix_serial_fd_out != serial->tme_posix_serial_fd_in) { if (ioctl(serial->tme_posix_serial_fd_in, TIOCMGET, &modem_state_out) < 0) { modem_state_out = 0; } modem_state &= ~(TIOCM_DTR | TIOCM_RTS | TIOCM_CTS); modem_state |= modem_state_out & ~(TIOCM_CD | TIOCM_RI | TIOCM_DSR); } /* lock the mutex: */ tme_mutex_lock(&serial->tme_posix_serial_mutex); /* update the control outputs: */ ctrl = (serial->tme_posix_serial_ctrl_callout & ~(TME_SERIAL_CTRL_CTS | TME_SERIAL_CTRL_DCD | TME_SERIAL_CTRL_RI | TME_SERIAL_CTRL_BREAK)); if (modem_state & TIOCM_CTS) { ctrl |= TME_SERIAL_CTRL_CTS; } if (modem_state & TIOCM_CD) { ctrl |= TME_SERIAL_CTRL_DCD; } if (modem_state & TIOCM_RI) { ctrl |= TME_SERIAL_CTRL_RI; } if (serial->tme_posix_serial_ctrl_callout_break > 0) { ctrl |= TME_SERIAL_CTRL_BREAK; serial->tme_posix_serial_ctrl_callout_break--; } /* if the control outputs have changed, call out the change: */ if (ctrl != serial->tme_posix_serial_ctrl_callout) { serial->tme_posix_serial_ctrl_callout = ctrl; _tme_posix_serial_callout(serial); } /* unlock the mutex: */ tme_mutex_unlock(&serial->tme_posix_serial_mutex); /* check the controls again in .5 seconds: */ tme_thread_sleep_yield(0, 500000); } /* NOTREACHED */ }
/* the isil7170 timer thread: */ static void _tme_isil7170_th_timer(struct tme_isil7170 *isil7170) { tme_uint8_t int_mask; tme_uint32_t sleep_usec; #ifdef TME_ISIL7170_TRACK_INT_RATE struct timeval now; #endif /* TME_ISIL7170_TRACK_INT_RATE */ /* lock the mutex: */ tme_mutex_lock(&isil7170->tme_isil7170_mutex); /* loop forever: */ for (;;) { /* if we were sleeping: */ int_mask = isil7170->tme_isil7170_timer_sleeping; isil7170->tme_isil7170_timer_sleeping = 0; if (int_mask) { #ifdef TME_ISIL7170_TRACK_INT_RATE /* if no interrupt is pending, and this interrupt is not masked, we will deliver another interrupt: */ if (!(isil7170->tme_isil7170_regs[TME_ISIL7170_REG_INT] & TME_ISIL7170_INT_PENDING) && (int_mask & isil7170->tme_isil7170_int_mask)) { isil7170->tme_isil7170_int_sample++; } /* if the sample time has finished, report on the interrupt rate: */ gettimeofday(&now, NULL); if (now.tv_sec > isil7170->tme_isil7170_int_sample_time.tv_sec || (now.tv_sec == isil7170->tme_isil7170_int_sample_time.tv_sec && now.tv_usec > isil7170->tme_isil7170_int_sample_time.tv_usec)) { if (isil7170->tme_isil7170_int_sample > 0) { tme_log(TME_ISIL7170_LOG_HANDLE(isil7170), 0, TME_OK, (TME_ISIL7170_LOG_HANDLE(isil7170), "timer interrupt rate: %ld/sec", (isil7170->tme_isil7170_int_sample / (TME_ISIL7170_TRACK_INT_RATE + (unsigned long) (now.tv_sec - isil7170->tme_isil7170_int_sample_time.tv_sec))))); } /* reset the sample: */ isil7170->tme_isil7170_int_sample_time.tv_sec = now.tv_sec + TME_ISIL7170_TRACK_INT_RATE; isil7170->tme_isil7170_int_sample_time.tv_usec = now.tv_usec; isil7170->tme_isil7170_int_sample = 0; } #endif /* TME_ISIL7170_TRACK_INT_RATE */ /* update the interrupt register: */ isil7170->tme_isil7170_regs[TME_ISIL7170_REG_INT] |= int_mask; /* callout to update our interrupt signal: */ _tme_isil7170_callout(isil7170); } /* get the interrupt mask: */ int_mask = isil7170->tme_isil7170_int_mask; /* if the 1/100 second periodic interrupt is unmasked: */ if (int_mask & TME_ISIL7170_INT_HSEC) { int_mask = TME_ISIL7170_INT_HSEC; sleep_usec = isil7170->tme_isil7170_clock_hsec_usec; } /* if the 1/10 second periodic interrupt is unmasked: */ else if (int_mask & TME_ISIL7170_INT_TSEC) { int_mask = TME_ISIL7170_INT_TSEC; sleep_usec = isil7170->tme_isil7170_clock_tsec_usec; } /* otherwise, all periodic interrupts are masked. wait until one of them is not: */ else { tme_cond_wait_yield(&isil7170->tme_isil7170_cond_timer, &isil7170->tme_isil7170_mutex); continue; } /* we are sleeping: */ isil7170->tme_isil7170_timer_sleeping = int_mask; /* unlock our mutex: */ tme_mutex_unlock(&isil7170->tme_isil7170_mutex); /* sleep: */ tme_thread_sleep_yield(0, sleep_usec); /* lock our mutex: */ tme_mutex_unlock(&isil7170->tme_isil7170_mutex); } /* NOTREACHED */ }
/* the GTK screens update thread: */ void _tme_gtk_screen_th_update(struct tme_gtk_display *display) { struct tme_gtk_screen *screen; struct tme_fb_connection *conn_fb_other; int changed; int rc; /* loop forever: */ for (;;) { /* lock the mutex: */ tme_mutex_lock(&display->tme_gtk_display_mutex); /* loop over all screens: */ for (screen = display->tme_gtk_display_screens; screen != NULL; screen = screen->tme_gtk_screen_next) { /* skip this screen if it's unconnected: */ if (screen->tme_gtk_screen_fb == NULL) { continue; } /* get the other side of this connection: */ conn_fb_other = ((struct tme_fb_connection *) screen->tme_gtk_screen_fb->tme_fb_connection.tme_connection_other); /* if the framebuffer has an update function, call it: */ if (conn_fb_other->tme_fb_connection_update != NULL) { rc = (*conn_fb_other->tme_fb_connection_update)(conn_fb_other); assert (rc == TME_OK); } /* if this framebuffer needs a full redraw: */ if (screen->tme_gtk_screen_full_redraw) { /* force the next translation to retranslate the entire buffer: */ tme_fb_xlat_redraw(conn_fb_other); conn_fb_other->tme_fb_connection_offset_updated_first = 0; conn_fb_other->tme_fb_connection_offset_updated_last = 0 - (tme_uint32_t) 1; /* clear the full redraw flag: */ screen->tme_gtk_screen_full_redraw = FALSE; } /* translate this framebuffer's contents: */ changed = (*screen->tme_gtk_screen_fb_xlat) (((struct tme_fb_connection *) screen->tme_gtk_screen_fb->tme_fb_connection.tme_connection_other), screen->tme_gtk_screen_fb); /* if those contents changed, redraw the widget: */ if (changed) { gtk_widget_queue_draw(screen->tme_gtk_screen_gtkimage); } } /* unlock the mutex: */ tme_mutex_unlock(&display->tme_gtk_display_mutex); /* update again in .5 seconds: */ tme_thread_sleep_yield(0, 500000); } /* NOTREACHED */ }