I just tested OpenBSD, and it seems that each *BSD has its own method to get a thread ID, with OpenBSD apparently having none ([1] "OpenBSD: not possible here, there is no way to get a TID") up to recently ([2] "The ps(1) program gains the tid formatting keyword. In conjunction with the -H option, thread ID is now included"). Thus the previous proposal, that used the FreeBSD way of getting a Thread ID, doesn't work.

This seems to be confirmed with the fact that the WINE implementation doesn't have any other BSDs besides FreeBSD (which we don't support) in its cross-plaform thread ID implementation [3].

With BSD support becoming a headache, and no official maintainer for the *BSD backends to help us out, along with the need to go to bugfix release soon, I propose dropping thread IDs for OpenBSD/NetBSD for the time being, and just return -1 there.

Now, if you think it's important to have a BSD tid implementation ASAP, you're of course very much invited to propose a patch, but please don't expect someone else will spend their limited time doing that work, or argue that the provision of thread IDs for Linux, Windows and OS X should be delayed because of *BSD, whereas, even without *BSD, at least 95% of our userbase is likely to benefit.

Thus, the attached is what I would currently go to release with, pending the possibility to identify whether we can/need to make the OS X thread ID coincide with X Code debug thread IDs.


Please note that I have also included a change that adds a header with a legend at the beginning of the log, which is very much RFC, i.e., I think it'll be helpful in case people wonder what the second column is for, as well as for making sure that the beginning on libusbx operations in a log that contains more than libusbx output is clearly highlighted, but if there are strong opinions against that header I don't have a problem removing it. I also reduced the default number of spaces before the timestamp, with the resulting output currently being as follows:

[timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
[ 0.000000] [00000b04] libusbx: debug [libusb_init]
[ 0.010000] [00000b04] libusbx: debug [init_polling] Will use CancelIoEx for I/O cancellation [ 0.022500] [00000b04] libusbx: debug [htab_create] using 1021 entries hash table
[ 0.025000] [00000b04] libusbx: debug [usbi_add_pollfd] add fd 3 events 1
[ 0.027500] [00000b04] libusbx: debug [libusb_init] created default context
[ 0.030000] [00000b04] libusbx: debug [libusb_get_device_list]
[ 0.022500] [000010e4] libusbx: debug [windows_clock_gettime_threaded] hires timer available (Frequency: 2083369 Hz)

Finally, you may also notice that the patch is using __linux__ or __APPLE__ defines, when we could use the OS_LINUX and OS_DARWIN as per in config.h. The main reason is that, as least for the BSDs, we're likely to have to split the OS_OPENBSD between __OpenBSD__ and __NetBSD__ anyway, and we may have to more OS splits in the future, so using the OS_* defines doesn't help us much.

Regards,

/Pete


[1] http://stackoverflow.com/questions/4867839/how-can-i-tell-if-pthread-self-is-the-main-first-thread-in-the-process
[2] http://www.openbsd.org/plus.html
[3] http://source.winehq.org/git/wine.git/?a=blob;f=dlls/ntdll/server.c#l943
>From 971f4eb540a414020f4ac9a3cf7b64827cc69ae6 Mon Sep 17 00:00:00 2001
From: Peter Stuge <pe...@stuge.se>
Date: Wed, 2 May 2012 17:04:00 +0000
Subject: [PATCH] Core: Add a timestamping and thread ID to logging

---
 configure.ac                |    1 +
 libusb/core.c               |   69 ++++++++++++++++++++++++++++++++++++++++++-
 libusb/libusbi.h            |   12 +++++++
 libusb/os/threads_posix.c   |   20 ++++++++++++
 libusb/os/threads_posix.h   |    2 +
 libusb/os/threads_windows.c |    4 ++
 libusb/os/threads_windows.h |    2 +
 7 files changed, 110 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index db5c534..792035f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -210,6 +210,7 @@ AM_CONDITIONAL([HAVE_SIGACTION], [test "x$have_sigaction" = 
"xyes"])
 
 # headers not available on all platforms but required on others
 AC_CHECK_HEADERS([sys/time.h])
+AC_CHECK_FUNCS(gettimeofday)
 
 AM_CFLAGS="-std=gnu99 -Wall -Wundef -Wunused -Wstrict-prototypes 
-Werror-implicit-function-declaration $nopointersign_cflags -Wshadow"
 
diff --git a/libusb/core.c b/libusb/core.c
index 1a95dd4..2c3de76 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -27,6 +27,10 @@
 #include <string.h>
 #include <sys/types.h>
 
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
 #include "libusbi.h"
 
 #if defined(OS_LINUX)
@@ -1665,11 +1669,59 @@ int API_EXPORTED libusb_has_capability(uint32_t 
capability)
        return 0;
 }
 
+/* this is defined in libusbi.h if needed */
+#ifdef LIBUSB_GETTIMEOFDAY_WIN32
+/*
+ * gettimeofday
+ * Implementation according to:
+ * The Open Group Base Specifications Issue 6
+ * IEEE Std 1003.1, 2004 Edition
+ */
+
+/*
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *  Contributed by:
+ *  Danny Smith <dannysm...@users.sourceforge.net>
+ */
+
+/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
+#define _W32_FT_OFFSET (116444736000000000)
+
+int usbi_gettimeofday(struct timeval *tp, void *tzp)
+ {
+  union {
+    unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */
+    FILETIME ft;
+  }  _now;
+
+  if(tp)
+    {
+      GetSystemTimeAsFileTime (&_now.ft);
+      tp->tv_usec=(long)((_now.ns100 / 10) % 1000000 );
+      tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000);
+    }
+  /* Always return 0 as per Open Group Base Specifications Issue 6.
+     Do not set errno on error.  */
+  return 0;
+}
+#endif
+
 void usbi_log_v(struct libusb_context *ctx, enum usbi_log_level level,
        const char *function, const char *format, va_list args)
 {
        FILE *stream = stdout;
        const char *prefix;
+       struct timeval now;
+       static struct timeval first = { 0, 0 };
 
 #ifndef ENABLE_DEBUG_LOGGING
        USBI_GET_CONTEXT(ctx);
@@ -1681,6 +1733,20 @@ void usbi_log_v(struct libusb_context *ctx, enum 
usbi_log_level level,
                return;
 #endif
 
+       usbi_gettimeofday(&now, NULL);
+       if (!first.tv_sec) {
+               first.tv_sec = now.tv_sec;
+               first.tv_usec = now.tv_usec;
+               fprintf(stream, "[timestamp] [threadID] facility level 
[function call] <message>\n");
+               fprintf(stream, 
"--------------------------------------------------------------------------------\n");
+       }
+       if (now.tv_usec < first.tv_usec) {
+               now.tv_sec--;
+               now.tv_usec += 1000000;
+       }
+       now.tv_sec -= first.tv_sec;
+       now.tv_usec -= first.tv_usec;
+
        switch (level) {
        case LOG_LEVEL_INFO:
                prefix = "info";
@@ -1703,7 +1769,8 @@ void usbi_log_v(struct libusb_context *ctx, enum 
usbi_log_level level,
                break;
        }
 
-       fprintf(stream, "libusb:%s [%s] ", prefix, function);
+       fprintf(stream, "[%2d.%06d] [%08x] libusbx: %s [%s] ",
+               (int)now.tv_sec, (int)now.tv_usec, usbi_get_tid(), prefix, 
function);
 
        vfprintf(stream, format, args);
 
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index 0aa6bf9..b8abab5 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -209,6 +209,18 @@ static inline void usbi_dbg(const char *format, ...)
 #include <os/poll_windows.h>
 #endif
 
+#if defined(OS_WINDOWS) && !defined(__GCC__)
+#undef HAVE_GETTIMEOFDAY
+int usbi_gettimeofday(struct timeval *tp, void *tzp);
+#define LIBUSB_GETTIMEOFDAY_WIN32
+#define HAVE_USBI_GETTIMEOFDAY
+#else
+#ifdef HAVE_GETTIMEOFDAY
+#define usbi_gettimeofday(tv, tz) gettimeofday((tv), (tz))
+#define HAVE_USBI_GETTIMEOFDAY
+#endif
+#endif
+
 extern struct libusb_context *usbi_default_context;
 
 struct libusb_context {
diff --git a/libusb/os/threads_posix.c b/libusb/os/threads_posix.c
index fb040ce..8e9b490 100644
--- a/libusb/os/threads_posix.c
+++ b/libusb/os/threads_posix.c
@@ -19,6 +19,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#if defined(__linux__)
+# include <unistd.h>
+# include <sys/syscall.h>
+#elif defined(__APPLE__)
+# include <mach/mach.h>
+#endif
+
 #ifdef _XOPEN_SOURCE
 # if _XOPEN_SOURCE < 500
 #  undef _XOPEN_SOURCE
@@ -53,3 +60,16 @@ finish:
 
        return err;
 }
+
+int usbi_get_tid(void)
+{
+       int ret = -1;
+#if defined(__linux__)
+       ret = syscall(SYS_gettid);
+#elif defined(__APPLE__)
+       ret = mach_thread_self();
+       mach_port_deallocate(mach_task_self(), ret);
+#endif
+/* TODO: OpenBSD and NetBSD thread ID support */
+       return ret;
+}
diff --git a/libusb/os/threads_posix.h b/libusb/os/threads_posix.h
index db4de28..5f66b6a 100644
--- a/libusb/os/threads_posix.h
+++ b/libusb/os/threads_posix.h
@@ -45,4 +45,6 @@
 
 extern int usbi_mutex_init_recursive(pthread_mutex_t *mutex, 
pthread_mutexattr_t *attr);
 
+int usbi_get_tid(void);
+
 #endif /* LIBUSB_THREADS_POSIX_H */
diff --git a/libusb/os/threads_windows.c b/libusb/os/threads_windows.c
index bb5c4c8..aceca36 100644
--- a/libusb/os/threads_windows.c
+++ b/libusb/os/threads_windows.c
@@ -204,3 +204,7 @@ int usbi_cond_timedwait(usbi_cond_t *cond,
 
        return usbi_cond_intwait(cond, mutex, millis);
 }
+
+int usbi_get_tid(void) {
+       return GetCurrentThreadId();
+}
diff --git a/libusb/os/threads_windows.h b/libusb/os/threads_windows.h
index 764a98c..3dbae02 100644
--- a/libusb/os/threads_windows.h
+++ b/libusb/os/threads_windows.h
@@ -82,4 +82,6 @@ int usbi_cond_timedwait(usbi_cond_t *cond,
 int usbi_cond_broadcast(usbi_cond_t *cond);
 int usbi_cond_signal(usbi_cond_t *cond);
 
+int usbi_get_tid(void);
+
 #endif /* LIBUSB_THREADS_WINDOWS_H */
-- 
1.7.9.msysgit.0

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusbx-devel mailing list
libusbx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusbx-devel

Reply via email to