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; }
/** * test the clock */ void ClockTest::testClock() { Clock clock; TimeStamp first; clock.CurrentTime(&first); sleep(1); TimeStamp second; clock.CurrentTime(&second); CPPUNIT_ASSERT(first < second); }
/** * 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); }
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; }
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(); } }
/* * 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(); }
/** * 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"); }
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; }
/* * 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(×tamp); 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(×tamp3); 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()); }
/* * 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(×tamp); 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(×tamp3); 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()); }
/* * 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; }
/* * 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; }
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 }
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(); }
/* * 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; }