[tarantool-patches] [PATCH v1 26/28] sql: cleanup of legacy memory management system

imeevma at tarantool.org imeevma at tarantool.org
Mon Jun 10 16:57:08 MSK 2019


Follow-up for #4074
---
 src/box/sql/malloc.c   | 246 +------------------------------------------------
 src/box/sql/sqlInt.h   |  16 ----
 src/box/sql/status.c   | 149 ------------------------------
 src/box/sql/tokenize.c |   5 -
 src/box/sql/vdbe.c     |   4 -
 src/box/sql/vdbesort.c |   8 +-
 6 files changed, 4 insertions(+), 424 deletions(-)

diff --git a/src/box/sql/malloc.c b/src/box/sql/malloc.c
index f5612bf..c3fc50b 100644
--- a/src/box/sql/malloc.c
+++ b/src/box/sql/malloc.c
@@ -121,26 +121,6 @@ sql_sized_realloc(void *pPrior, int nByte)
 }
 
 /*
- * Attempt to release up to n bytes of non-essential memory currently
- * held by sql. An example of non-essential memory is memory used to
- * cache database pages that are not currently in use.
- */
-int
-sql_release_memory(int n)
-{
-#ifdef SQL_ENABLE_MEMORY_MANAGEMENT
-	return sqlPcacheReleaseMemory(n);
-#else
-	/* IMPLEMENTATION-OF: R-34391-24921 The sql_release_memory() routine
-	 * is a no-op returning zero if sql is not compiled with
-	 * SQL_ENABLE_MEMORY_MANAGEMENT.
-	 */
-	UNUSED_PARAMETER(n);
-	return 0;
-#endif
-}
-
-/*
  * An instance of the following object records the location of
  * each unused scratch buffer.
  */
@@ -149,38 +129,11 @@ typedef struct ScratchFreeslot {
 } ScratchFreeslot;
 
 /*
- * State information local to the memory allocation subsystem.
- */
-static SQL_WSD struct Mem0Global {
-	sql_int64 alarmThreshold;	/* The soft heap limit */
-
-	/*
-	 * Pointers to the end of sqlGlobalConfig.pScratch memory
-	 * (so that a range test can be used to determine if an allocation
-	 * being freed came from pScratch) and a pointer to the list of
-	 * unused scratch allocations.
-	 */
-	void *pScratchEnd;
-	ScratchFreeslot *pScratchFree;
-	u32 nScratchFree;
-
-	/*
-	 * True if heap is nearly "full" where "full" is defined by the
-	 * sql_soft_heap_limit() setting.
-	 */
-	int nearlyFull;
-} mem0 = {
-0, 0, 0, 0, 0};
-
-#define mem0 GLOBAL(struct Mem0Global, mem0)
-
-/*
  * Initialize the memory allocation subsystem.
  */
 void
 sqlMallocInit(void)
 {
-	memset(&mem0, 0, sizeof(mem0));
 	if (sqlGlobalConfig.pScratch && sqlGlobalConfig.szScratch >= 100
 	    && sqlGlobalConfig.nScratch > 0) {
 		int i, n, sz;
@@ -189,16 +142,12 @@ sqlMallocInit(void)
 		sqlGlobalConfig.szScratch = sz;
 		pSlot = (ScratchFreeslot *) sqlGlobalConfig.pScratch;
 		n = sqlGlobalConfig.nScratch;
-		mem0.pScratchFree = pSlot;
-		mem0.nScratchFree = n;
 		for (i = 0; i < n - 1; i++) {
 			pSlot->pNext = (ScratchFreeslot *) (sz + (char *)pSlot);
 			pSlot = pSlot->pNext;
 		}
 		pSlot->pNext = 0;
-		mem0.pScratchEnd = (void *)&pSlot[1];
 	} else {
-		mem0.pScratchEnd = 0;
 		sqlGlobalConfig.pScratch = 0;
 		sqlGlobalConfig.szScratch = 0;
 		sqlGlobalConfig.nScratch = 0;
@@ -211,37 +160,6 @@ sqlMallocInit(void)
 }
 
 /*
- * Return true if the heap is currently under memory pressure - in other
- * words if the amount of heap used is close to the limit set by
- * sql_soft_heap_limit().
- */
-int
-sqlHeapNearlyFull(void)
-{
-	return mem0.nearlyFull;
-}
-
-/*
- * Deinitialize the memory allocation subsystem.
- */
-void
-sqlMallocEnd(void)
-{
-	memset(&mem0, 0, sizeof(mem0));
-}
-
-/*
- * Trigger the alarm
- */
-static void
-sqlMallocAlarm(int nByte)
-{
-	if (mem0.alarmThreshold <= 0)
-		return;
-	sql_release_memory(nByte);
-}
-
-/*
  * Do a memory allocation with statistics and alarms.  Assume the
  * lock is already held.
  */
@@ -252,23 +170,7 @@ mallocWithAlarm(int n, void **pp)
 	void *p;
 	nFull = ROUND8(n);
 	sqlStatusHighwater(SQL_STATUS_MALLOC_SIZE, n);
-	if (mem0.alarmThreshold > 0) {
-		sql_int64 nUsed =
-		    sqlStatusValue(SQL_STATUS_MEMORY_USED);
-		if (nUsed >= mem0.alarmThreshold - nFull) {
-			mem0.nearlyFull = 1;
-			sqlMallocAlarm(nFull);
-		} else {
-			mem0.nearlyFull = 0;
-		}
-	}
 	p = sql_sized_malloc(nFull);
-#ifdef SQL_ENABLE_MEMORY_MANAGEMENT
-	if (p == 0 && mem0.alarmThreshold > 0) {
-		sqlMallocAlarm(nFull);
-		p = sql_sized_malloc(nFull);
-	}
-#endif
 	if (p) {
 		nFull = sqlMallocSize(p);
 		sqlStatusUp(SQL_STATUS_MEMORY_USED, nFull);
@@ -321,101 +223,6 @@ sql_malloc64(sql_uint64 n)
 }
 
 /*
- * Each thread may only have a single outstanding allocation from
- * xScratchMalloc().  We verify this constraint in the single-threaded
- * case by setting scratchAllocOut to 1 when an allocation
- * is outstanding clearing it when the allocation is freed.
- */
-#if !defined(NDEBUG)
-static int scratchAllocOut = 0;
-#endif
-
-/*
- * Allocate memory that is to be used and released right away.
- * This routine is similar to alloca() in that it is not intended
- * for situations where the memory might be held long-term.  This
- * routine is intended to get memory to old large transient data
- * structures that would not normally fit on the stack of an
- * embedded processor.
- */
-void *
-sqlScratchMalloc(int n)
-{
-	void *p;
-	assert(n > 0);
-
-	sqlStatusHighwater(SQL_STATUS_SCRATCH_SIZE, n);
-	if (mem0.nScratchFree && sqlGlobalConfig.szScratch >= n) {
-		p = mem0.pScratchFree;
-		mem0.pScratchFree = mem0.pScratchFree->pNext;
-		mem0.nScratchFree--;
-		sqlStatusUp(SQL_STATUS_SCRATCH_USED, 1);
-	} else {
-		p = sqlMalloc(n);
-		if (sqlGlobalConfig.bMemstat && p) {
-			sqlStatusUp(SQL_STATUS_SCRATCH_OVERFLOW,
-					sqlMallocSize(p));
-		}
-	}
-
-#if !defined(NDEBUG)
-	/* EVIDENCE-OF: R-12970-05880 sql will not use more than one scratch
-	 * buffers per thread.
-	 *
-	 * This can only be checked in single-threaded mode.
-	 */
-	assert(scratchAllocOut == 0);
-	if (p)
-		scratchAllocOut++;
-#endif
-
-	return p;
-}
-
-void
-sqlScratchFree(void *p)
-{
-	if (p) {
-
-#if !defined(NDEBUG)
-		/* Verify that no more than two scratch allocation per thread
-		 * is outstanding at one time.  (This is only checked in the
-		 * single-threaded case since checking in the multi-threaded case
-		 * would be much more complicated.)
-		 */
-		assert(scratchAllocOut >= 1 && scratchAllocOut <= 2);
-		scratchAllocOut--;
-#endif
-
-		if (SQL_WITHIN
-		    (p, sqlGlobalConfig.pScratch, mem0.pScratchEnd)) {
-			/* Release memory from the SQL_CONFIG_SCRATCH allocation */
-			ScratchFreeslot *pSlot;
-			pSlot = (ScratchFreeslot *) p;
-			pSlot->pNext = mem0.pScratchFree;
-			mem0.pScratchFree = pSlot;
-			mem0.nScratchFree++;
-			assert(mem0.nScratchFree <=
-			       (u32) sqlGlobalConfig.nScratch);
-			sqlStatusDown(SQL_STATUS_SCRATCH_USED, 1);
-		} else {
-			/* Release memory back to the heap */
-			if (sqlGlobalConfig.bMemstat) {
-				int iSize = sqlMallocSize(p);
-				sqlStatusDown
-				    (SQL_STATUS_SCRATCH_OVERFLOW, iSize);
-				sqlStatusDown(SQL_STATUS_MEMORY_USED,
-						  iSize);
-				sqlStatusDown(SQL_STATUS_MALLOC_COUNT,
-						  1);
-				sql_sized_free(p);
-			} else
-				sql_sized_free(p);
-		}
-	}
-}
-
-/*
  * Return the size of a memory allocation previously obtained from
  * sqlMalloc() or sql_malloc().
  */
@@ -432,12 +239,6 @@ sqlDbMallocSize(void *p)
 	return sql_sized_sizeof(p);
 }
 
-sql_uint64
-sql_msize(void *p)
-{
-	return p ? sql_sized_sizeof(p) : 0;
-}
-
 /*
  * Free memory previously obtained from sqlMalloc().
  */
@@ -489,7 +290,7 @@ sqlDbFree(sql * db, void *p)
 void *
 sqlRealloc(void *pOld, u64 nBytes)
 {
-	int nOld, nNew, nDiff;
+	int nOld, nNew;
 	void *pNew;
 	if (pOld == 0) {
 		return sqlMalloc(nBytes);	/* IMP: R-04300-56712 */
@@ -508,17 +309,7 @@ sqlRealloc(void *pOld, u64 nBytes)
 		pNew = pOld;
 	} else if (sqlGlobalConfig.bMemstat) {
 		sqlStatusHighwater(SQL_STATUS_MALLOC_SIZE, (int)nBytes);
-		nDiff = nNew - nOld;
-		if (nDiff > 0
-		    && sqlStatusValue(SQL_STATUS_MEMORY_USED) >=
-		    mem0.alarmThreshold - nDiff) {
-			sqlMallocAlarm(nDiff);
-		}
 		pNew = sql_sized_realloc(pOld, nNew);
-		if (pNew == 0 && mem0.alarmThreshold > 0) {
-			sqlMallocAlarm((int)nBytes);
-			pNew = sql_sized_realloc(pOld, nNew);
-		}
 		if (pNew) {
 			nNew = sqlMallocSize(pNew);
 			sqlStatusUp(SQL_STATUS_MEMORY_USED, nNew - nOld);
@@ -530,18 +321,6 @@ sqlRealloc(void *pOld, u64 nBytes)
 	return pNew;
 }
 
-/*
- * The public interface to sqlRealloc.  Make sure that the memory
- * subsystem is initialized prior to invoking sqlRealloc.
- */
-void *
-sql_realloc(void *pOld, int n)
-{
-	if (n < 0)
-		n = 0;		/* IMP: R-26507-47431 */
-	return sqlRealloc(pOld, n);
-}
-
 void *
 sql_realloc64(void *pOld, sql_uint64 n)
 {
@@ -717,16 +496,6 @@ sqlDbStrNDup(sql * db, const char *z, u64 n)
 }
 
 /*
- * Free any prior content in *pz and replace it with a copy of zNew.
- */
-void
-sqlSetString(char **pz, sql * db, const char *zNew)
-{
-	sqlDbFree(db, *pz);
-	*pz = sqlDbStrDup(db, zNew);
-}
-
-/*
  * Call this routine to record the fact that an OOM (out-of-memory) error
  * has happened.  This routine will set db->mallocFailed, and also
  * temporarily disable the lookaside memory allocator and interrupt
@@ -759,16 +528,6 @@ sqlOomClear(sql * db)
 }
 
 /*
- * Take actions at the end of an API call to indicate an OOM error
- */
-static SQL_NOINLINE int
-apiOomError(sql * db)
-{
-	sqlOomClear(db);
-	return -1;
-}
-
-/*
  * This function must be called before exiting any API function (i.e.
  * returning control to the user) that has called sql_malloc or
  * sql_realloc.
@@ -781,7 +540,8 @@ sqlApiExit(sql * db, int rc)
 {
 	assert(db != 0);
 	if (db->mallocFailed) {
-		return apiOomError(db);
+		sqlOomClear(db);
+		return -1;
 	}
 	return rc;
 }
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 3825a2b..27e57cc 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -369,17 +369,11 @@ void *
 sql_malloc64(sql_uint64);
 
 void *
-sql_realloc(void *, int);
-
-void *
 sql_realloc64(void *, sql_uint64);
 
 void
 sql_free(void *);
 
-sql_uint64
-sql_msize(void *);
-
 int
 sql_stricmp(const char *, const char *);
 
@@ -1447,11 +1441,7 @@ struct sql {
  * than being distinct from one another.
  */
 #define SQL_MAGIC_OPEN     0xa029a697	/* Database is open */
-#define SQL_MAGIC_CLOSED   0x9f3c2d33	/* Database is closed */
-#define SQL_MAGIC_SICK     0x4b771290	/* Error and awaiting close */
 #define SQL_MAGIC_BUSY     0xf03b7906	/* Database currently in use */
-#define SQL_MAGIC_ERROR    0xb5357930	/* An sql_MISUSE error occurred */
-#define SQL_MAGIC_ZOMBIE   0x64cffc7f	/* Close with last statement close */
 
 /**
  * SQL type definition. Now it is an alias to type, but in
@@ -2925,7 +2915,6 @@ unsigned sqlStrlen30(const char *);
 #define sqlStrNICmp sql_strnicmp
 
 void sqlMallocInit(void);
-void sqlMallocEnd(void);
 void *sqlMalloc(u64);
 void *sqlMallocZero(u64);
 void *sqlDbMallocZero(sql *, u64);
@@ -2939,15 +2928,12 @@ void *sqlDbRealloc(sql *, void *, u64);
 void sqlDbFree(sql *, void *);
 int sqlMallocSize(void *);
 int sqlDbMallocSize(void *);
-void *sqlScratchMalloc(int);
-void sqlScratchFree(void *);
 void *sqlPageMalloc(int);
 void sqlPageFree(void *);
 void sqlMemSetDefault(void);
 #ifndef SQL_UNTESTABLE
 void sqlBenignMallocHooks(void (*)(void), void (*)(void));
 #endif
-int sqlHeapNearlyFull(void);
 
 /*
  * On systems with ample stack space and that support alloca(), make
@@ -2967,7 +2953,6 @@ int sqlHeapNearlyFull(void);
 #define sqlStackFree(D,P)       sqlDbFree(D,P)
 #endif
 
-sql_int64 sqlStatusValue(int);
 void sqlStatusUp(int, int);
 void sqlStatusDown(int, int);
 void sqlStatusHighwater(int, int);
@@ -3003,7 +2988,6 @@ void sqlTreeViewSelect(TreeView *, const Select *, u8);
 void sqlTreeViewWith(TreeView *, const With *);
 #endif
 
-void sqlSetString(char **, sql *, const char *);
 void sqlDequote(char *);
 
 /**
diff --git a/src/box/sql/status.c b/src/box/sql/status.c
index d6de484..9e56836 100644
--- a/src/box/sql/status.c
+++ b/src/box/sql/status.c
@@ -62,18 +62,6 @@ static SQL_WSD struct sqlStatType {
 #define wsdStat sqlStat
 
 /*
- * Return the current value of a status parameter.
- */
-sql_int64
-sqlStatusValue(int op)
-{
-	wsdStatInit;
-	assert(op >= 0 && op < ArraySize(wsdStat.nowValue));
-
-	return wsdStat.nowValue[op];
-}
-
-/*
  * Add N to the value of a status record.
  *
  * The StatusUp() routine can accept positive or negative values for N.
@@ -125,140 +113,3 @@ sqlStatusHighwater(int op, int X)
 		wsdStat.mxValue[op] = newValue;
 	}
 }
-
-/*
- * Query status information for a single database connection
- */
-int
-sql_db_status(sql * db,	/* The database connection whose status is desired */
-		  int op,	/* Status verb */
-		  int *pCurrent,	/* Write current value here */
-		  int *pHighwater,	/* Write high-water mark here */
-		  int resetFlag	/* Reset high-water mark if true */
-    )
-{
-	int rc = 0;	/* Return code */
-	switch (op) {
-	case SQL_DBSTATUS_LOOKASIDE_USED:{
-			*pCurrent = db->lookaside.nOut;
-			*pHighwater = db->lookaside.mxOut;
-			if (resetFlag) {
-				db->lookaside.mxOut = db->lookaside.nOut;
-			}
-			break;
-		}
-
-	case SQL_DBSTATUS_LOOKASIDE_HIT:
-	case SQL_DBSTATUS_LOOKASIDE_MISS_SIZE:
-	case SQL_DBSTATUS_LOOKASIDE_MISS_FULL:{
-			testcase(op == SQL_DBSTATUS_LOOKASIDE_HIT);
-			testcase(op == SQL_DBSTATUS_LOOKASIDE_MISS_SIZE);
-			testcase(op == SQL_DBSTATUS_LOOKASIDE_MISS_FULL);
-			assert((op - SQL_DBSTATUS_LOOKASIDE_HIT) >= 0);
-			assert((op - SQL_DBSTATUS_LOOKASIDE_HIT) < 3);
-			*pCurrent = 0;
-			*pHighwater =
-			    db->lookaside.anStat[op -
-						 SQL_DBSTATUS_LOOKASIDE_HIT];
-			if (resetFlag) {
-				db->lookaside.anStat[op -
-						     SQL_DBSTATUS_LOOKASIDE_HIT]
-				    = 0;
-			}
-			break;
-		}
-
-		/*
-		 * Return an approximation for the amount of memory currently used
-		 * by all pagers associated with the given database connection.  The
-		 * highwater mark is meaningless and is returned as zero.
-		 */
-	case SQL_DBSTATUS_CACHE_USED_SHARED:
-	case SQL_DBSTATUS_CACHE_USED:{
-			int totalUsed = 0;
-			*pCurrent = totalUsed;
-			*pHighwater = 0;
-			break;
-		}
-
-		/*
-		 * *pCurrent gets an accurate estimate of the amount of memory used
-		 * to store the schema for database. *pHighwater is set to zero.
-		 */
-	case SQL_DBSTATUS_SCHEMA_USED:{
-			int nByte = 0;	/* Used to accumulate return value */
-
-			*pHighwater = 0;
-			*pCurrent = nByte;
-			break;
-		}
-
-		/*
-		 * *pCurrent gets an accurate estimate of the amount of memory used
-		 * to store all prepared statements.
-		 * *pHighwater is set to zero.
-		 */
-	case SQL_DBSTATUS_STMT_USED:{
-			struct Vdbe *pVdbe;	/* Used to iterate through VMs */
-			int nByte = 0;	/* Used to accumulate return value */
-
-			db->pnBytesFreed = &nByte;
-			for (pVdbe = db->pVdbe; pVdbe; pVdbe = pVdbe->pNext) {
-				sqlVdbeClearObject(db, pVdbe);
-				sqlDbFree(db, pVdbe);
-			}
-			db->pnBytesFreed = 0;
-
-			*pHighwater = 0;	/* IMP: R-64479-57858
-			*/
-			*pCurrent = nByte;
-
-			break;
-		}
-
-		/*
-		 * Set *pCurrent to the total cache hits or misses encountered by all
-		 * pagers the database handle is connected to. *pHighwater is always set
-		 * to zero.
-		 */
-	case SQL_DBSTATUS_CACHE_HIT:
-	case SQL_DBSTATUS_CACHE_MISS:
-	case SQL_DBSTATUS_CACHE_WRITE:{
-			int nRet = 0;
-			assert(SQL_DBSTATUS_CACHE_MISS ==
-			       SQL_DBSTATUS_CACHE_HIT + 1);
-			assert(SQL_DBSTATUS_CACHE_WRITE ==
-			       SQL_DBSTATUS_CACHE_HIT + 2);
-
-			*pHighwater = 0;	/* IMP: R-42420-56072
-			*/
-			/* IMP: R-54100-20147 */
-			/* IMP: R-29431-39229 */
-			*pCurrent = nRet;
-			break;
-		}
-
-		/* Set *pCurrent to non-zero if there are unresolved deferred foreign
-		 * key constraints.  Set *pCurrent to zero if all foreign key constraints
-		 * have been satisfied.  The *pHighwater is always set to zero.
-		 */
-	case SQL_DBSTATUS_DEFERRED_FKS:{
-			*pHighwater = 0;	/* IMP: R-11967-56545
-			*/
-			const struct txn *ptxn = in_txn();
-
-			if (!ptxn || !ptxn->psql_txn) {
-				*pCurrent = 0;
-				break;
-			}
-			const struct sql_txn *psql_txn = ptxn->psql_txn;
-			*pCurrent = psql_txn->fk_deferred_count > 0;
-			break;
-		}
-
-	default:{
-			rc = -1;
-		}
-	}
-	return rc;
-}
diff --git a/src/box/sql/tokenize.c b/src/box/sql/tokenize.c
index ea364de..32e4fd6 100644
--- a/src/box/sql/tokenize.c
+++ b/src/box/sql/tokenize.c
@@ -514,11 +514,6 @@ sqlRunParser(Parse * pParse, const char *zSql)
 		}
 	}
 	pParse->zTail = &zSql[i];
-#ifdef YYTRACKMAXSTACKDEPTH
-	sqlStatusHighwater(SQL_STATUS_PARSER_STACK,
-			       sqlParserStackPeak(pEngine)
-	    );
-#endif				/* YYDEBUG */
 	sqlParserFree(pEngine, sql_free);
 	if (db->mallocFailed)
 		pParse->is_aborted = true;
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 4204637..1534026 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -226,10 +226,6 @@ allocateCursor(
 	 *     different sized allocations. Memory cells provide growable
 	 *     allocations.
 	 *
-	 *   * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can
-	 *     be freed lazily via the sql_release_memory() API. This
-	 *     minimizes the number of malloc calls made by the system.
-	 *
 	 * The memory cell for cursor 0 is aMem[0]. The rest are allocated from
 	 * the top of the register space.  Cursor 1 is at Mem[p->nMem-1].
 	 * Cursor 2 is at Mem[p->nMem-2]. And so forth.
diff --git a/src/box/sql/vdbesort.c b/src/box/sql/vdbesort.c
index 7caf13b..0af9d0c 100644
--- a/src/box/sql/vdbesort.c
+++ b/src/box/sql/vdbesort.c
@@ -1778,9 +1778,6 @@ sqlVdbeSorterWrite(const VdbeCursor * pCsr,	/* Sorter cursor */
 	 *
 	 *   * The total memory allocated for the in-memory list is greater
 	 *     than (page-size * cache-size), or
-	 *
-	 *   * The total memory allocated for the in-memory list is greater
-	 *     than (page-size * 10) and sqlHeapNearlyFull() returns true.
 	 */
 	nReq = pVal->n + sizeof(SorterRecord);
 	nPMA = pVal->n + sqlVarintLen(pVal->n);
@@ -1789,10 +1786,7 @@ sqlVdbeSorterWrite(const VdbeCursor * pCsr,	/* Sorter cursor */
 			bFlush = pSorter->iMemory
 			    && (pSorter->iMemory + nReq) > pSorter->mxPmaSize;
 		} else {
-			bFlush = ((pSorter->list.szPMA > pSorter->mxPmaSize)
-				  || (pSorter->list.szPMA > pSorter->mnPmaSize
-				      && sqlHeapNearlyFull())
-			    );
+			bFlush = ((pSorter->list.szPMA > pSorter->mxPmaSize));
 		}
 		if (bFlush) {
 			rc = vdbeSorterFlushPMA(pSorter);
-- 
2.7.4





More information about the Tarantool-patches mailing list