Merge "adb: add unit test for fdevent."
diff --git a/adb/Android.mk b/adb/Android.mk
index 88e0418..41016ee 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -198,7 +198,6 @@
ifeq ($(HOST_OS),linux)
LOCAL_LDLIBS += -lrt -ldl -lpthread
- LOCAL_CFLAGS += -DWORKAROUND_BUG6558362
endif
ifeq ($(HOST_OS),darwin)
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 49cf123..eb01da8 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -244,11 +244,11 @@
//Close the associated usb
t->online = 0;
- // This is necessary to avoid a race condition that occured when a transport closes
+ // This is necessary to avoid a race condition that occurred when a transport closes
// while a client socket is still active.
close_all_sockets(t);
- run_transport_disconnects(t);
+ t->RunDisconnects();
}
#if DEBUG_PACKETS
@@ -670,10 +670,12 @@
}
static unsigned __stdcall _redirect_stdout_thread(HANDLE h) {
+ adb_thread_setname("stdout redirect");
return _redirect_pipe_thread(h, STD_OUTPUT_HANDLE);
}
static unsigned __stdcall _redirect_stderr_thread(HANDLE h) {
+ adb_thread_setname("stderr redirect");
return _redirect_pipe_thread(h, STD_ERROR_HANDLE);
}
diff --git a/adb/adb.h b/adb/adb.h
index 6855f3b..8b3359e 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -157,8 +157,6 @@
{
void (*func)(void* opaque, atransport* t);
void* opaque;
- adisconnect* next;
- adisconnect* prev;
};
@@ -229,8 +227,8 @@
void connect_to_remote(asocket *s, const char *destination);
void connect_to_smartsocket(asocket *s);
-void fatal(const char *fmt, ...);
-void fatal_errno(const char *fmt, ...);
+void fatal(const char *fmt, ...) __attribute__((noreturn));
+void fatal_errno(const char *fmt, ...) __attribute__((noreturn));
void handle_packet(apacket *p, atransport *t);
diff --git a/adb/adb_auth_client.cpp b/adb/adb_auth_client.cpp
index be28202..c3af024 100644
--- a/adb/adb_auth_client.cpp
+++ b/adb/adb_auth_client.cpp
@@ -47,7 +47,7 @@
static int framework_fd = -1;
static void usb_disconnected(void* unused, atransport* t);
-static struct adisconnect usb_disconnect = { usb_disconnected, 0, 0, 0 };
+static struct adisconnect usb_disconnect = { usb_disconnected, nullptr};
static atransport* usb_transport;
static bool needs_retry = false;
@@ -164,7 +164,6 @@
static void usb_disconnected(void* unused, atransport* t)
{
D("USB disconnect\n");
- remove_transport_disconnect(usb_transport, &usb_disconnect);
usb_transport = NULL;
needs_retry = false;
}
@@ -196,7 +195,7 @@
if (!usb_transport) {
usb_transport = t;
- add_transport_disconnect(t, &usb_disconnect);
+ t->AddDisconnect(&usb_disconnect);
}
if (framework_fd < 0) {
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index 8fb2d19..d5b1fd5 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -101,13 +101,15 @@
free((char*)l->connect_to);
if (l->transport) {
- remove_transport_disconnect(l->transport, &l->disconnect);
+ l->transport->RemoveDisconnect(&l->disconnect);
}
free(l);
}
-static void listener_disconnect(void* listener, atransport* t) {
- free_listener(reinterpret_cast<alistener*>(listener));
+static void listener_disconnect(void* arg, atransport*) {
+ alistener* listener = reinterpret_cast<alistener*>(arg);
+ listener->transport = nullptr;
+ free_listener(listener);
}
static int local_name_to_fd(const char* name, std::string* error) {
@@ -159,7 +161,7 @@
for (l = listener_list.next; l != &listener_list; l = l->next) {
if (!strcmp(local_name, l->local_name)) {
- listener_disconnect(l, l->transport);
+ free_listener(l);
return INSTALL_STATUS_OK;
}
}
@@ -174,7 +176,7 @@
// Never remove smart sockets.
if (l->connect_to[0] == '*')
continue;
- listener_disconnect(l, l->transport);
+ free_listener(l);
}
}
@@ -209,9 +211,9 @@
free((void*) l->connect_to);
l->connect_to = cto;
if (l->transport != transport) {
- remove_transport_disconnect(l->transport, &l->disconnect);
+ l->transport->RemoveDisconnect(&l->disconnect);
l->transport = transport;
- add_transport_disconnect(l->transport, &l->disconnect);
+ l->transport->AddDisconnect(&l->disconnect);
}
return INSTALL_STATUS_OK;
}
@@ -260,7 +262,7 @@
if (transport) {
listener->disconnect.opaque = listener;
listener->disconnect.func = listener_disconnect;
- add_transport_disconnect(transport, &listener->disconnect);
+ transport->AddDisconnect(&listener->disconnect);
}
return INSTALL_STATUS_OK;
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index f6ddeb4..8d644d9 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -36,42 +36,6 @@
#include "adb_listeners.h"
#include "transport.h"
-#if defined(WORKAROUND_BUG6558362) && defined(__linux__)
-static const bool kWorkaroundBug6558362 = true;
-#else
-static const bool kWorkaroundBug6558362 = false;
-#endif
-
-static void adb_workaround_affinity(void) {
-#if defined(__linux__)
- const char affinity_env[] = "ADB_CPU_AFFINITY_BUG6558362";
- const char* cpunum_str = getenv(affinity_env);
- if (cpunum_str == nullptr || *cpunum_str == '\0') {
- return;
- }
-
- char* strtol_res;
- int cpu_num = strtol(cpunum_str, &strtol_res, 0);
- if (*strtol_res != '\0') {
- fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str,
- affinity_env);
- }
-
- cpu_set_t cpu_set;
- sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
- D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
-
- CPU_ZERO(&cpu_set);
- CPU_SET(cpu_num, &cpu_set);
- sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
-
- sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
- D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
-#else
- // No workaround was ever implemented for the other platforms.
-#endif
-}
-
#if defined(_WIN32)
static const char kNullFileName[] = "NUL";
@@ -157,10 +121,6 @@
init_transport_registration();
- if (kWorkaroundBug6558362 && is_daemon) {
- adb_workaround_affinity();
- }
-
usb_init();
local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
adb_auth_init();
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index b92757f..6325e64 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -374,6 +374,8 @@
fdi = fds[1];
free(fds);
+ adb_thread_setname("stdin reader");
+
while (true) {
/* fdi is really the client's stdin, so use read, not adb_read here */
D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi);
diff --git a/adb/services.cpp b/adb/services.cpp
index c8c2d54..4606804 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -67,6 +67,7 @@
void *service_bootstrap_func(void *x)
{
stinfo* sti = reinterpret_cast<stinfo*>(x);
+ adb_thread_setname(android::base::StringPrintf("service %d", sti->fd));
sti->func(sti->fd, sti->cookie);
free(sti);
return 0;
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index a58a762..5918a94 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -111,6 +111,13 @@
return (tid != static_cast<uintptr_t>(-1L));
}
+static __inline__ int adb_thread_setname(const std::string& name) {
+ // TODO: See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx for how to set
+ // the thread name in Windows. Unfortunately, it only works during debugging, but
+ // our build process doesn't generate PDB files needed for debugging.
+ return 0;
+}
+
static __inline__ unsigned long adb_thread_id()
{
return GetCurrentThreadId();
@@ -617,7 +624,26 @@
return (errno == 0);
}
-static __inline__ int adb_socket_setbufsize( int fd, int bufsize )
+static __inline__ int adb_thread_setname(const std::string& name) {
+#ifdef __APPLE__
+ return pthread_setname_np(name.c_str());
+#else
+ const char *s = name.c_str();
+
+ // pthread_setname_np fails rather than truncating long strings.
+ const int max_task_comm_len = 16; // including the null terminator
+ if (name.length() > (max_task_comm_len - 1)) {
+ char buf[max_task_comm_len];
+ strncpy(buf, name.c_str(), sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+ s = buf;
+ }
+
+ return pthread_setname_np(pthread_self(), s) ;
+#endif
+}
+
+static __inline__ int adb_socket_setbufsize(int fd, int bufsize )
{
int opt = bufsize;
return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 4dc5e4a..5a962de 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -42,36 +42,6 @@
ADB_MUTEX_DEFINE( transport_lock );
-// Each atransport contains a list of adisconnects (t->disconnects).
-// An adisconnect contains a link to the next/prev adisconnect, a function
-// pointer to a disconnect callback which takes a void* piece of user data and
-// the atransport, and some user data for the callback (helpfully named
-// "opaque").
-//
-// The list is circular. New items are added to the entry member of the list
-// (t->disconnects) by add_transport_disconnect.
-//
-// run_transport_disconnects invokes each function in the list.
-//
-// Gotchas:
-// * run_transport_disconnects assumes that t->disconnects is non-null, so
-// this can't be run on a zeroed atransport.
-// * The callbacks in this list are not removed when called, and this function
-// is not guarded against running more than once. As such, ensure that this
-// function is not called multiple times on the same atransport.
-// TODO(danalbert): Just fix this so that it is guarded once you have tests.
-void run_transport_disconnects(atransport* t)
-{
- adisconnect* dis = t->disconnects.next;
-
- D("%s: run_transport_disconnects\n", t->serial);
- while (dis != &t->disconnects) {
- adisconnect* next = dis->next;
- dis->func( dis->opaque, t );
- dis = next;
- }
-}
-
static void dump_packet(const char* name, const char* func, apacket* p) {
unsigned command = p->msg.command;
int len = p->msg.data_length;
@@ -205,25 +175,27 @@
}
}
-/* The transport is opened by transport_register_func before
-** the input and output threads are started.
-**
-** The output thread issues a SYNC(1, token) message to let
-** the input thread know to start things up. In the event
-** of transport IO failure, the output thread will post a
-** SYNC(0,0) message to ensure shutdown.
-**
-** The transport will not actually be closed until both
-** threads exit, but the input thread will kick the transport
-** on its way out to disconnect the underlying device.
-*/
-
-static void *output_thread(void *_t)
+// The transport is opened by transport_register_func before
+// the read_transport and write_transport threads are started.
+//
+// The read_transport thread issues a SYNC(1, token) message to let
+// the write_transport thread know to start things up. In the event
+// of transport IO failure, the read_transport thread will post a
+// SYNC(0,0) message to ensure shutdown.
+//
+// The transport will not actually be closed until both threads exit, but the threads
+// will kick the transport on their way out to disconnect the underlying device.
+//
+// read_transport thread reads data from a transport (representing a usb/tcp connection),
+// and makes the main thread call handle_packet().
+static void *read_transport_thread(void *_t)
{
atransport *t = reinterpret_cast<atransport*>(_t);
apacket *p;
- D("%s: starting transport output thread on fd %d, SYNC online (%d)\n",
+ adb_thread_setname(android::base::StringPrintf("<-%s",
+ (t->serial != nullptr ? t->serial : "transport")));
+ D("%s: starting read_transport thread on fd %d, SYNC online (%d)\n",
t->serial, t->fd, t->sync_token + 1);
p = get_apacket();
p->msg.command = A_SYNC;
@@ -267,19 +239,23 @@
}
oops:
- D("%s: transport output thread is exiting\n", t->serial);
+ D("%s: read_transport thread is exiting\n", t->serial);
kick_transport(t);
transport_unref(t);
return 0;
}
-static void *input_thread(void *_t)
+// write_transport thread gets packets sent by the main thread (through send_packet()),
+// and writes to a transport (representing a usb/tcp connection).
+static void *write_transport_thread(void *_t)
{
atransport *t = reinterpret_cast<atransport*>(_t);
apacket *p;
int active = 0;
- D("%s: starting transport input thread, reading from fd %d\n",
+ adb_thread_setname(android::base::StringPrintf("->%s",
+ (t->serial != nullptr ? t->serial : "transport")));
+ D("%s: starting write_transport thread, reading from fd %d\n",
t->serial, t->fd);
for(;;){
@@ -314,7 +290,7 @@
put_apacket(p);
}
- D("%s: transport input thread is exiting, fd %d\n", t->serial, t->fd);
+ D("%s: write_transport thread is exiting, fd %d\n", t->serial, t->fd);
kick_transport(t);
transport_unref(t);
return 0;
@@ -574,12 +550,12 @@
fdevent_set(&(t->transport_fde), FDE_READ);
- if (!adb_thread_create(input_thread, t)) {
- fatal_errno("cannot create input thread");
+ if (!adb_thread_create(write_transport_thread, t)) {
+ fatal_errno("cannot create write_transport thread");
}
- if (!adb_thread_create(output_thread, t)) {
- fatal_errno("cannot create output thread");
+ if (!adb_thread_create(read_transport_thread, t)) {
+ fatal_errno("cannot create read_transport thread");
}
}
@@ -588,8 +564,6 @@
transport_list.push_front(t);
adb_mutex_unlock(&transport_lock);
- t->disconnects.next = t->disconnects.prev = &t->disconnects;
-
update_transports();
}
@@ -653,23 +627,6 @@
adb_mutex_unlock(&transport_lock);
}
-void add_transport_disconnect(atransport* t, adisconnect* dis)
-{
- adb_mutex_lock(&transport_lock);
- dis->next = &t->disconnects;
- dis->prev = dis->next->prev;
- dis->prev->next = dis;
- dis->next->prev = dis;
- adb_mutex_unlock(&transport_lock);
-}
-
-void remove_transport_disconnect(atransport* t, adisconnect* dis)
-{
- dis->prev->next = dis->next;
- dis->next->prev = dis->prev;
- dis->next = dis->prev = dis;
-}
-
static int qual_match(const char *to_test,
const char *prefix, const char *qual, bool sanitize_qual)
{
@@ -844,6 +801,21 @@
return has_feature(feature) && supported_features().count(feature) > 0;
}
+void atransport::AddDisconnect(adisconnect* disconnect) {
+ disconnects_.push_back(disconnect);
+}
+
+void atransport::RemoveDisconnect(adisconnect* disconnect) {
+ disconnects_.remove(disconnect);
+}
+
+void atransport::RunDisconnects() {
+ for (auto& disconnect : disconnects_) {
+ disconnect->func(disconnect->opaque, this);
+ }
+ disconnects_.clear();
+}
+
#if ADB_HOST
static void append_transport_info(std::string* result, const char* key,
@@ -969,9 +941,9 @@
for (auto& t : transport_list) {
// TCP/IP devices have adb_port == 0.
if (t->type == kTransportLocal && t->adb_port == 0) {
- // Kicking breaks the output thread of this transport out of any read, then
- // the output thread will notify the main thread to make this transport
- // offline. Then the main thread will notify the input thread to exit.
+ // Kicking breaks the read_transport thread of this transport out of any read, then
+ // the read_transport thread will notify the main thread to make this transport
+ // offline. Then the main thread will notify the write_transport thread to exit.
// Finally, this transport will be closed and freed in the main thread.
kick_transport_locked(t);
}
diff --git a/adb/transport.h b/adb/transport.h
index abb26a7..3b56c55 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -19,6 +19,7 @@
#include <sys/types.h>
+#include <list>
#include <string>
#include <unordered_set>
@@ -71,9 +72,6 @@
int adb_port = -1; // Use for emulators (local transport)
bool kicked = false;
- // A list of adisconnect callbacks called when the transport is kicked.
- adisconnect disconnects = {};
-
void* key = nullptr;
unsigned char token[TOKEN_SIZE] = {};
fdevent auth_fde;
@@ -96,6 +94,10 @@
// feature.
bool CanUseFeature(const std::string& feature) const;
+ void AddDisconnect(adisconnect* disconnect);
+ void RemoveDisconnect(adisconnect* disconnect);
+ void RunDisconnects();
+
private:
// A set of features transmitted in the banner with the initial connection.
// This is stored in the banner as 'features=feature0,feature1,etc'.
@@ -103,6 +105,9 @@
int protocol_version;
size_t max_payload;
+ // A list of adisconnect callbacks called when the transport is kicked.
+ std::list<adisconnect*> disconnects_;
+
DISALLOW_COPY_AND_ASSIGN(atransport);
};
@@ -114,10 +119,7 @@
*/
atransport* acquire_one_transport(ConnectionState state, TransportType type,
const char* serial, std::string* error_out);
-void add_transport_disconnect(atransport* t, adisconnect* dis);
-void remove_transport_disconnect(atransport* t, adisconnect* dis);
void kick_transport(atransport* t);
-void run_transport_disconnects(atransport* t);
void update_transports(void);
void init_transport_registration(void);
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 6a17497..6821cfc 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -123,6 +123,7 @@
#if ADB_HOST
static void *client_socket_thread(void *x)
{
+ adb_thread_setname("client_socket_thread");
D("transport: client_socket_thread() starting\n");
while (true) {
int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
@@ -146,6 +147,7 @@
socklen_t alen;
int port = (int) (uintptr_t) arg;
+ adb_thread_setname("server socket");
D("transport: server_socket_thread() starting\n");
serverfd = -1;
for(;;) {
@@ -231,6 +233,7 @@
char tmp[256];
char con_name[32];
+ adb_thread_setname("qemu socket");
D("transport: qemu_socket_thread() starting\n");
/* adb QEMUD service connection request. */
diff --git a/adb/transport_test.cpp b/adb/transport_test.cpp
index 743d97d..10872ac 100644
--- a/adb/transport_test.cpp
+++ b/adb/transport_test.cpp
@@ -51,9 +51,6 @@
EXPECT_EQ(adb_port, rhs.adb_port);
EXPECT_EQ(kicked, rhs.kicked);
- EXPECT_EQ(
- 0, memcmp(&disconnects, &rhs.disconnects, sizeof(adisconnect)));
-
EXPECT_EQ(key, rhs.key);
EXPECT_EQ(0, memcmp(token, rhs.token, TOKEN_SIZE));
EXPECT_EQ(0, memcmp(&auth_fde, &rhs.auth_fde, sizeof(fdevent)));
@@ -118,12 +115,33 @@
ASSERT_EQ(expected, t);
}
-// Disabled because the function currently segfaults for a zeroed atransport. I
-// want to make sure I understand how this is working at all before I try fixing
-// that.
-TEST(transport, DISABLED_run_transport_disconnects_zeroed_atransport) {
+static void DisconnectFunc(void* arg, atransport*) {
+ int* count = reinterpret_cast<int*>(arg);
+ ++*count;
+}
+
+TEST(transport, RunDisconnects) {
atransport t;
- run_transport_disconnects(&t);
+ // RunDisconnects() can be called with an empty atransport.
+ t.RunDisconnects();
+
+ int count = 0;
+ adisconnect disconnect;
+ disconnect.func = DisconnectFunc;
+ disconnect.opaque = &count;
+ t.AddDisconnect(&disconnect);
+ t.RunDisconnects();
+ ASSERT_EQ(1, count);
+
+ // disconnect should have been removed automatically.
+ t.RunDisconnects();
+ ASSERT_EQ(1, count);
+
+ count = 0;
+ t.AddDisconnect(&disconnect);
+ t.RemoveDisconnect(&disconnect);
+ t.RunDisconnects();
+ ASSERT_EQ(0, count);
}
TEST(transport, add_feature) {
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index dd22712..65b8735 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -572,6 +572,7 @@
}
static void* device_poll_thread(void* unused) {
+ adb_thread_setname("device poll");
D("Created device thread\n");
while (true) {
// TODO: Use inotify.
@@ -591,6 +592,6 @@
sigaction(SIGALRM, &actions, nullptr);
if (!adb_thread_create(device_poll_thread, nullptr)) {
- fatal_errno("cannot create input thread");
+ fatal_errno("cannot create device_poll thread");
}
}
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index dc44f16..e1d7594 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -209,6 +209,8 @@
struct usb_handle *usb = (struct usb_handle *)x;
int fd;
+ adb_thread_setname("usb open");
+
while (true) {
// wait until the USB device needs opening
adb_mutex_lock(&usb->lock);
@@ -403,6 +405,8 @@
{
struct usb_handle *usb = (struct usb_handle *)x;
+ adb_thread_setname("usb ffs open");
+
while (true) {
// wait until the USB device needs opening
adb_mutex_lock(&usb->lock);
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 0ce85f3..8037606 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -403,6 +403,7 @@
void* RunLoopThread(void* unused)
{
+ adb_thread_setname("RunLoop");
InitUSB();
currentRunLoop = CFRunLoopGetCurrent();
@@ -438,7 +439,7 @@
adb_cond_init(&start_cond, NULL);
if (!adb_thread_create(RunLoopThread, nullptr)) {
- fatal_errno("cannot create input thread");
+ fatal_errno("cannot create RunLoop thread");
}
// Wait for initialization to finish
diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp
index b8cc5cf..ab36475 100644
--- a/adb/usb_windows.cpp
+++ b/adb/usb_windows.cpp
@@ -171,6 +171,7 @@
}
void* device_poll_thread(void* unused) {
+ adb_thread_setname("Device Poll");
D("Created device thread\n");
while(1) {
@@ -208,6 +209,7 @@
// of a developer's interactive session, a window message pump is more
// appropriate.
D("Created power notification thread\n");
+ adb_thread_setname("Power Notifier");
// Window class names are process specific.
static const WCHAR kPowerNotificationWindowClassName[] =
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index c609870..a93369e 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -413,6 +413,12 @@
it = f->second;
}
}
+ static const timespec too_old = {
+ EXPIRE_HOUR_THRESHOLD * 60 * 60, 0
+ };
+ LogBufferElementCollection::iterator lastt;
+ lastt = mLogElements.end();
+ --lastt;
LogBufferElementLast last;
while (it != mLogElements.end()) {
LogBufferElement *e = *it;
@@ -464,6 +470,11 @@
continue;
}
+ if ((e->getRealTime() < ((*lastt)->getRealTime() - too_old))
+ || (e->getRealTime() > (*lastt)->getRealTime())) {
+ break;
+ }
+
// unmerged drop message
if (dropped) {
last.add(e);
@@ -477,18 +488,6 @@
}
if (e->getUid() != worst) {
- if (leading) {
- static const timespec too_old = {
- EXPIRE_HOUR_THRESHOLD * 60 * 60, 0
- };
- LogBufferElementCollection::iterator last;
- last = mLogElements.end();
- --last;
- if ((e->getRealTime() < ((*last)->getRealTime() - too_old))
- || (e->getRealTime() > (*last)->getRealTime())) {
- break;
- }
- }
leading = false;
last.clear(e);
++it;
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 2ae7ed2..24f702f 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -53,7 +53,6 @@
start \
stop \
top \
- uptime \
ALL_TOOLS = $(BSD_TOOLS) $(OUR_TOOLS)
diff --git a/toolbox/uptime.c b/toolbox/uptime.c
deleted file mode 100644
index ebfb15e..0000000
--- a/toolbox/uptime.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2010, The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-static void format_time(int time, char* buffer) {
- int seconds = time % 60;
- time /= 60;
- int minutes = time % 60;
- time /= 60;
- int hours = time % 24;
- int days = time / 24;
-
- if (days > 0) {
- sprintf(buffer, "%d day%s, %02d:%02d:%02d", days, (days == 1) ? "" : "s", hours, minutes, seconds);
- } else {
- sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds);
- }
-}
-
-int uptime_main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) {
- FILE* file = fopen("/proc/uptime", "r");
- if (!file) {
- fprintf(stderr, "Could not open /proc/uptime\n");
- return -1;
- }
- float idle_time;
- if (fscanf(file, "%*f %f", &idle_time) != 1) {
- fprintf(stderr, "Could not parse /proc/uptime\n");
- fclose(file);
- return -1;
- }
- fclose(file);
-
- struct timespec up_timespec;
- if (clock_gettime(CLOCK_MONOTONIC, &up_timespec) == -1) {
- fprintf(stderr, "Could not get monotonic time: %s\n", strerror(errno));
- return -1;
- }
- float up_time = up_timespec.tv_sec + up_timespec.tv_nsec / 1e9;
-
- struct timespec elapsed_timespec;
- if (clock_gettime(CLOCK_BOOTTIME, &elapsed_timespec) == -1) {
- fprintf(stderr, "Could not get boot time: %s\n", strerror(errno));
- return -1;
- }
- int elapsed = elapsed_timespec.tv_sec;
-
- char up_string[100], idle_string[100], sleep_string[100];
- format_time(elapsed, up_string);
- format_time((int)idle_time, idle_string);
- format_time((int)(elapsed - up_time), sleep_string);
- printf("up time: %s, idle time: %s, sleep time: %s\n", up_string, idle_string, sleep_string);
-
- return 0;
-}