/ Check-in [3f0a0ff1]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Update the per-thread bytes allocated counter with the number of bytes actually allocated, not the number requested. Ticket #1660. (CVS 3056)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3f0a0ff1973079956506daaba9b21912fc76982b
User & Date: danielk1977 2006-02-06 13:59:43
Context
2006-02-06
21:22
Keep correct track of the amount of outstanding memory even when the system memory allocator returns a different number of bytes than requested. Ticket #1660. (CVS 3057) check-in: 6f5eb74f user: drh tags: trunk
13:59
Update the per-thread bytes allocated counter with the number of bytes actually allocated, not the number requested. Ticket #1660. (CVS 3056) check-in: 3f0a0ff1 user: danielk1977 tags: trunk
2006-02-05
18:55
Detect circularly defined views and issue an error message. Ticket #1658. (CVS 3055) check-in: f5341529 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
138
139
140
141
142
143
144







145
146
147
148
149
150
151
...
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
...
444
445
446
447
448
449
450

451
452
453
454
455
456
457
...
485
486
487
488
489
490
491

492
493


494
495

496
497
498
499
500
501
502
...
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590


591

592
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607
608
609
610
611
612
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.182 2006/01/23 15:39:59 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*
................................................................................
** Size reserved for storing the user string. Each time a Malloc() or Realloc()
** call succeeds, up to TESTALLOC_USERSIZE bytes of the string pointed to by
** sqlite3_malloc_id are stored along with the other test system metadata.
*/
#define TESTALLOC_USERSIZE 64
const char *sqlite3_malloc_id = 0;








/*
** Blocks used by the test layer have the following format:
**
**        <sizeof(void *) pNext pointer>
**        <sizeof(void *) pPrev pointer>
**        <TESTALLOC_NGUARD 32-bit guard words>
**            <The application level allocation>
................................................................................
#if defined(TCLSH) && defined(SQLITE_DEBUG) && SQLITE_MEMDEBUG>1
#include <tcl.h>
int sqlite3OutstandingMallocs(Tcl_Interp *interp){
  void *p;
  Tcl_Obj *pRes = Tcl_NewObj();
  Tcl_IncrRefCount(pRes);


  for(p=sqlite3_pFirst; p; p=((void **)p)[1]){
    Tcl_Obj *pEntry = Tcl_NewObj();
    Tcl_Obj *pStack = Tcl_NewObj();
    char *z;
    u32 iLine;
    int nBytes = sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD;
    char *zAlloc = (char *)p;
................................................................................
*/
static void * OSMALLOC(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  sqlite3_nMaxAlloc = 
      MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc);
#endif
  assert( !sqlite3_mallocDisallowed );

  if( !sqlite3TestMallocFail() ){
    u32 *p;
    p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD);
    assert(p);
    sqlite3_nMalloc++;
    applyGuards(p);
    linkAlloc(p);
................................................................................
** This is the test layer's wrapper around sqlite3OsRealloc().
*/
static void * OSREALLOC(void *pRealloc, int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  sqlite3_nMaxAlloc = 
      MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc);
#endif

  assert( !sqlite3_mallocDisallowed );
  if( !sqlite3TestMallocFail() ){


    u32 *p = (u32 *)getOsPointer(pRealloc);
    checkGuards(p);

    p = sqlite3OsRealloc(p, n + TESTALLOC_OVERHEAD);
    applyGuards(p);
    relinkAlloc(p);
    return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]);
  }
  return 0;
}
................................................................................
/*
** Allocate and return N bytes of uninitialised memory by calling
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
** by calling sqlite3_release_memory().
*/
void *sqlite3MallocRaw(int n){
  void *p = 0;
  if( n>0 && !sqlite3MallocFailed() && !handleSoftLimit(n) ){
    while( (p = OSMALLOC(n))==0 && sqlite3_release_memory(n) );
    if( !p ){
      /* If the allocation failed, call handleSoftLimit() again, this time
      ** with the additive inverse of the argument passed to 
      ** handleSoftLimit() above. This is so the ThreadData.nAlloc variable is
      ** still correct after a malloc() failure. 
      */
      (void)handleSoftLimit(n * -1);

      sqlite3FailedMalloc();
      OSMALLOC_FAILED();
    }
  }
  return p;
}

/*
** Resize the allocation at p to n bytes by calling sqlite3OsRealloc(). The
** pointer to the new allocation is returned.  If the Realloc() call fails,
** attempt to free memory by calling sqlite3_release_memory().
*/
void *sqlite3Realloc(void *p, int n){
  if( sqlite3MallocFailed() ){
    return 0;
  }

  if( !p ){
    return sqlite3Malloc(n);
  }else{
    void *np = 0;


    if( !handleSoftLimit(n - OSSIZEOF(p)) ){

      while( (np = OSREALLOC(p, n))==0 && sqlite3_release_memory(n) );
      if( !np ){
        /* If the allocation failed, call handleSoftLimit() again, this time
        ** with the additive inverse of the argument passed to 
        ** handleSoftLimit() above. This is so the ThreadData.nAlloc variable is
        ** still correct after a malloc() failure. 
        */
        (void)handleSoftLimit(OSSIZEOF(p) - n);

        sqlite3FailedMalloc();
        OSMALLOC_FAILED();
      }
    }
    return np;
  }
}

/*
** Free the memory pointed to by p. p must be either a NULL pointer or a 
** value returned by a previous call to sqlite3Malloc() or sqlite3Realloc().
*/
void sqlite3FreeX(void *p){







|







 







>
>
>
>
>
>
>







 







<







 







>







 







>


>
>
|
|
>







 







|

<
<
<
<
<
<
|
>













<
<
<
<
<
<
<
|
>
>
|
>
|
<
<
<
<
<
<
|
>
|
|
|
|
|
<







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
...
402
403
404
405
406
407
408

409
410
411
412
413
414
415
...
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
...
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
...
565
566
567
568
569
570
571
572
573






574
575
576
577
578
579
580
581
582
583
584
585
586
587
588







589
590
591
592
593
594






595
596
597
598
599
600
601

602
603
604
605
606
607
608
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.183 2006/02/06 13:59:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*
................................................................................
** Size reserved for storing the user string. Each time a Malloc() or Realloc()
** call succeeds, up to TESTALLOC_USERSIZE bytes of the string pointed to by
** sqlite3_malloc_id are stored along with the other test system metadata.
*/
#define TESTALLOC_USERSIZE 64
const char *sqlite3_malloc_id = 0;

/*
** Always allocate blocks to be a multiple of the following size in bytes.
** For example, if TESTALLOC_QUANTA is 8 and a block of 21 bytes is 
** requested, return a pointer to a block of 24 bytes.
*/
#define TESTALLOC_QUANTA 8

/*
** Blocks used by the test layer have the following format:
**
**        <sizeof(void *) pNext pointer>
**        <sizeof(void *) pPrev pointer>
**        <TESTALLOC_NGUARD 32-bit guard words>
**            <The application level allocation>
................................................................................
#if defined(TCLSH) && defined(SQLITE_DEBUG) && SQLITE_MEMDEBUG>1
#include <tcl.h>
int sqlite3OutstandingMallocs(Tcl_Interp *interp){
  void *p;
  Tcl_Obj *pRes = Tcl_NewObj();
  Tcl_IncrRefCount(pRes);


  for(p=sqlite3_pFirst; p; p=((void **)p)[1]){
    Tcl_Obj *pEntry = Tcl_NewObj();
    Tcl_Obj *pStack = Tcl_NewObj();
    char *z;
    u32 iLine;
    int nBytes = sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD;
    char *zAlloc = (char *)p;
................................................................................
*/
static void * OSMALLOC(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  sqlite3_nMaxAlloc = 
      MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc);
#endif
  assert( !sqlite3_mallocDisallowed );
  n += (TESTALLOC_QUANTA - (n % TESTALLOC_QUANTA)) % TESTALLOC_QUANTA;
  if( !sqlite3TestMallocFail() ){
    u32 *p;
    p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD);
    assert(p);
    sqlite3_nMalloc++;
    applyGuards(p);
    linkAlloc(p);
................................................................................
** This is the test layer's wrapper around sqlite3OsRealloc().
*/
static void * OSREALLOC(void *pRealloc, int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  sqlite3_nMaxAlloc = 
      MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc);
#endif
  n += (TESTALLOC_QUANTA - (n % TESTALLOC_QUANTA)) % TESTALLOC_QUANTA;
  assert( !sqlite3_mallocDisallowed );
  if( !sqlite3TestMallocFail() ){
    u32 *p = 0;
    if( pRealloc ){
      u32 *p = (u32 *)getOsPointer(pRealloc);
      checkGuards(p);
    }
    p = sqlite3OsRealloc(p, n + TESTALLOC_OVERHEAD);
    applyGuards(p);
    relinkAlloc(p);
    return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]);
  }
  return 0;
}
................................................................................
/*
** Allocate and return N bytes of uninitialised memory by calling
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
** by calling sqlite3_release_memory().
*/
void *sqlite3MallocRaw(int n){
  void *p = 0;
  if( n>0 && !sqlite3MallocFailed() ){
    while( (p = OSMALLOC(n))==0 && sqlite3_release_memory(n) );






    if( !p || handleSoftLimit(OSSIZEOF(p)) ){
      OSFREE(p);
      sqlite3FailedMalloc();
      OSMALLOC_FAILED();
    }
  }
  return p;
}

/*
** Resize the allocation at p to n bytes by calling sqlite3OsRealloc(). The
** pointer to the new allocation is returned.  If the Realloc() call fails,
** attempt to free memory by calling sqlite3_release_memory().
*/
void *sqlite3Realloc(void *p, int n){







  void *np = 0;
  if( !sqlite3MallocFailed() ){
#ifndef SQLITE_ENABLE_MEMORY_MANAGEMENT
    int oldsize = OSSIZEOF(p);
#endif
    while( (np = OSREALLOC(p, n))==0 && sqlite3_release_memory(n) );






    if( !np || handleSoftLimit(OSSIZEOF(np) - oldsize) ){
      OSFREE(np);
      sqlite3FailedMalloc();
      OSMALLOC_FAILED();
    }
  }
  return np;

}

/*
** Free the memory pointed to by p. p must be either a NULL pointer or a 
** value returned by a previous call to sqlite3Malloc() or sqlite3Realloc().
*/
void sqlite3FreeX(void *p){