From 7118c38b2bcda649fcdccf5b24fab266f319a906 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 10 May 2023 12:42:28 -0700 Subject: [PATCH] libsysprof-analyze: break out string helper We'll want strings to be deduplicated a bunch, and may need to pass this around to make that a bit easier to ensure. --- src/libsysprof-analyze/meson.build | 1 + src/libsysprof-analyze/sysprof-document.c | 31 ++---- .../sysprof-strings-private.h | 37 +++++++ src/libsysprof-analyze/sysprof-strings.c | 96 +++++++++++++++++++ 4 files changed, 141 insertions(+), 24 deletions(-) create mode 100644 src/libsysprof-analyze/sysprof-strings-private.h create mode 100644 src/libsysprof-analyze/sysprof-strings.c diff --git a/src/libsysprof-analyze/meson.build b/src/libsysprof-analyze/meson.build index 905fd5b6..9f150797 100644 --- a/src/libsysprof-analyze/meson.build +++ b/src/libsysprof-analyze/meson.build @@ -28,6 +28,7 @@ libsysprof_analyze_private_sources = [ 'sysprof-mount.c', 'sysprof-mount-device.c', 'sysprof-mount-namespace.c', + 'sysprof-strings.c', ] libsysprof_analyze_public_headers = [ diff --git a/src/libsysprof-analyze/sysprof-document.c b/src/libsysprof-analyze/sysprof-document.c index 60acbd51..bc2e6949 100644 --- a/src/libsysprof-analyze/sysprof-document.c +++ b/src/libsysprof-analyze/sysprof-document.c @@ -35,6 +35,7 @@ #include "sysprof-mount-private.h" #include "sysprof-mount-device-private.h" #include "sysprof-mount-namespace-private.h" +#include "sysprof-strings-private.h" #include "sysprof-symbolizer-private.h" #include "line-reader-private.h" @@ -47,6 +48,8 @@ struct _SysprofDocument GMappedFile *mapped_file; const guint8 *base; + SysprofStrings *strings; + GtkBitset *file_chunks; GtkBitset *traceables; GtkBitset *processes; @@ -58,9 +61,6 @@ struct _SysprofDocument SysprofMountNamespace *mount_namespace; - GMutex strings_mutex; - GHashTable *strings; - SysprofCaptureFileHeader header; guint needs_swap : 1; }; @@ -150,11 +150,12 @@ sysprof_document_finalize (GObject *object) { SysprofDocument *self = (SysprofDocument *)object; + g_clear_pointer (&self->strings, sysprof_strings_unref); + g_clear_pointer (&self->pid_to_mmaps, g_hash_table_unref); g_clear_pointer (&self->pid_to_mountinfo, g_hash_table_unref); g_clear_pointer (&self->mapped_file, g_mapped_file_unref); g_clear_pointer (&self->frames, g_array_unref); - g_clear_pointer (&self->strings, g_hash_table_unref); g_clear_pointer (&self->traceables, gtk_bitset_unref); g_clear_pointer (&self->processes, gtk_bitset_unref); @@ -165,8 +166,6 @@ sysprof_document_finalize (GObject *object) g_clear_pointer (&self->files_first_position, g_hash_table_unref); - g_mutex_clear (&self->strings_mutex); - G_OBJECT_CLASS (sysprof_document_parent_class)->finalize (object); } static void @@ -180,11 +179,9 @@ sysprof_document_class_init (SysprofDocumentClass *klass) static void sysprof_document_init (SysprofDocument *self) { - g_mutex_init (&self->strings_mutex); + self->strings = sysprof_strings_new (); self->frames = g_array_new (FALSE, FALSE, sizeof (SysprofDocumentFramePointer)); - self->strings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, - (GDestroyNotify)g_ref_string_release); self->traceables = gtk_bitset_new_empty (); self->file_chunks = gtk_bitset_new_empty (); @@ -549,23 +546,9 @@ char * _sysprof_document_ref_string (SysprofDocument *self, const char *name) { - char *ret; - g_return_val_if_fail (SYSPROF_IS_DOCUMENT (self), NULL); - if (name == NULL) - return NULL; - - g_mutex_lock (&self->strings_mutex); - if (!(ret = g_hash_table_lookup (self->strings, name))) - { - ret = g_ref_string_new (name); - g_hash_table_insert (self->strings, ret, ret); - } - ret = g_ref_string_acquire (ret); - g_mutex_unlock (&self->strings_mutex); - - return ret; + return sysprof_strings_get (self->strings, name); } static void diff --git a/src/libsysprof-analyze/sysprof-strings-private.h b/src/libsysprof-analyze/sysprof-strings-private.h new file mode 100644 index 00000000..3d58b927 --- /dev/null +++ b/src/libsysprof-analyze/sysprof-strings-private.h @@ -0,0 +1,37 @@ +/* sysprof-strings-private.h + * + * Copyright 2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +typedef struct _SysprofStrings SysprofStrings; + +SysprofStrings *sysprof_strings_new (void); +SysprofStrings *sysprof_strings_ref (SysprofStrings *self); +void sysprof_strings_unref (SysprofStrings *self); +GRefString *sysprof_strings_get (SysprofStrings *self, + const char *string); +GRefString *sysprof_strings_lookup (SysprofStrings *self, + const char *string); + +G_END_DECLS diff --git a/src/libsysprof-analyze/sysprof-strings.c b/src/libsysprof-analyze/sysprof-strings.c new file mode 100644 index 00000000..319d4219 --- /dev/null +++ b/src/libsysprof-analyze/sysprof-strings.c @@ -0,0 +1,96 @@ +/* sysprof-strings.c + * + * Copyright 2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "config.h" + +#include "sysprof-strings-private.h" + +struct _SysprofStrings +{ + GMutex mutex; + GHashTable *hashtable; +}; + +SysprofStrings * +sysprof_strings_new (void) +{ + SysprofStrings *self; + + self = g_atomic_rc_box_new0 (SysprofStrings); + g_mutex_init (&self->mutex); + self->hashtable = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify)g_ref_string_release, + NULL); + + return self; +} + +SysprofStrings * +sysprof_strings_ref (SysprofStrings *self) +{ + return g_atomic_rc_box_acquire (self); +} + +static void +sysprof_strings_finalize (gpointer data) +{ + SysprofStrings *self = data; + + g_mutex_clear (&self->mutex); + g_clear_pointer (&self->hashtable, g_hash_table_unref); +} + +void +sysprof_strings_unref (SysprofStrings *self) +{ + g_atomic_rc_box_release_full (self, sysprof_strings_finalize); +} + +GRefString * +sysprof_strings_get (SysprofStrings *self, + const char *string) +{ + GRefString *ret; + + g_mutex_lock (&self->mutex); + if (!(ret = g_hash_table_lookup (self->hashtable, string))) + { + ret = g_ref_string_new (string); + g_hash_table_insert (self->hashtable, ret, ret); + } + g_ref_string_acquire (ret); + g_mutex_unlock (&self->mutex); + + return ret; +} + +GRefString * +sysprof_strings_lookup (SysprofStrings *self, + const char *string) +{ + GRefString *ret; + + g_mutex_lock (&self->mutex); + ret = g_hash_table_lookup (self->hashtable, string); + g_mutex_unlock (&self->mutex); + + return ret; +}