Пример #1
0
void *PeriodicThread::Run() {
  Clock clock;
  TimeStamp last_run_at;

  clock.CurrentTime(&last_run_at);
  if (!m_callback->Run()) {
    return NULL;
  }

  while (true) {
    {
      MutexLocker lock(&m_mutex);
      if (m_terminate) {
        return NULL;
      }
      if (m_condition.TimedWait(&m_mutex, last_run_at + m_delay)) {
        // Either m_terminate is true, or a spurious wake up
        if (m_terminate) {
          return NULL;
        }
        continue;
      }
    }
    clock.CurrentTime(&last_run_at);
    if (!m_callback->Run()) {
      return NULL;
    }
  }
  return NULL;
}
Пример #2
0
/**
 * test the clock
 */
void ClockTest::testClock() {
  Clock clock;
  TimeStamp first;
  clock.CurrentTime(&first);
  sleep(1);

  TimeStamp second;
  clock.CurrentTime(&second);
  CPPUNIT_ASSERT(first < second);
}
Пример #3
0
/**
 * test the clock
 */
void ClockTest::testClock() {
  Clock clock;
  TimeStamp first;
  clock.CurrentTime(&first);
#ifdef _WIN32
  Sleep(1000);
#else
  sleep(1);
#endif

  TimeStamp second;
  clock.CurrentTime(&second);
  OLA_ASSERT_LT(first, second);
}
Пример #4
0
bool OpenLightingDevice::SubmitInTransfer() {
  if (m_in_in_progress) {
    OLA_WARN << "Read already pending";
    return true;
  }

  uint8_t* rx_buffer = new uint8_t[IN_BUFFER_SIZE];
  libusb_fill_bulk_transfer(m_in_transfer, m_handle, kInEndpoint,
                            rx_buffer, IN_BUFFER_SIZE,
                            InTransferCompleteHandler,
                            static_cast<void*>(this),
                            kTimeout);

  Clock clock;
  clock.CurrentTime(&m_send_in_time);
  int r = libusb_submit_transfer(m_in_transfer);
  if (r) {
    OLA_WARN << "Failed to submit input transfer: "
             << LibUsbAdaptor::ErrorCodeToString(r);
    return false;
  }

  m_in_in_progress = true;
  return true;
}
Пример #5
0
void OpenLightingDevice::_InTransferComplete() {
  TimeStamp now;
  Clock clock;
  clock.CurrentTime(&now);
  OLA_INFO << "In transfer completed in " << (now - m_out_sent_time)
           << ", status is "
           << LibUsbAdaptor::ErrorCodeToString(m_in_transfer->status);

  if (m_in_transfer->status == LIBUSB_TRANSFER_COMPLETED) {
    // Ownership of the buffer is transferred to the HandleData method,
    // running on the SS thread.
    m_ss->Execute(
        NewSingleCallback(
          this, &OpenLightingDevice::HandleData,
          reinterpret_cast<const uint8_t*>(m_in_transfer->buffer),
          static_cast<unsigned int>(m_in_transfer->actual_length)));
  } else {
    delete[] m_in_transfer->buffer;
  }

  MutexLocker locker(&m_mutex);
  m_in_in_progress = false;
  m_pending_requests--;
  if (m_pending_requests) {
    SubmitInTransfer();
  }
}
Пример #6
0
/*
 * Called when there is new DMX data
 */
void DmxMonitor::NewDmx(OLA_UNUSED const ola::client::DMXMetadata &meta,
                        const DmxBuffer &buffer) {
  m_buffer.Set(buffer);

  if (m_data_loss_window) {
    // delete the window
    wborder(m_data_loss_window, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ');
    wrefresh(m_data_loss_window);
    delwin(m_data_loss_window);
    m_data_loss_window = NULL;
    Mask();
  }
  move(0, COLS - 1);  // NOLINT(build/include_what_you_use) This is ncurses.h's
  switch (m_counter % 4) {
    case 0:
      printw("/");
      break;
    case 1:
      printw("-");
      break;
    case 2:
      printw("\\");
      break;
    default:
      printw("|");
      break;
  }
  m_counter++;

  Clock clock;
  clock.CurrentTime(&m_last_data);
  Values();
  refresh();
}
Пример #7
0
/**
 * Check the granularity of usleep.
 */
void UartDmxThread::CheckTimeGranularity() {
  TimeStamp ts1, ts2;
  Clock clock;
  /** If sleeping for 1ms takes longer than this, don't trust
   * usleep for this session
   */
  const int threshold = 3;

  clock.CurrentTime(&ts1);
  usleep(1000);
  clock.CurrentTime(&ts2);

  TimeInterval interval = ts2 - ts1;
  m_granularity = interval.InMilliSeconds() > threshold ? BAD : GOOD;
  OLA_INFO << "Granularity for UART thread is "
           << (m_granularity == GOOD ? "GOOD" : "BAD");
}
Пример #8
0
void OpenLightingDevice::MaybeSendRequest() {
  if (m_out_in_progress || m_pending_requests > MAX_IN_FLIGHT ||
      m_queued_requests.empty()) {
    return;
  }

  OLA_INFO << "Sending out transfer";
  PendingRequest request = m_queued_requests.front();
  m_queued_requests.pop();

  unsigned int offset = 0;
  m_out_buffer[0] = SOF_IDENTIFIER;
  SplitUInt16(request.command, &m_out_buffer[2], &m_out_buffer[1]);
  SplitUInt16(request.payload.size(), &m_out_buffer[4], &m_out_buffer[3]);
  offset += 5;

  if (request.payload.size() > 0) {
    memcpy(m_out_buffer + offset, request.payload.data(),
           request.payload.size());
    offset += request.payload.size();
  }
  m_out_buffer[offset++] = EOF_IDENTIFIER;

  if (offset % USB_PACKET_SIZE == 0)  {
    // We need to pad the message so that the transfer completes on the
    // Device side. We could use LIBUSB_TRANSFER_ADD_ZERO_PACKET instead but
    // that isn't avaiable on all platforms.
    m_out_buffer[offset++] = 0;
  }

  libusb_fill_bulk_transfer(m_out_transfer, m_handle, kOutEndpoint,
                            m_out_buffer, offset,
                            OutTransferCompleteHandler,
                            static_cast<void*>(this),
                            kTimeout);

  Clock clock;
  clock.CurrentTime(&m_out_sent_time);
  OLA_INFO << "TX: Sending " << offset << " bytes";

  int r = libusb_submit_transfer(m_out_transfer);

  if (r) {
    OLA_WARN << "Failed to submit out transfer: "
             << LibUsbAdaptor::ErrorCodeToString(r);
    return;
  }

  m_out_in_progress = true;
  m_pending_requests++;
  if (!m_in_in_progress) {
    SubmitInTransfer();
  }
  return;
}
Пример #9
0
/*
 * Test the TimeStamp class
 */
void ClockTest::testTimeStamp() {
  Clock clock;
  TimeStamp timestamp, timestamp2;
  OLA_ASSERT_FALSE(timestamp.IsSet());
  OLA_ASSERT_FALSE(timestamp2.IsSet());

  // test assignment & copy constructor
  clock.CurrentTime(&timestamp);
  OLA_ASSERT_TRUE(timestamp.IsSet());
  timestamp2 = timestamp;
  OLA_ASSERT_TRUE(timestamp2.IsSet());
  TimeStamp timestamp3(timestamp);
  OLA_ASSERT_TRUE(timestamp3.IsSet());
  OLA_ASSERT_EQ(timestamp, timestamp2);
  OLA_ASSERT_EQ(timestamp, timestamp3);

  // test equalities
  // Windows only seems to have ms resolution, to make the tests pass we need
  // to sleep here; XP only has 16ms resolution, so sleep a bit longer
  usleep(20000);
  clock.CurrentTime(&timestamp3);
  OLA_ASSERT_NE(timestamp3, timestamp);
  OLA_ASSERT_GT(timestamp3, timestamp);
  OLA_ASSERT_LT(timestamp, timestamp3);

  // test intervals
  TimeInterval interval = timestamp3 - timestamp;

  // test subtraction / addition
  timestamp2 = timestamp + interval;
  OLA_ASSERT_EQ(timestamp2, timestamp3);
  timestamp2 -= interval;
  OLA_ASSERT_EQ(timestamp, timestamp2);

  // test toString and AsInt
  TimeInterval one_point_five_seconds(1500000);
  OLA_ASSERT_EQ(string("1.500000"), one_point_five_seconds.ToString());
  OLA_ASSERT_EQ(static_cast<int64_t>(1500000),
                       one_point_five_seconds.AsInt());
  OLA_ASSERT_EQ(static_cast<int64_t>(1500),
                       one_point_five_seconds.InMilliSeconds());
}
Пример #10
0
/*
 * Test the TimeStamp class
 */
void ClockTest::testTimeStamp() {
  Clock clock;
  TimeStamp timestamp, timestamp2;
  CPPUNIT_ASSERT(!timestamp.IsSet());
  CPPUNIT_ASSERT(!timestamp2.IsSet());

  // test assignment & copy constructor
  clock.CurrentTime(&timestamp);
  CPPUNIT_ASSERT(timestamp.IsSet());
  timestamp2 = timestamp;
  CPPUNIT_ASSERT(timestamp2.IsSet());
  TimeStamp timestamp3(timestamp);
  CPPUNIT_ASSERT(timestamp3.IsSet());
  CPPUNIT_ASSERT_EQUAL(timestamp, timestamp2);
  CPPUNIT_ASSERT_EQUAL(timestamp, timestamp3);

  // test equalities
  // Windows only seems to have ms resolution, to make the tests pass we need
  // to sleep here
  usleep(1000);
  clock.CurrentTime(&timestamp3);
  CPPUNIT_ASSERT(timestamp3 != timestamp);
  CPPUNIT_ASSERT(timestamp3 > timestamp);
  CPPUNIT_ASSERT(timestamp < timestamp3);

  // test intervals
  TimeInterval interval = timestamp3 - timestamp;

  // test subtraction / addition
  timestamp2 = timestamp + interval;
  CPPUNIT_ASSERT_EQUAL(timestamp2, timestamp3);
  timestamp2 -= interval;
  CPPUNIT_ASSERT_EQUAL(timestamp, timestamp2);

  // test toString and AsInt
  TimeInterval one_point_five_seconds(1500000);
  CPPUNIT_ASSERT_EQUAL(string("1.500000"), one_point_five_seconds.ToString());
  CPPUNIT_ASSERT_EQUAL(static_cast<int64_t>(1500000),
                       one_point_five_seconds.AsInt());
  CPPUNIT_ASSERT_EQUAL(static_cast<int64_t>(1500),
                       one_point_five_seconds.InMilliSeconds());
}
Пример #11
0
/*
 * Run this thread
 */
void *OpenDmxThread::Run() {
  uint8_t buffer[DMX_UNIVERSE_SIZE+1];
  unsigned int length = DMX_UNIVERSE_SIZE;
  Clock clock;

  // should close other fd here

  // start code
  buffer[0] = 0x00;
  ola::io::Open(m_path, O_WRONLY, &m_fd);

  while (true) {
    {
      MutexLocker lock(&m_term_mutex);
      if (m_term)
        break;
    }

    if (m_fd == INVALID_FD) {
      TimeStamp wake_up;
      clock.CurrentTime(&wake_up);
      wake_up += TimeInterval(1, 0);

      // wait for either a signal that we should terminate, or ts seconds
      m_term_mutex.Lock();
      if (m_term)
        break;
      m_term_cond.TimedWait(&m_term_mutex, wake_up);
      m_term_mutex.Unlock();


      ola::io::Open(m_path, O_WRONLY, &m_fd);

    } else {
      length = DMX_UNIVERSE_SIZE;
      {
        MutexLocker locker(&m_mutex);
        m_buffer.Get(buffer + 1, &length);
      }

      if (write(m_fd, buffer, length + 1) < 0) {
        // if you unplug the dongle
        OLA_WARN << "Error writing to device: " << strerror(errno);

        if (close(m_fd) < 0)
          OLA_WARN << "Close failed " << strerror(errno);
        m_fd = INVALID_FD;
      }
    }
  }
  return NULL;
}
Пример #12
0
/*
 * Check for data loss.
 * TODO(simon): move to the ola server
 */
bool DmxMonitor::CheckDataLoss() {
  if (m_last_data.IsSet()) {
    TimeStamp now;
    Clock clock;
    clock.CurrentTime(&now);
    TimeInterval diff = now - m_last_data;
    if (diff > TimeInterval(2, 5000000)) {
      // loss of data
      DrawDataLossWindow();
    }
  }
  return true;
}
Пример #13
0
void InitRandom() {
  Clock clock;
  TimeStamp now;
  clock.CurrentTime(&now);

  uint64_t seed = (static_cast<uint64_t>(now.MicroSeconds()) << 32) +
                   static_cast<uint64_t>(getpid());
#ifdef HAVE_RANDOM
  generator_.seed(seed);
#elif defined(_WIN32)
  srand(seed);
#else
  srandom(seed);
#endif
}
Пример #14
0
void OpenLightingDevice::_OutTransferComplete() {
  TimeStamp now;
  Clock clock;
  clock.CurrentTime(&now);
  OLA_INFO << "Out Command completed in " << (now - m_out_sent_time)
           << ", status is "
           << LibUsbAdaptor::ErrorCodeToString(m_in_transfer->status);
  if (m_out_transfer->status == LIBUSB_TRANSFER_COMPLETED) {
    if (m_out_transfer->actual_length != m_out_transfer->length) {
      OLA_WARN << "Only sent " << m_out_transfer->actual_length << " / "
               << m_out_transfer->length << " bytes";
    }
  }

  MutexLocker locker(&m_mutex);
  m_out_in_progress = false;
  MaybeSendRequest();
}
Пример #15
0
/*
 * Run this thread
 */
void *KarateThread::Run() {
  bool write_success;
  Clock clock;

  KarateLight k(m_path);
  k.Init();

  while (true) {
    {
      MutexLocker lock(&m_term_mutex);
      if (m_term)
        break;
    }

    if (!k.IsActive()) {
      // try to reopen the device...
      TimeStamp wake_up;
      clock.CurrentTime(&wake_up);
      wake_up += TimeInterval(1, 0);

      // wait for either a signal that we should terminate, or ts seconds
      m_term_mutex.Lock();
      if (m_term)
        break;
      m_term_cond.TimedWait(&m_term_mutex, wake_up);
      m_term_mutex.Unlock();

      OLA_WARN << "Re-Initialising device " << m_path;
      k.Init();

    } else {
      {
        MutexLocker locker(&m_mutex);
        write_success = k.SetColors(m_buffer);
      }
      if (!write_success) {
        OLA_WARN << "Failed to write color data";
      }  else {
        usleep(20000);  // 50Hz
      }
    }  // port is okay
  }
  return NULL;
}