mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-23 10:42:11 +01:00
gmetrics: Add debug api for print metrics
In order to get a handle on memory usage it would be good to get reports of various types of object usage over time. This commit provides a little api for generating CSV files to dump the data to.
This commit is contained in:
parent
a4b72a282c
commit
3934937c30
@ -143,6 +143,7 @@ libglib_2_0_la_SOURCES = \
|
|||||||
gmarkup.c \
|
gmarkup.c \
|
||||||
gmem.c \
|
gmem.c \
|
||||||
gmessages.c \
|
gmessages.c \
|
||||||
|
gmetrics.c \
|
||||||
gmirroringtable.h \
|
gmirroringtable.h \
|
||||||
gnode.c \
|
gnode.c \
|
||||||
goption.c \
|
goption.c \
|
||||||
@ -278,6 +279,7 @@ glibsubinclude_HEADERS = \
|
|||||||
gmarkup.h \
|
gmarkup.h \
|
||||||
gmem.h \
|
gmem.h \
|
||||||
gmessages.h \
|
gmessages.h \
|
||||||
|
gmetrics.h \
|
||||||
gnode.h \
|
gnode.h \
|
||||||
goption.h \
|
goption.h \
|
||||||
gpattern.h \
|
gpattern.h \
|
||||||
@ -351,8 +353,8 @@ pcre_lib = pcre/libpcre.la
|
|||||||
pcre_inc =
|
pcre_inc =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libglib_2_0_la_CFLAGS = $(AM_CFLAGS) $(GLIB_HIDDEN_VISIBILITY_CFLAGS) $(LIBSYSTEMD_CFLAGS)
|
libglib_2_0_la_CFLAGS = $(AM_CFLAGS) $(GLIB_HIDDEN_VISIBILITY_CFLAGS) $(LIBSYSTEMD_CFLAGS) $(ZLIB_CFLAGS)
|
||||||
libglib_2_0_la_LIBADD = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ @ICONV_LIBS@ @G_LIBS_EXTRA@ $(pcre_lib) $(G_THREAD_LIBS_EXTRA) $(G_THREAD_LIBS_FOR_GTHREAD) $(LIBSYSTEMD_LIBS)
|
libglib_2_0_la_LIBADD = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ @ICONV_LIBS@ @G_LIBS_EXTRA@ $(pcre_lib) $(G_THREAD_LIBS_EXTRA) $(G_THREAD_LIBS_FOR_GTHREAD) $(LIBSYSTEMD_LIBS) $(ZLIB_LIBS)
|
||||||
libglib_2_0_la_DEPENDENCIES = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ $(glib_win32_res) $(glib_def)
|
libglib_2_0_la_DEPENDENCIES = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ $(glib_win32_res) $(glib_def)
|
||||||
|
|
||||||
libglib_2_0_la_LDFLAGS = $(GLIB_LINK_FLAGS) \
|
libglib_2_0_la_LDFLAGS = $(GLIB_LINK_FLAGS) \
|
||||||
|
@ -268,6 +268,7 @@ glib_init (void)
|
|||||||
|
|
||||||
glib_inited = TRUE;
|
glib_inited = TRUE;
|
||||||
|
|
||||||
|
g_metrics_init ();
|
||||||
g_messages_prefixed_init ();
|
g_messages_prefixed_init ();
|
||||||
g_debug_init ();
|
g_debug_init ();
|
||||||
g_quark_init ();
|
g_quark_init ();
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define __GLIB_INIT_H__
|
#define __GLIB_INIT_H__
|
||||||
|
|
||||||
#include "gmessages.h"
|
#include "gmessages.h"
|
||||||
|
#include "gmetrics.h"
|
||||||
|
|
||||||
extern GLogLevelFlags g_log_always_fatal;
|
extern GLogLevelFlags g_log_always_fatal;
|
||||||
extern GLogLevelFlags g_log_msg_prefix;
|
extern GLogLevelFlags g_log_msg_prefix;
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
#include <glib/gmarkup.h>
|
#include <glib/gmarkup.h>
|
||||||
#include <glib/gmem.h>
|
#include <glib/gmem.h>
|
||||||
#include <glib/gmessages.h>
|
#include <glib/gmessages.h>
|
||||||
|
#include <glib/gmetrics.h>
|
||||||
#include <glib/gnode.h>
|
#include <glib/gnode.h>
|
||||||
#include <glib/goption.h>
|
#include <glib/goption.h>
|
||||||
#include <glib/gpattern.h>
|
#include <glib/gpattern.h>
|
||||||
|
@ -202,6 +202,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
#include <process.h> /* For getpid() */
|
#include <process.h> /* For getpid() */
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
@ -618,7 +618,6 @@ GPrintFunc g_set_printerr_handler (GPrintFunc func);
|
|||||||
return (val); }G_STMT_END
|
return (val); }G_STMT_END
|
||||||
|
|
||||||
#endif /* !G_DISABLE_CHECKS */
|
#endif /* !G_DISABLE_CHECKS */
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_MESSAGES_H__ */
|
#endif /* __G_MESSAGES_H__ */
|
||||||
|
4243
glib/gmetrics.c
Normal file
4243
glib/gmetrics.c
Normal file
File diff suppressed because it is too large
Load Diff
333
glib/gmetrics.h
Normal file
333
glib/gmetrics.h
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
/* GLIB - Library of useful routines for C programming
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
||||||
|
* file for a list of people on the GLib Team. See the ChangeLog
|
||||||
|
* files for a list of changes. These files are distributed with
|
||||||
|
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __G_METRICS_H__
|
||||||
|
#define __G_METRICS_H__
|
||||||
|
|
||||||
|
#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
|
||||||
|
#error "Only <glib.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <glib/gtypes.h>
|
||||||
|
#include <glib/gmacros.h>
|
||||||
|
#include <glib/gmain.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_init (void);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gboolean g_metrics_enabled (void);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gboolean g_metrics_requested (const char *name);
|
||||||
|
|
||||||
|
typedef void (*GMetricsTimeoutFunc) (void);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
int g_metrics_get_timeout_fd (void);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_run_timeout_handlers (void);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gulong g_metrics_get_generation (void);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_start_timeout (GMetricsTimeoutFunc timeout_handler);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
const char *g_metrics_get_log_dir (void);
|
||||||
|
|
||||||
|
typedef struct _GMetricsFile GMetricsFile;
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
GMetricsFile *g_metrics_file_new (const char *name,
|
||||||
|
const char *first_column_name,
|
||||||
|
const char *first_column_format,
|
||||||
|
...);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_file_start_record (GMetricsFile *metrics_file);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_file_add_row_without_cast (GMetricsFile *metrics_file,
|
||||||
|
gconstpointer first_column_value,
|
||||||
|
...);
|
||||||
|
#define g_metrics_file_add_row(_file,_first,_rest...) g_metrics_file_add_row_without_cast ((_file), (gpointer) (_first), _rest)
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_file_end_record (GMetricsFile *metrics_file);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_file_free (GMetricsFile *metrics_file);
|
||||||
|
|
||||||
|
typedef struct _GMetricsTable GMetricsTable;
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
GMetricsTable *g_metrics_table_new (gsize record_size);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_table_set_record (GMetricsTable *metrics_table,
|
||||||
|
const char *name,
|
||||||
|
gpointer record);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_table_get_record (GMetricsTable *metrics_table,
|
||||||
|
const char *name);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_table_remove_record (GMetricsTable *metrics_table,
|
||||||
|
const char *name);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_table_clear (GMetricsTable *metrics_table);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_table_free (GMetricsTable *metrics_table);
|
||||||
|
|
||||||
|
typedef struct _GMetricsTableIter GMetricsTableIter;
|
||||||
|
|
||||||
|
typedef struct _GMetricsTableEntry GMetricsTableEntry;
|
||||||
|
struct _GMetricsTableIter
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GMetricsTableEntry *entry;
|
||||||
|
};
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_table_iter_init (GMetricsTableIter *iter,
|
||||||
|
GMetricsTable *table);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_table_sorted_iter_init (GMetricsTableIter *iter,
|
||||||
|
GMetricsTable *table,
|
||||||
|
GCompareFunc comparison_function);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gboolean g_metrics_table_iter_next_without_cast (GMetricsTableIter *iter,
|
||||||
|
const char **name,
|
||||||
|
gpointer *record);
|
||||||
|
#define g_metrics_table_iter_next(_iter,_name,_record) g_metrics_table_iter_next_without_cast ((_iter), (_name), (gpointer *) (_record))
|
||||||
|
|
||||||
|
struct _GMetricsInstanceCounterMetrics
|
||||||
|
{
|
||||||
|
char comment[64];
|
||||||
|
gsize total_memory_usage;
|
||||||
|
gsize instance_count;
|
||||||
|
gssize instance_change;
|
||||||
|
gsize instance_watermark;
|
||||||
|
gssize average_instance_change;
|
||||||
|
gsize number_of_samples;
|
||||||
|
};
|
||||||
|
typedef struct _GMetricsInstanceCounterMetrics GMetricsInstanceCounterMetrics;
|
||||||
|
|
||||||
|
typedef struct _GMetricsInstanceCounter GMetricsInstanceCounter;
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
GMetricsInstanceCounter *g_metrics_instance_counter_new (void);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_instance_counter_start_record (GMetricsInstanceCounter *counter);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_instance_counter_add_instance (GMetricsInstanceCounter *counter,
|
||||||
|
const char *name,
|
||||||
|
gsize memory_usage);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_instance_counter_add_instances (GMetricsInstanceCounter *counter,
|
||||||
|
const char *name,
|
||||||
|
const char *comment,
|
||||||
|
gsize number_of_instances,
|
||||||
|
gsize total_usage);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_instance_counter_end_record (GMetricsInstanceCounter *counter);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gboolean g_metrics_instance_counter_instance_is_interesting (GMetricsInstanceCounter *counter,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_instance_counter_free (GMetricsInstanceCounter *counter);
|
||||||
|
|
||||||
|
typedef struct _GMetricsInstanceCounterIter GMetricsInstanceCounterIter;
|
||||||
|
|
||||||
|
typedef struct _GMetricsInstanceCounterEntry GMetricsInstanceCounterEntry;
|
||||||
|
struct _GMetricsInstanceCounterIter
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
gssize table_index;
|
||||||
|
GMetricsTableIter table_iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_instance_counter_iter_init (GMetricsInstanceCounterIter *iter,
|
||||||
|
GMetricsInstanceCounter *table);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gboolean g_metrics_instance_counter_iter_next (GMetricsInstanceCounterIter *iter,
|
||||||
|
const char **name,
|
||||||
|
GMetricsInstanceCounterMetrics **metrics);
|
||||||
|
|
||||||
|
typedef struct _GMetricsList GMetricsList;
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
GMetricsList *g_metrics_list_new (void);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_list_add_item (GMetricsList *list,
|
||||||
|
gpointer item);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_list_remove_item (GMetricsList *list,
|
||||||
|
gpointer item);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gsize g_metrics_list_get_length (GMetricsList *list);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_list_get_last_item (GMetricsList *list);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_list_remove_last_item (GMetricsList *list);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_list_free (GMetricsList *list);
|
||||||
|
|
||||||
|
typedef struct _GMetricsListIter GMetricsListIter;
|
||||||
|
typedef struct _GMetricsListNode GMetricsListNode;
|
||||||
|
struct _GMetricsListIter
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GMetricsListNode *node;
|
||||||
|
GMetricsListNode *next_node;
|
||||||
|
};
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_list_iter_init (GMetricsListIter *iter,
|
||||||
|
GMetricsList *list);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gboolean g_metrics_list_iter_next_without_cast (GMetricsListIter *iter,
|
||||||
|
gpointer *item);
|
||||||
|
#define g_metrics_list_iter_next(_iter,_item) g_metrics_list_iter_next_without_cast ((_iter), (gpointer *) (_item))
|
||||||
|
|
||||||
|
typedef struct _GMetricsStackTrace GMetricsStackTrace;
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
GMetricsStackTrace *g_metrics_stack_trace_new (int start_frame,
|
||||||
|
int number_of_frames,
|
||||||
|
const char *delimiter);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
const char *g_metrics_stack_trace_get_hash_key (GMetricsStackTrace *stack_trace);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
const char *g_metrics_stack_trace_get_output (GMetricsStackTrace *stack_trace);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_stack_trace_add_annotation (GMetricsStackTrace *stack_trace,
|
||||||
|
const char *annotation);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_stack_trace_free (GMetricsStackTrace *stack_trace);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
char *g_metrics_stack_trace (void);
|
||||||
|
|
||||||
|
typedef struct _GMetricsStackTraceSampler GMetricsStackTraceSampler;
|
||||||
|
typedef struct _GMetricsStackTraceSample GMetricsStackTraceSample;
|
||||||
|
typedef struct _GMetricsStackTraceSamplerIter GMetricsStackTraceSamplerIter;
|
||||||
|
|
||||||
|
struct _GMetricsStackTraceSamplerIter
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GMetricsTableIter table_iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GMetricsStackTraceSample
|
||||||
|
{
|
||||||
|
char name[64];
|
||||||
|
GMetricsStackTrace *stack_trace;
|
||||||
|
gsize number_of_hits;
|
||||||
|
};
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_stack_trace_sampler_iter_init (GMetricsStackTraceSamplerIter *iter,
|
||||||
|
GMetricsStackTraceSampler *sampler);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gboolean g_metrics_stack_trace_sampler_iter_next (GMetricsStackTraceSamplerIter *iter,
|
||||||
|
GMetricsStackTraceSample **sample);
|
||||||
|
|
||||||
|
typedef gboolean (* GMetricsStackTraceAnnotationHandler) (char *annotation, gsize annotation_size, gpointer user_data);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_set_stack_trace_annotation_handler (GMetricsStackTraceAnnotationHandler handler,
|
||||||
|
gpointer user_data);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
GMetricsStackTraceSampler *g_metrics_stack_trace_sampler_new (void);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_stack_trace_sampler_take_sample (GMetricsStackTraceSampler *sample,
|
||||||
|
const char *name,
|
||||||
|
gpointer instance);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_stack_trace_sampler_remove_sample (GMetricsStackTraceSampler *sampler,
|
||||||
|
gpointer instance);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_stack_trace_sampler_clear (GMetricsStackTraceSampler *sampler);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_stack_trace_sampler_free (GMetricsStackTraceSampler *sampler);
|
||||||
|
|
||||||
|
typedef struct _GMetricsAllocationBlockStore GMetricsAllocationBlockStore;
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
GMetricsAllocationBlockStore *g_metrics_allocation_block_store_new (const char *name,
|
||||||
|
gsize size);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_allocation_block_store_free (GMetricsAllocationBlockStore *block_store);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_allocation_block_store_allocate (GMetricsAllocationBlockStore *block_store,
|
||||||
|
gsize size);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_allocation_block_store_allocate_with_name (GMetricsAllocationBlockStore *block_store,
|
||||||
|
gsize size,
|
||||||
|
const char *name);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_allocation_block_store_reallocate (GMetricsAllocationBlockStore *block_store,
|
||||||
|
gpointer allocation,
|
||||||
|
gsize size);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_allocation_block_store_copy (GMetricsAllocationBlockStore *block_store,
|
||||||
|
gconstpointer allocation,
|
||||||
|
gsize size);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_allocation_block_store_copy_with_name (GMetricsAllocationBlockStore *block_store,
|
||||||
|
gconstpointer allocation,
|
||||||
|
gsize size,
|
||||||
|
const char *name);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_allocation_block_store_deallocate (GMetricsAllocationBlockStore *block_store,
|
||||||
|
gpointer allocation);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_push_default_allocation_block_store (GMetricsAllocationBlockStore *block_store);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_pop_default_allocation_block_store (void);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_allocate (gsize size);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_reallocate (gpointer allocation,
|
||||||
|
gsize size);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
gpointer g_metrics_copy (gconstpointer allocation,
|
||||||
|
gsize size);
|
||||||
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
void g_metrics_free (gpointer allocation);
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __G_METRICS_H__ */
|
1138
glib/uthash.h
Normal file
1138
glib/uthash.h
Normal file
File diff suppressed because it is too large
Load Diff
1073
glib/utlist.h
Normal file
1073
glib/utlist.h
Normal file
File diff suppressed because it is too large
Load Diff
411
glib/utstring.h
Normal file
411
glib/utstring.h
Normal file
@ -0,0 +1,411 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2021, Troy D. Hanson http://troydhanson.github.io/uthash/
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||||
|
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* a dynamic string implementation using macros
|
||||||
|
*/
|
||||||
|
#ifndef UTSTRING_H
|
||||||
|
#define UTSTRING_H
|
||||||
|
|
||||||
|
#define UTSTRING_VERSION 2.3.0
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define UTSTRING_UNUSED __attribute__((__unused__))
|
||||||
|
#else
|
||||||
|
#define UTSTRING_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef oom
|
||||||
|
#error "The name of macro 'oom' has been changed to 'utstring_oom'. Please update your code."
|
||||||
|
#define utstring_oom() oom()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef utstring_oom
|
||||||
|
#define utstring_oom() exit(-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void *__libc_malloc (size_t size);
|
||||||
|
extern void *__libc_realloc (void *ptr, size_t size);
|
||||||
|
extern void __libc_free (void *ptr);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *d; /* pointer to allocated buffer */
|
||||||
|
size_t n; /* allocated capacity */
|
||||||
|
size_t i; /* index of first unused byte */
|
||||||
|
} UT_string;
|
||||||
|
|
||||||
|
#define utstring_reserve(s,amt) \
|
||||||
|
do { \
|
||||||
|
if (((s)->n - (s)->i) < (size_t)(amt)) { \
|
||||||
|
char *utstring_tmp = (char*)__libc_realloc( \
|
||||||
|
(s)->d, (s)->n + (amt)); \
|
||||||
|
if (!utstring_tmp) { \
|
||||||
|
utstring_oom(); \
|
||||||
|
} \
|
||||||
|
(s)->d = utstring_tmp; \
|
||||||
|
(s)->n += (amt); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define utstring_init(s) \
|
||||||
|
do { \
|
||||||
|
(s)->n = 0; (s)->i = 0; (s)->d = NULL; \
|
||||||
|
utstring_reserve(s,100); \
|
||||||
|
(s)->d[0] = '\0'; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define utstring_done(s) \
|
||||||
|
do { \
|
||||||
|
if ((s)->d != NULL) __libc_free((s)->d); \
|
||||||
|
(s)->n = 0; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define utstring_free(s) \
|
||||||
|
do { \
|
||||||
|
utstring_done(s); \
|
||||||
|
__libc_free(s); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define utstring_new(s) \
|
||||||
|
do { \
|
||||||
|
(s) = (UT_string*)__libc_malloc(sizeof(UT_string)); \
|
||||||
|
if (!(s)) { \
|
||||||
|
utstring_oom(); \
|
||||||
|
} \
|
||||||
|
utstring_init(s); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define utstring_renew(s) \
|
||||||
|
do { \
|
||||||
|
if (s) { \
|
||||||
|
utstring_clear(s); \
|
||||||
|
} else { \
|
||||||
|
utstring_new(s); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define utstring_clear(s) \
|
||||||
|
do { \
|
||||||
|
(s)->i = 0; \
|
||||||
|
(s)->d[0] = '\0'; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define utstring_bincpy(s,b,l) \
|
||||||
|
do { \
|
||||||
|
utstring_reserve((s),(l)+1); \
|
||||||
|
if (l) memcpy(&(s)->d[(s)->i], b, l); \
|
||||||
|
(s)->i += (l); \
|
||||||
|
(s)->d[(s)->i]='\0'; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define utstring_concat(dst,src) \
|
||||||
|
do { \
|
||||||
|
utstring_reserve((dst),((src)->i)+1); \
|
||||||
|
if ((src)->i) memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \
|
||||||
|
(dst)->i += (src)->i; \
|
||||||
|
(dst)->d[(dst)->i]='\0'; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define utstring_len(s) ((s)->i)
|
||||||
|
|
||||||
|
#define utstring_body(s) ((s)->d)
|
||||||
|
|
||||||
|
UTSTRING_UNUSED static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
|
||||||
|
int n;
|
||||||
|
va_list cp;
|
||||||
|
for (;;) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
cp = ap;
|
||||||
|
#else
|
||||||
|
va_copy(cp, ap);
|
||||||
|
#endif
|
||||||
|
n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
|
||||||
|
va_end(cp);
|
||||||
|
|
||||||
|
if ((n > -1) && ((size_t) n < (s->n-s->i))) {
|
||||||
|
s->i += n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Else try again with more space. */
|
||||||
|
if (n > -1) utstring_reserve(s,n+1); /* exact */
|
||||||
|
else utstring_reserve(s,(s->n)*2); /* 2x */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef __GNUC__
|
||||||
|
/* support printf format checking (2=the format string, 3=start of varargs) */
|
||||||
|
static void utstring_printf(UT_string *s, const char *fmt, ...)
|
||||||
|
__attribute__ (( format( printf, 2, 3) ));
|
||||||
|
#endif
|
||||||
|
UTSTRING_UNUSED static void utstring_printf(UT_string *s, const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap,fmt);
|
||||||
|
utstring_printf_va(s,fmt,ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* begin substring search functions *
|
||||||
|
******************************************************************************/
|
||||||
|
/* Build KMP table from left to right. */
|
||||||
|
UTSTRING_UNUSED static void _utstring_BuildTable(
|
||||||
|
const char *P_Needle,
|
||||||
|
size_t P_NeedleLen,
|
||||||
|
long *P_KMP_Table)
|
||||||
|
{
|
||||||
|
long i, j;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
j = i - 1;
|
||||||
|
P_KMP_Table[i] = j;
|
||||||
|
while (i < (long) P_NeedleLen)
|
||||||
|
{
|
||||||
|
while ( (j > -1) && (P_Needle[i] != P_Needle[j]) )
|
||||||
|
{
|
||||||
|
j = P_KMP_Table[j];
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
if (i < (long) P_NeedleLen)
|
||||||
|
{
|
||||||
|
if (P_Needle[i] == P_Needle[j])
|
||||||
|
{
|
||||||
|
P_KMP_Table[i] = P_KMP_Table[j];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
P_KMP_Table[i] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
P_KMP_Table[i] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Build KMP table from right to left. */
|
||||||
|
UTSTRING_UNUSED static void _utstring_BuildTableR(
|
||||||
|
const char *P_Needle,
|
||||||
|
size_t P_NeedleLen,
|
||||||
|
long *P_KMP_Table)
|
||||||
|
{
|
||||||
|
long i, j;
|
||||||
|
|
||||||
|
i = P_NeedleLen - 1;
|
||||||
|
j = i + 1;
|
||||||
|
P_KMP_Table[i + 1] = j;
|
||||||
|
while (i >= 0)
|
||||||
|
{
|
||||||
|
while ( (j < (long) P_NeedleLen) && (P_Needle[i] != P_Needle[j]) )
|
||||||
|
{
|
||||||
|
j = P_KMP_Table[j + 1];
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
j--;
|
||||||
|
if (i >= 0)
|
||||||
|
{
|
||||||
|
if (P_Needle[i] == P_Needle[j])
|
||||||
|
{
|
||||||
|
P_KMP_Table[i + 1] = P_KMP_Table[j + 1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
P_KMP_Table[i + 1] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
P_KMP_Table[i + 1] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Search data from left to right. ( Multiple search mode. ) */
|
||||||
|
UTSTRING_UNUSED static long _utstring_find(
|
||||||
|
const char *P_Haystack,
|
||||||
|
size_t P_HaystackLen,
|
||||||
|
const char *P_Needle,
|
||||||
|
size_t P_NeedleLen,
|
||||||
|
long *P_KMP_Table)
|
||||||
|
{
|
||||||
|
long i, j;
|
||||||
|
long V_FindPosition = -1;
|
||||||
|
|
||||||
|
/* Search from left to right. */
|
||||||
|
i = j = 0;
|
||||||
|
while ( (j < (int)P_HaystackLen) && (((P_HaystackLen - j) + i) >= P_NeedleLen) )
|
||||||
|
{
|
||||||
|
while ( (i > -1) && (P_Needle[i] != P_Haystack[j]) )
|
||||||
|
{
|
||||||
|
i = P_KMP_Table[i];
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
if (i >= (int)P_NeedleLen)
|
||||||
|
{
|
||||||
|
/* Found. */
|
||||||
|
V_FindPosition = j - i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return V_FindPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Search data from right to left. ( Multiple search mode. ) */
|
||||||
|
UTSTRING_UNUSED static long _utstring_findR(
|
||||||
|
const char *P_Haystack,
|
||||||
|
size_t P_HaystackLen,
|
||||||
|
const char *P_Needle,
|
||||||
|
size_t P_NeedleLen,
|
||||||
|
long *P_KMP_Table)
|
||||||
|
{
|
||||||
|
long i, j;
|
||||||
|
long V_FindPosition = -1;
|
||||||
|
|
||||||
|
/* Search from right to left. */
|
||||||
|
j = (P_HaystackLen - 1);
|
||||||
|
i = (P_NeedleLen - 1);
|
||||||
|
while ( (j >= 0) && (j >= i) )
|
||||||
|
{
|
||||||
|
while ( (i < (int)P_NeedleLen) && (P_Needle[i] != P_Haystack[j]) )
|
||||||
|
{
|
||||||
|
i = P_KMP_Table[i + 1];
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
j--;
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
/* Found. */
|
||||||
|
V_FindPosition = j + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return V_FindPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Search data from left to right. ( One time search mode. ) */
|
||||||
|
UTSTRING_UNUSED static long utstring_find(
|
||||||
|
UT_string *s,
|
||||||
|
long P_StartPosition, /* Start from 0. -1 means last position. */
|
||||||
|
const char *P_Needle,
|
||||||
|
size_t P_NeedleLen)
|
||||||
|
{
|
||||||
|
long V_StartPosition;
|
||||||
|
long V_HaystackLen;
|
||||||
|
long *V_KMP_Table;
|
||||||
|
long V_FindPosition = -1;
|
||||||
|
|
||||||
|
if (P_StartPosition < 0)
|
||||||
|
{
|
||||||
|
V_StartPosition = s->i + P_StartPosition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
V_StartPosition = P_StartPosition;
|
||||||
|
}
|
||||||
|
V_HaystackLen = s->i - V_StartPosition;
|
||||||
|
if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) )
|
||||||
|
{
|
||||||
|
V_KMP_Table = (long *)__libc_malloc(sizeof(long) * (P_NeedleLen + 1));
|
||||||
|
if (V_KMP_Table != NULL)
|
||||||
|
{
|
||||||
|
_utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table);
|
||||||
|
|
||||||
|
V_FindPosition = _utstring_find(s->d + V_StartPosition,
|
||||||
|
V_HaystackLen,
|
||||||
|
P_Needle,
|
||||||
|
P_NeedleLen,
|
||||||
|
V_KMP_Table);
|
||||||
|
if (V_FindPosition >= 0)
|
||||||
|
{
|
||||||
|
V_FindPosition += V_StartPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
__libc_free(V_KMP_Table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return V_FindPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Search data from right to left. ( One time search mode. ) */
|
||||||
|
UTSTRING_UNUSED static long utstring_findR(
|
||||||
|
UT_string *s,
|
||||||
|
long P_StartPosition, /* Start from 0. -1 means last position. */
|
||||||
|
const char *P_Needle,
|
||||||
|
size_t P_NeedleLen)
|
||||||
|
{
|
||||||
|
long V_StartPosition;
|
||||||
|
long V_HaystackLen;
|
||||||
|
long *V_KMP_Table;
|
||||||
|
long V_FindPosition = -1;
|
||||||
|
|
||||||
|
if (P_StartPosition < 0)
|
||||||
|
{
|
||||||
|
V_StartPosition = s->i + P_StartPosition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
V_StartPosition = P_StartPosition;
|
||||||
|
}
|
||||||
|
V_HaystackLen = V_StartPosition + 1;
|
||||||
|
if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) )
|
||||||
|
{
|
||||||
|
V_KMP_Table = (long *)__libc_malloc(sizeof(long) * (P_NeedleLen + 1));
|
||||||
|
if (V_KMP_Table != NULL)
|
||||||
|
{
|
||||||
|
_utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table);
|
||||||
|
|
||||||
|
V_FindPosition = _utstring_findR(s->d,
|
||||||
|
V_HaystackLen,
|
||||||
|
P_Needle,
|
||||||
|
P_NeedleLen,
|
||||||
|
V_KMP_Table);
|
||||||
|
|
||||||
|
__libc_free(V_KMP_Table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return V_FindPosition;
|
||||||
|
}
|
||||||
|
/*******************************************************************************
|
||||||
|
* end substring search functions *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#endif /* UTSTRING_H */
|
Loading…
x
Reference in New Issue
Block a user