Beispiel #1
0
/* 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 */
}
Beispiel #2
0
/* 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 */
}
Beispiel #3
0
/* 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 */
}