summaryrefslogtreecommitdiffstats
path: root/services/common_time/diag_thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/common_time/diag_thread.cpp')
-rw-r--r--services/common_time/diag_thread.cpp323
1 files changed, 0 insertions, 323 deletions
diff --git a/services/common_time/diag_thread.cpp b/services/common_time/diag_thread.cpp
deleted file mode 100644
index 4cb9551..0000000
--- a/services/common_time/diag_thread.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "common_time"
-#include <utils/Log.h>
-
-#include <fcntl.h>
-#include <linux/in.h>
-#include <linux/tcp.h>
-#include <poll.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <utils/Errors.h>
-#include <utils/misc.h>
-
-#include <common_time/local_clock.h>
-
-#include "common_clock.h"
-#include "diag_thread.h"
-
-#define kMaxEvents 16
-#define kListenPort 9876
-
-static bool setNonblocking(int fd) {
- int flags = fcntl(fd, F_GETFL);
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
- ALOGE("Failed to set socket (%d) to non-blocking mode (errno %d)",
- fd, errno);
- return false;
- }
-
- return true;
-}
-
-static bool setNodelay(int fd) {
- int tmp = 1;
- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &tmp, sizeof(tmp)) < 0) {
- ALOGE("Failed to set socket (%d) to no-delay mode (errno %d)",
- fd, errno);
- return false;
- }
-
- return true;
-}
-
-namespace android {
-
-DiagThread::DiagThread(CommonClock* common_clock, LocalClock* local_clock) {
- common_clock_ = common_clock;
- local_clock_ = local_clock;
- listen_fd_ = -1;
- data_fd_ = -1;
- kernel_logID_basis_known_ = false;
- discipline_log_ID_ = 0;
-}
-
-DiagThread::~DiagThread() {
-}
-
-status_t DiagThread::startWorkThread() {
- status_t res;
- stopWorkThread();
- res = run("Diag");
-
- if (res != OK)
- ALOGE("Failed to start work thread (res = %d)", res);
-
- return res;
-}
-
-void DiagThread::stopWorkThread() {
- status_t res;
- res = requestExitAndWait(); // block until thread exit.
- if (res != OK)
- ALOGE("Failed to stop work thread (res = %d)", res);
-}
-
-bool DiagThread::openListenSocket() {
- bool ret = false;
- int flags;
- cleanupListenSocket();
-
- if ((listen_fd_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
- ALOGE("Socket failed.");
- goto bailout;
- }
-
- // Set non-blocking operation
- if (!setNonblocking(listen_fd_))
- goto bailout;
-
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons(kListenPort);
-
- if (bind(listen_fd_, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
- ALOGE("Bind failed.");
- goto bailout;
- }
-
- if (listen(listen_fd_, 1) < 0) {
- ALOGE("Listen failed.");
- goto bailout;
- }
-
- ret = true;
-bailout:
- if (!ret)
- cleanupListenSocket();
-
- return ret;
-}
-
-void DiagThread::cleanupListenSocket() {
- if (listen_fd_ >= 0) {
- int res;
-
- struct linger l;
- l.l_onoff = 1;
- l.l_linger = 0;
-
- setsockopt(listen_fd_, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
- shutdown(listen_fd_, SHUT_RDWR);
- close(listen_fd_);
- listen_fd_ = -1;
- }
-}
-
-void DiagThread::cleanupDataSocket() {
- if (data_fd_ >= 0) {
- int res;
-
- struct linger l;
- l.l_onoff = 1;
- l.l_linger = 0;
-
- setsockopt(data_fd_, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
- shutdown(data_fd_, SHUT_RDWR);
- close(data_fd_);
- data_fd_ = -1;
- }
-}
-
-void DiagThread::resetLogIDs() {
- // Drain and discard all of the events from the kernel
- struct local_time_debug_event events[kMaxEvents];
- while(local_clock_->getDebugLog(events, kMaxEvents) > 0)
- ;
-
- {
- Mutex::Autolock lock(&discipline_log_lock_);
- discipline_log_.clear();
- discipline_log_ID_ = 0;
- }
-
- kernel_logID_basis_known_ = false;
-}
-
-void DiagThread::pushDisciplineEvent(int64_t observed_local_time,
- int64_t observed_common_time,
- int64_t nominal_common_time,
- int32_t total_correction,
- int32_t rtt) {
- Mutex::Autolock lock(&discipline_log_lock_);
-
- DisciplineEventRecord evt;
-
- evt.event_id = discipline_log_ID_++;
-
- evt.action_local_time = local_clock_->getLocalTime();
- common_clock_->localToCommon(evt.action_local_time,
- &evt.action_common_time);
-
- evt.observed_local_time = observed_local_time;
- evt.observed_common_time = observed_common_time;
- evt.nominal_common_time = nominal_common_time;
- evt.total_correction = total_correction;
- evt.rtt = rtt;
-
- discipline_log_.push_back(evt);
- while (discipline_log_.size() > kMaxDisciplineLogSize)
- discipline_log_.erase(discipline_log_.begin());
-}
-
-bool DiagThread::threadLoop() {
- struct pollfd poll_fds[1];
-
- if (!openListenSocket()) {
- ALOGE("Failed to open listen socket");
- goto bailout;
- }
-
- while (!exitPending()) {
- memset(&poll_fds, 0, sizeof(poll_fds));
-
- if (data_fd_ < 0) {
- poll_fds[0].fd = listen_fd_;
- poll_fds[0].events = POLLIN;
- } else {
- poll_fds[0].fd = data_fd_;
- poll_fds[0].events = POLLRDHUP | POLLIN;
- }
-
- int poll_res = poll(poll_fds, NELEM(poll_fds), 50);
- if (poll_res < 0) {
- ALOGE("Fatal error (%d,%d) while waiting on events",
- poll_res, errno);
- goto bailout;
- }
-
- if (exitPending())
- break;
-
- if (poll_fds[0].revents) {
- if (poll_fds[0].fd == listen_fd_) {
- data_fd_ = accept(listen_fd_, NULL, NULL);
-
- if (data_fd_ < 0) {
- ALOGW("Failed accept on socket %d with err %d",
- listen_fd_, errno);
- } else {
- if (!setNonblocking(data_fd_))
- cleanupDataSocket();
- if (!setNodelay(data_fd_))
- cleanupDataSocket();
- }
- } else
- if (poll_fds[0].fd == data_fd_) {
- if (poll_fds[0].revents & POLLRDHUP) {
- // Connection hung up; time to clean up.
- cleanupDataSocket();
- } else
- if (poll_fds[0].revents & POLLIN) {
- uint8_t cmd;
- if (read(data_fd_, &cmd, sizeof(cmd)) > 0) {
- switch(cmd) {
- case 'r':
- case 'R':
- resetLogIDs();
- break;
- }
- }
- }
- }
- }
-
- struct local_time_debug_event events[kMaxEvents];
- int amt = local_clock_->getDebugLog(events, kMaxEvents);
-
- if (amt > 0) {
- for (int i = 0; i < amt; i++) {
- struct local_time_debug_event& e = events[i];
-
- if (!kernel_logID_basis_known_) {
- kernel_logID_basis_ = e.local_timesync_event_id;
- kernel_logID_basis_known_ = true;
- }
-
- char buf[1024];
- int64_t common_time;
- status_t res = common_clock_->localToCommon(e.local_time,
- &common_time);
- snprintf(buf, sizeof(buf), "E,%lld,%lld,%lld,%d\n",
- e.local_timesync_event_id - kernel_logID_basis_,
- e.local_time,
- common_time,
- (OK == res) ? 1 : 0);
- buf[sizeof(buf) - 1] = 0;
-
- if (data_fd_ >= 0)
- write(data_fd_, buf, strlen(buf));
- }
- }
-
- { // scope for autolock pattern
- Mutex::Autolock lock(&discipline_log_lock_);
-
- while (discipline_log_.size() > 0) {
- char buf[1024];
- DisciplineEventRecord& e = *discipline_log_.begin();
- snprintf(buf, sizeof(buf),
- "D,%lld,%lld,%lld,%lld,%lld,%lld,%d,%d\n",
- e.event_id,
- e.action_local_time,
- e.action_common_time,
- e.observed_local_time,
- e.observed_common_time,
- e.nominal_common_time,
- e.total_correction,
- e.rtt);
- buf[sizeof(buf) - 1] = 0;
-
- if (data_fd_ >= 0)
- write(data_fd_, buf, strlen(buf));
-
- discipline_log_.erase(discipline_log_.begin());
- }
- }
- }
-
-bailout:
- cleanupDataSocket();
- cleanupListenSocket();
- return false;
-}
-
-} // namespace android