Example #1
0
/* the serial writer thread: */
static void
_tme_posix_serial_th_writer(struct tme_posix_serial *serial)
{
  tme_uint8_t buffer_output[1024];
  unsigned int buffer_output_size;
  int rc;

  /* lock the mutex: */
  tme_mutex_lock(&serial->tme_posix_serial_mutex);

  /* loop forever: */
  for (;;) {

    /* if there is no data to write, wait on the writer condition,
       after which there must be data to write: */
    if (tme_serial_buffer_is_empty(&serial->tme_posix_serial_buffer_out)) {
      tme_cond_wait_yield(&serial->tme_posix_serial_cond_writer,
			  &serial->tme_posix_serial_mutex);
    }

    /* get the data to write: */
    buffer_output_size = 
      tme_serial_buffer_copyout(&serial->tme_posix_serial_buffer_out,
				buffer_output,
				sizeof(buffer_output),
				NULL,
				TME_SERIAL_COPY_PEEK);
    assert(buffer_output_size > 0);

    /* unlock the mutex: */
    tme_mutex_unlock(&serial->tme_posix_serial_mutex);

    /* try to write the device: */
    rc = tme_thread_write_yield(serial->tme_posix_serial_fd_out,
				buffer_output,
				buffer_output_size);

    /* lock the mutex: */
    tme_mutex_lock(&serial->tme_posix_serial_mutex);

    /* if the write was successful: */
    if (rc > 0) {

      /* remove the written data from the output buffer: */
      tme_serial_buffer_copyout(&serial->tme_posix_serial_buffer_out,
				NULL,
				rc,
				NULL,
				TME_SERIAL_COPY_NORMAL);

      /* call out for more data: */
      _tme_posix_serial_callout(serial);
    }
  }
  /* NOTREACHED */
}
Example #2
0
/* this waits on a condition, with an optional sleep time: */
void
tme_stp22xx_cond_sleep_yield(struct tme_stp22xx *stp22xx,
			     struct tme_stp22xx_cond *cond,
			     const struct timeval *sleep)
{
  signed long completion_i;
  struct tme_completion *completion;

  /* this condition must be idle: */
  assert (cond->tme_stp22xx_cond_state == TME_STP22XX_COND_STATE_IDLE);

  /* we are now running, before waiting on this condition: */
  cond->tme_stp22xx_cond_state = TME_STP22XX_COND_STATE_RUNNING;

  /* run: */
  _tme_stp22xx_run(stp22xx);

  /* if this condition was notified while we were running: */
  if (cond->tme_stp22xx_cond_state == TME_STP22XX_COND_STATE_NOTIFIED) {

    /* this condition is idle again: */
    cond->tme_stp22xx_cond_state = TME_STP22XX_COND_STATE_IDLE;

    return;
  }

  /* the condition must still be running: */
  assert (cond->tme_stp22xx_cond_state == TME_STP22XX_COND_STATE_RUNNING);

  /* make a total write-after-write barrier, to force writes to the
     completion states to happen before validation: */
  tme_memory_barrier(0, 0, TME_MEMORY_BARRIER_WRITE_BEFORE_WRITE);

  /* validate any completions whose validations were delayed: */
  for (completion_i = 0;; completion_i++) {
    completion = stp22xx->tme_stp22xx_completions_delayed[completion_i];
    if (completion == NULL) {
      break;
    }
    stp22xx->tme_stp22xx_completions_delayed[completion_i] = NULL;
    tme_completion_validate(completion);
  }

  /* we are now waiting on this condition, unless threading is
     cooperative, in which case the condition will be idle again the
     next time this thread runs: */
  cond->tme_stp22xx_cond_state
    = (TME_THREADS_COOPERATIVE
       ? TME_STP22XX_COND_STATE_IDLE
       : TME_STP22XX_COND_STATE_WAITING);

  /* sleep or wait on the condition variable: */
  if (sleep != NULL) {
    tme_cond_sleep_yield(&cond->tme_stp22xx_cond_cond,
			 &stp22xx->tme_stp22xx_mutex,
			 sleep);
  }
  else {
    tme_cond_wait_yield(&cond->tme_stp22xx_cond_cond,
			&stp22xx->tme_stp22xx_mutex);
  }

  /* this condition is idle again: */
  cond->tme_stp22xx_cond_state = TME_STP22XX_COND_STATE_IDLE;

  /* reenter: */
  _tme_stp22xx_enter_locked(stp22xx);
}
Example #3
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 */
}