2007-01-07 Matthias Clasen <mclasen@redhat.com>
+ Don't link glib against libpthread. (#393812)
+
+ * configure.in: Link gthread against librt, not glib itself.
+
+ * glib/gthread.h:
+ * glib/gthread.c: Add a new thread function, gettime.
+
+ * glib/gtimer.c: Use gettime instead of directly working with
+ the various system interfaces.
+
+ * gthread/gthread-impl.c:
+ * gthread/gthread-posix.c:
+ * gthread/gthread-win32.c: Implement gettime.
+
+2007-01-07 Matthias Clasen <mclasen@redhat.com>
+
* m4macros/glib-2.0.m4: Use PKG_PROG_PKG_CONFIG. (#392636,
Yevgen Muntyan)
AC_CHECK_FUNCS(clock_gettime, [], [
AC_CHECK_LIB(rt, clock_gettime, [
AC_DEFINE(HAVE_CLOCK_GETTIME, 1)
- LIBS="$LIBS -lrt"
+ G_THREAD_LIBS="$G_THREAD_LIBS -lrt"
])
])
#include <unistd.h>
#endif
+#ifndef G_OS_WIN32
+#include <sys/time.h>
+#include <time.h>
+#endif /* G_OS_WIN32 */
+
#include <string.h>
#include "glib.h"
GDestroyNotify destroy;
};
-static void g_thread_cleanup (gpointer data);
-static void g_thread_fail (void);
+static void g_thread_cleanup (gpointer data);
+static void g_thread_fail (void);
+static guint64 gettime (void);
/* Global variables */
NULL, /* thread_join */
NULL, /* thread_exit */
NULL, /* thread_set_priority */
- NULL /* thread_self */
+ NULL, /* thread_self */
+ NULL, /* thread_equal */
+ gettime /* gettime */
};
/* Local data */
g_error ("The thread system is not yet initialized.");
}
+static guint64
+gettime (void)
+{
+#ifdef G_OS_WIN32
+ guint64 v;
+
+ GetSystemTimeAsFileTime ((FILETIME *)&v);
+
+ return v;
+#else
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+
+ return tv.tv_sec * 1e9 + tv.tv_usec * 1000;
+#endif
+}
+
static gpointer
g_thread_create_proxy (gpointer data)
{
void (*thread_self) (gpointer thread);
gboolean (*thread_equal) (gpointer thread1,
gpointer thread2);
+ guint64 (*gettime) (void);
};
GLIB_VAR GThreadFunctions g_thread_functions_for_glib_use;
#endif /* G_OS_WIN32 */
#include "glib.h"
+#include "gthread.h"
#include "galias.h"
#define G_NSEC_PER_SEC 1000000000
-#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_MONOTONIC_CLOCK)
-#define USE_CLOCK_GETTIME 1
-#endif
+#define GETTIME(v) (v = G_THREAD_UF (gettime, ()))
struct _GTimer
{
-#ifdef G_OS_WIN32
guint64 start;
guint64 end;
-#elif USE_CLOCK_GETTIME
- struct timespec start;
- struct timespec end;
- gint clock;
-#else /* uses gettimeofday */
- struct timeval start;
- struct timeval end;
-#endif
guint active : 1;
};
-#ifdef G_OS_WIN32
-# define GETTIME(v) \
- GetSystemTimeAsFileTime ((FILETIME *)&v)
-#elif USE_CLOCK_GETTIME
-# define GETTIME(v) \
- clock_gettime (posix_clock, &v)
-#else
-# define GETTIME(v) \
- gettimeofday (&v, NULL)
-#endif
-
-#ifdef USE_CLOCK_GETTIME
-static gint posix_clock = 0;
-
-static void
-init_posix_clock (void)
-{
- static gboolean initialized = FALSE;
-
- if (!initialized)
- {
- initialized = TRUE;
- if (sysconf (_SC_MONOTONIC_CLOCK) >= 0)
- posix_clock = CLOCK_MONOTONIC;
- else
- posix_clock = CLOCK_REALTIME;
- }
-}
-#endif
GTimer*
g_timer_new (void)
timer = g_new (GTimer, 1);
timer->active = TRUE;
-#ifdef USE_CLOCK_GETTIME
- init_posix_clock ();
-#endif
-
GETTIME (timer->start);
return timer;
timer->active = FALSE;
- GETTIME(timer->end);
+ GETTIME (timer->end);
}
void
void
g_timer_continue (GTimer *timer)
{
-#ifdef G_OS_WIN32
guint64 elapsed;
-#elif USE_CLOCK_GETTIME
- struct timespec elapsed;
-#else
- struct timeval elapsed;
-#endif
g_return_if_fail (timer != NULL);
g_return_if_fail (timer->active == FALSE);
* elapsed interval.
*/
-#ifdef G_OS_WIN32
-
elapsed = timer->end - timer->start;
GETTIME (timer->start);
timer->start -= elapsed;
-#elif USE_CLOCK_GETTIME
-
- if (timer->start.tv_nsec > timer->end.tv_nsec)
- {
- timer->end.tv_nsec += G_NSEC_PER_SEC;
- timer->end.tv_sec--;
- }
-
- elapsed.tv_nsec = timer->end.tv_nsec - timer->start.tv_nsec;
- elapsed.tv_sec = timer->end.tv_sec - timer->start.tv_sec;
-
- GETTIME (timer->start);
-
- if (timer->start.tv_nsec < elapsed.tv_nsec)
- {
- timer->start.tv_nsec += G_NSEC_PER_SEC;
- timer->start.tv_sec--;
- }
-
- timer->start.tv_nsec -= elapsed.tv_nsec;
- timer->start.tv_sec -= elapsed.tv_sec;
-
-#else
-
- if (timer->start.tv_usec > timer->end.tv_usec)
- {
- timer->end.tv_usec += G_USEC_PER_SEC;
- timer->end.tv_sec--;
- }
-
- elapsed.tv_usec = timer->end.tv_usec - timer->start.tv_usec;
- elapsed.tv_sec = timer->end.tv_sec - timer->start.tv_sec;
-
- GETTIME (timer->start);
-
- if (timer->start.tv_usec < elapsed.tv_usec)
- {
- timer->start.tv_usec += G_USEC_PER_SEC;
- timer->start.tv_sec--;
- }
-
- timer->start.tv_usec -= elapsed.tv_usec;
- timer->start.tv_sec -= elapsed.tv_sec;
-
-#endif /* !G_OS_WIN32 */
-
timer->active = TRUE;
}
gulong *microseconds)
{
gdouble total;
-#ifdef G_OS_WIN32
gint64 elapsed;
-#elif USE_CLOCK_GETTIME
- struct timespec elapsed;
-#else
- struct timeval elapsed;
-#endif
g_return_val_if_fail (timer != NULL, 0);
-#ifdef G_OS_WIN32
if (timer->active)
GETTIME (timer->end);
if (microseconds)
*microseconds = (elapsed / 10) % 1000000;
-#elif USE_CLOCK_GETTIME
- if (timer->active)
- GETTIME (timer->end);
-
- if (timer->start.tv_nsec > timer->end.tv_nsec)
- {
- timer->end.tv_nsec += G_NSEC_PER_SEC;
- timer->end.tv_sec--;
- }
-
- elapsed.tv_nsec = timer->end.tv_nsec - timer->start.tv_nsec;
- elapsed.tv_sec = timer->end.tv_sec - timer->start.tv_sec;
-
- total = elapsed.tv_sec + ((gdouble) elapsed.tv_nsec / (gdouble) G_NSEC_PER_SEC);
- if (total < 0)
- {
- total = 0;
-
- if (microseconds)
- *microseconds = 0;
- }
- else if (microseconds)
- *microseconds = elapsed.tv_nsec / 1000;
-
-#else
- if (timer->active)
- GETTIME (timer->end);
-
- if (timer->start.tv_usec > timer->end.tv_usec)
- {
- timer->end.tv_usec += G_USEC_PER_SEC;
- timer->end.tv_sec--;
- }
-
- elapsed.tv_usec = timer->end.tv_usec - timer->start.tv_usec;
- elapsed.tv_sec = timer->end.tv_sec - timer->start.tv_sec;
-
- total = elapsed.tv_sec + ((gdouble) elapsed.tv_usec / (gdouble) G_USEC_PER_SEC);
- if (total < 0)
- {
- total = 0;
-
- if (microseconds)
- *microseconds = 0;
- }
- else if (microseconds)
- *microseconds = elapsed.tv_usec;
-
-#endif
return total;
}
init->thread_join &&
init->thread_exit &&
init->thread_set_priority &&
- init->thread_self);
+ init->thread_self &&
+ init->gettime);
/* if somebody is calling g_thread_init (), it means that he wants to
* have thread support, so check this
#define G_MUTEX_SIZE (sizeof (pthread_mutex_t))
-#if defined(_SC_THREAD_STACK_MIN) || defined (HAVE_PRIORITIES)
+static gint posix_clock = 0;
+#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_MONOTONIC_CLOCK)
+#define USE_CLOCK_GETTIME 1
+#endif
+
+#if defined(_SC_THREAD_STACK_MIN) || defined (HAVE_PRIORITIES) || defined (USE_CLOCK_GETTIME)
#define HAVE_G_THREAD_IMPL_INIT
static void
g_thread_impl_init(void)
# endif
#endif /* HAVE_PRIORITIES */
+ if (sysconf (_SC_MONOTONIC_CLOCK) >= 0)
+ posix_clock = CLOCK_MONOTONIC;
+ else
+ posix_clock = CLOCK_REALTIME;
}
#endif /* _SC_THREAD_STACK_MIN || HAVE_PRIORITIES */
return (pthread_equal (*(pthread_t*)thread1, *(pthread_t*)thread2) != 0);
}
+static guint64
+g_gettime_posix_impl (void)
+{
+#ifdef USE_CLOCK_GETTIME
+ struct timespec tv;
+
+ clock_gettime (posix_clock, &tv);
+
+ return tv.tv_sec * 1e9 + tv.tv_nsec;
+#else
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+
+ return tv.tv_sec * 1e9 + tv.tv_usec * 1000;
+#endif
+}
+
static GThreadFunctions g_thread_functions_for_glib_use_default =
{
g_mutex_new_posix_impl,
g_thread_exit_posix_impl,
g_thread_set_priority_posix_impl,
g_thread_self_posix_impl,
- g_thread_equal_posix_impl
+ g_thread_equal_posix_impl,
+ g_gettime_posix_impl
};
g_free (target);
}
+static guint64
+g_gettime_win32_impl (void)
+{
+ guint64 v;
+
+ GetSystemTimeAsFileTime ((FILETIME *)&v);
+
+ return v;
+}
+
static GThreadFunctions g_thread_functions_for_glib_use_default =
{
g_mutex_new_win32_impl, /* mutex */
g_thread_exit_win32_impl,
g_thread_set_priority_win32_impl,
g_thread_self_win32_impl,
- NULL /* no equal function necessary */
+ NULL, /* no equal function necessary */
+ g_gettime_win32_impl
};
#define HAVE_G_THREAD_IMPL_INIT