libsysprof-capture: Port from GLib to pthreads for locking and once-init

Another step towards dropping the GLib dependency.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

Helps: #40
This commit is contained in:
Philip Withnall
2020-07-02 12:28:08 +01:00
parent c89a47939e
commit 5a2144e254
3 changed files with 59 additions and 32 deletions

View File

@ -40,6 +40,7 @@ libsysprof_capture_deps = [
glib_dep, glib_dep,
gio_dep, gio_dep,
gio_unix_dep, gio_unix_dep,
dependency('threads'),
] ]
libsysprof_capture = static_library( libsysprof_capture = static_library(

View File

@ -71,7 +71,7 @@
#include "sysprof-macros.h" #include "sysprof-macros.h"
#ifdef _WIN32 #ifdef _WIN32
static G_LOCK_DEFINE (_sysprof_io_sync); static void *_sysprof_io_sync_lock = SRWLOCK_INIT;
#endif #endif
size_t size_t
@ -102,11 +102,11 @@ ssize_t
#ifdef _WIN32 #ifdef _WIN32
ssize_t ret = -1; ssize_t ret = -1;
G_LOCK (_sysprof_io_sync); AcquireSRWLockExclusive (_sysprof_io_sync_lock);
errno = 0; errno = 0;
if (lseek (fd, offset, SEEK_SET) != -1) if (lseek (fd, offset, SEEK_SET) != -1)
ret = read (fd, buf, count); ret = read (fd, buf, count);
G_UNLOCK (_sysprof_io_sync); ReleaseSRWLockExclusive (_sysprof_io_sync_lock);
return ret; return ret;
#else #else
@ -124,11 +124,11 @@ ssize_t
#ifdef _WIN32 #ifdef _WIN32
ssize_t ret = -1; ssize_t ret = -1;
G_LOCK (_sysprof_io_sync); AcquireSRWLockExclusive (_sysprof_io_sync_lock);
errno = 0; errno = 0;
if (lseek (fd, offset, SEEK_SET) != -1) if (lseek (fd, offset, SEEK_SET) != -1)
ret = write (fd, buf, count); ret = write (fd, buf, count);
G_UNLOCK (_sysprof_io_sync); ReleaseSRWLockExclusive (_sysprof_io_sync_lock);
return ret; return ret;
#else #else
@ -145,10 +145,10 @@ ssize_t
#ifdef _WIN32 #ifdef _WIN32
ssize_t ret = -1; ssize_t ret = -1;
G_LOCK (_sysprof_io_sync); AcquireSRWLockExclusive (_sysprof_io_sync_lock);
errno = 0; errno = 0;
ret = write (fd, buf, count); ret = write (fd, buf, count);
G_UNLOCK (_sysprof_io_sync); ReleaseSRWLockExclusive (_sysprof_io_sync_lock);
return ret; return ret;
#else #else

View File

@ -62,6 +62,7 @@
#include <glib-unix.h> #include <glib-unix.h>
#include <gio/gio.h> #include <gio/gio.h>
#include <gio/gunixconnection.h> #include <gio/gunixconnection.h>
#include <pthread.h>
#ifdef __linux__ #ifdef __linux__
# include <sched.h> # include <sched.h>
#endif #endif
@ -97,16 +98,17 @@ static MappedRingBuffer *request_writer (void);
static void sysprof_collector_free (void *data); static void sysprof_collector_free (void *data);
static const SysprofCollector *sysprof_collector_get (void); static const SysprofCollector *sysprof_collector_get (void);
static G_LOCK_DEFINE (control_fd); static pthread_mutex_t control_fd_lock = PTHREAD_MUTEX_INITIALIZER;
static GPrivate collector_key = G_PRIVATE_INIT (sysprof_collector_free); static pthread_key_t collector_key; /* initialised in sysprof_collector_init() */
static GPrivate single_trace_key = G_PRIVATE_INIT (NULL); static pthread_key_t single_trace_key; /* initialised in sysprof_collector_init() */
static pthread_once_t collector_init = PTHREAD_ONCE_INIT;
static SysprofCollector *shared_collector; static SysprofCollector *shared_collector;
static SysprofCollector invalid; static SysprofCollector invalid;
static inline bool static inline bool
use_single_trace (void) use_single_trace (void)
{ {
return GPOINTER_TO_INT (g_private_get (&single_trace_key)); return (bool) pthread_getspecific (single_trace_key);
} }
static inline int static inline int
@ -223,7 +225,10 @@ sysprof_collector_free (void *data)
static const SysprofCollector * static const SysprofCollector *
sysprof_collector_get (void) sysprof_collector_get (void)
{ {
const SysprofCollector *collector = g_private_get (&collector_key); const SysprofCollector *collector;
sysprof_collector_init ();
collector = pthread_getspecific (collector_key);
/* We might have gotten here recursively */ /* We might have gotten here recursively */
if SYSPROF_UNLIKELY (collector == COLLECTOR_INVALID) if SYSPROF_UNLIKELY (collector == COLLECTOR_INVALID)
@ -236,16 +241,12 @@ sysprof_collector_get (void)
return shared_collector; return shared_collector;
{ {
SysprofCollector *self; SysprofCollector *self, *old_collector;
g_private_replace (&collector_key, COLLECTOR_INVALID);
self = sysprof_malloc0 (sizeof (SysprofCollector)); self = sysprof_malloc0 (sizeof (SysprofCollector));
if (self == NULL) if (self == NULL)
return COLLECTOR_INVALID; return COLLECTOR_INVALID;
G_LOCK (control_fd);
self->pid = getpid (); self->pid = getpid ();
#ifdef __linux__ #ifdef __linux__
self->tid = syscall (__NR_gettid, 0); self->tid = syscall (__NR_gettid, 0);
@ -253,31 +254,56 @@ sysprof_collector_get (void)
self->tid = self->pid; self->tid = self->pid;
#endif #endif
pthread_mutex_lock (&control_fd_lock);
if (getenv ("SYSPROF_CONTROL_FD") != NULL) if (getenv ("SYSPROF_CONTROL_FD") != NULL)
self->buffer = request_writer (); self->buffer = request_writer ();
if (self->is_shared) /* Update the stored collector */
shared_collector = self; old_collector = pthread_getspecific (collector_key);
else
g_private_replace (&collector_key, self);
G_UNLOCK (control_fd); if (self->is_shared)
{
if (pthread_setspecific (collector_key, COLLECTOR_INVALID) != 0)
goto fail;
sysprof_collector_free (old_collector);
shared_collector = self;
}
else
{
if (pthread_setspecific (collector_key, self) != 0)
goto fail;
sysprof_collector_free (old_collector);
}
pthread_mutex_unlock (&control_fd_lock);
return self; return self;
fail:
pthread_mutex_unlock (&control_fd_lock);
sysprof_collector_free (self);
return COLLECTOR_INVALID;
} }
} }
static void
collector_init_cb (void)
{
if (SYSPROF_UNLIKELY (pthread_key_create (&collector_key, sysprof_collector_free) != 0))
abort ();
if (SYSPROF_UNLIKELY (pthread_key_create (&single_trace_key, NULL) != 0))
abort ();
sysprof_clock_init ();
}
void void
sysprof_collector_init (void) sysprof_collector_init (void)
{ {
static size_t once_init; if (pthread_once (&collector_init, collector_init_cb) != 0)
abort ();
if (g_once_init_enter (&once_init))
{
sysprof_clock_init ();
(void)sysprof_collector_get ();
g_once_init_leave (&once_init, TRUE);
}
} }
#define COLLECTOR_BEGIN \ #define COLLECTOR_BEGIN \
@ -286,7 +312,7 @@ sysprof_collector_init (void)
if SYSPROF_LIKELY (collector->buffer) \ if SYSPROF_LIKELY (collector->buffer) \
{ \ { \
if SYSPROF_UNLIKELY (collector->is_shared) \ if SYSPROF_UNLIKELY (collector->is_shared) \
G_LOCK (control_fd); \ pthread_mutex_lock (&control_fd_lock); \
\ \
{ {
@ -294,7 +320,7 @@ sysprof_collector_init (void)
} \ } \
\ \
if SYSPROF_UNLIKELY (collector->is_shared) \ if SYSPROF_UNLIKELY (collector->is_shared) \
G_UNLOCK (control_fd); \ pthread_mutex_unlock (&control_fd_lock); \
} \ } \
} while (0) } while (0)