aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2018-07-31 22:40:30 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2018-07-31 22:52:30 +0700
commit8cdecdd54feb33dfb8463f639dd860a6698bafb0 (patch)
tree3a549bdfe7c06c012860710f11b99be9ddcccc9a
parent633fddebcdf15c7daa1a9a12cd9a9de050174c01 (diff)
src/db.c: WIP: integrate SQLite3 with talloc allocatorfixeria/sqlite3_talloc
The current version of this commit enables a custom memory allocator for SQLite3 via SQLITE_CONFIG_MALLOC. If OsmoHLR is compiled with ENABLE_TALLOC macro, talloc is used. Otherwise the default malloc/realloc/free are used. There are lots of debug messages for each call. They are helpful for comparison heap usage footprints between both talloc & malloc. NOTE: SQLite3 version 3.8.2 fails (at least) to init the database with talloc, and there is some big difference in heap usage footprint compared to malloc. At the same time, with the recent SQLite3 version 3.24.0, both heap usage footprints are identical, and OsmoHLR works fine... Change-Id: Icfe67ed0f063b63e6794f9516da3003d01cf20a7
-rw-r--r--src/db.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/db.c b/src/db.c
index 4b0577f..3a86b08 100644
--- a/src/db.c
+++ b/src/db.c
@@ -18,10 +18,12 @@
*/
#include <osmocom/core/utils.h>
+#include <osmocom/core/talloc.h>
#include <stdbool.h>
#include <sqlite3.h>
#include <string.h>
+#include <malloc.h>
#include "logging.h"
#include "db.h"
@@ -72,6 +74,109 @@ static const char *stmt_sql[] = {
[DB_STMT_AUC_3G_DELETE] = "DELETE FROM auc_3g WHERE subscriber_id = $subscriber_id",
};
+/* Dedicated talloc context for SQLite */
+static void *db_sqlite_ctx = NULL;
+/* TEMP: used for memory footprint debugging */
+static int ctr = 0;
+
+/* talloc or malloc? */
+// #define ENABLE_TALLOC
+
+static void *tall_xMalloc(int size)
+{
+#ifdef ENABLE_TALLOC
+ void *p = talloc_size(db_sqlite_ctx, size);
+ int s = talloc_total_size(p);
+#else
+ void *p = malloc(size);
+ int s = malloc_usable_size(p);
+#endif
+ /* TEMP: used for memory footprint debugging */
+ printf("[%d] %s size_req=%d vs size_act=%d ptr=%c\n",
+ ctr++, __func__, size, s, p != NULL ? '+' : '!');
+ return p;
+}
+
+static void tall_xFree(void *ptr)
+{
+#ifdef ENABLE_TALLOC
+ int s = talloc_total_size(ptr);
+ talloc_free(ptr);
+#else
+ int s = malloc_usable_size(ptr);
+ free(ptr);
+#endif
+ /* TEMP: used for memory footprint debugging */
+ printf("[%d] %s size=%d\n", ctr++, __func__, s);
+}
+
+static void *tall_xRealloc(void *ptr, int size)
+{
+#ifdef ENABLE_TALLOC
+ void *p = talloc_realloc_fn(db_sqlite_ctx, ptr, size);
+ int s = talloc_total_size(p);
+#else
+ void *p = realloc(ptr, size);
+ int s = malloc_usable_size(p);
+#endif
+ /* TEMP: used for memory footprint debugging */
+ printf("[%d] %s size_req=%d vs size_act=%d ptr=%c\n",
+ ctr++, __func__, size, s, p != NULL ? '+' : '!');
+ return p;
+}
+
+static int tall_xSize(void *ptr)
+{
+#ifdef ENABLE_TALLOC
+ int s = talloc_total_size(ptr);
+#else
+ int s = malloc_usable_size(ptr);
+#endif
+ /* TEMP: used for memory footprint debugging */
+ printf("[%d] %s size=%d\n", ctr++, __func__, s);
+ return s;
+}
+
+static int tall_xRoundup(int size)
+{
+ /**
+ * DUMMY: return size 'as-is'...
+ * AFAIK talloc doesn't round up the allocation size.
+ */
+ return size;
+}
+
+static int tall_xInit(void *data)
+{
+ /* DUMMY: nothing to initialize */
+ return 0;
+}
+
+static void tall_xShutdown(void *data)
+{
+ /* DUMMY: nothing to deinitialize */
+}
+
+/* Interface between SQLite and talloc memory allocator */
+static const struct sqlite3_mem_methods tall_sqlite_if = {
+ /* Memory allocation function */
+ .xMalloc = &tall_xMalloc,
+ /* Free a prior allocation */
+ .xFree = &tall_xFree,
+ /* Resize an allocation */
+ .xRealloc = &tall_xRealloc,
+ /* Return the size of an allocation */
+ .xSize = &tall_xSize,
+ /* Round up request size to allocation size */
+ .xRoundup = &tall_xRoundup,
+ /* Initialize the memory allocator */
+ .xInit = &tall_xInit,
+ /* Deinitialize the memory allocator */
+ .xShutdown = &tall_xShutdown,
+ /* Argument to xInit() and xShutdown() */
+ .pAppData = NULL,
+};
+
static void sql3_error_log_cb(void *arg, int err_code, const char *msg)
{
LOGP(DDB, LOGL_ERROR, "(%d) %s\n", err_code, msg);
@@ -231,6 +336,15 @@ struct db_context *db_open(void *ctx, const char *fname, bool enable_sqlite_logg
LOGP(DDB, LOGL_INFO, "Compiled against SQLite3 lib version %s\n", SQLITE_VERSION);
LOGP(DDB, LOGL_INFO, "Running with SQLite3 lib version %s\n", sqlite3_libversion());
+ db_sqlite_ctx = talloc_named_const(dbc, 0, "SQLite3");
+
+ /* Configure SQLite3 to use talloc memory allocator */
+ rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &tall_sqlite_if);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Unable to configure SQLite3 "
+ "to use talloc, using default memory allocator\n");
+ }
+
dbc->fname = talloc_strdup(dbc, fname);
for (i = 0; i < 0xfffff; i++) {