mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
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:
@ -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(
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user