SQLite

Check-in [f69ce75b3d]
Login

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

Overview
Comment:Use the GCC built-in __sync_fetch_and_sub() to make the sqlite3StatusDown() routine atomic, and thereby avoid some mutexing.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | gnu-safe-math
Files: files | file ages | folders
SHA1: f69ce75b3d94331fdbfa2f3a27d61db24c285d2b
User & Date: drh 2017-01-03 18:05:04.175
Context
2017-01-03
21:50
Back out the use of __sync_fetch_and_sub() as it does not appear to work. (Closed-Leaf check-in: 4c2efd4239 user: drh tags: gnu-safe-math)
20:01
Use the CLANG_VERSION macro to control clang-specific features. (check-in: f8ebeec211 user: drh tags: gnu-safe-math)
18:05
Use the GCC built-in __sync_fetch_and_sub() to make the sqlite3StatusDown() routine atomic, and thereby avoid some mutexing. (check-in: f69ce75b3d user: drh tags: gnu-safe-math)
17:33
Make use of the __buildin_OP_overflow() functions from GCC when doing 64-bit signed integer arithmetic. (check-in: 82cbebb8ee user: drh tags: gnu-safe-math)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/malloc.c.
372
373
374
375
376
377
378

379

380
381
382
383

384

385
386
387
388
389
390
391
    }else{
      /* Release memory back to the heap */
      assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
      assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) );
      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
      if( sqlite3GlobalConfig.bMemstat ){
        int iSize = sqlite3MallocSize(p);

        sqlite3_mutex_enter(mem0.mutex);

        sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize);
        sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize);
        sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
        sqlite3GlobalConfig.m.xFree(p);

        sqlite3_mutex_leave(mem0.mutex);

      }else{
        sqlite3GlobalConfig.m.xFree(p);
      }
    }
  }
}








>

>




>

>







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
    }else{
      /* Release memory back to the heap */
      assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
      assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) );
      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
      if( sqlite3GlobalConfig.bMemstat ){
        int iSize = sqlite3MallocSize(p);
#ifndef SQLITE_ATOMIC_STATUS_DOWN
        sqlite3_mutex_enter(mem0.mutex);
#endif
        sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize);
        sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize);
        sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
        sqlite3GlobalConfig.m.xFree(p);
#ifndef SQLITE_ATOMIC_STATUS_DOWN
        sqlite3_mutex_leave(mem0.mutex);
#endif
      }else{
        sqlite3GlobalConfig.m.xFree(p);
      }
    }
  }
}

436
437
438
439
440
441
442

443

444
445
446

447

448
449
450
451
452
453
454
** Free memory previously obtained from sqlite3Malloc().
*/
void sqlite3_free(void *p){
  if( p==0 ) return;  /* IMP: R-49053-54554 */
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
  if( sqlite3GlobalConfig.bMemstat ){

    sqlite3_mutex_enter(mem0.mutex);

    sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
    sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
    sqlite3GlobalConfig.m.xFree(p);

    sqlite3_mutex_leave(mem0.mutex);

  }else{
    sqlite3GlobalConfig.m.xFree(p);
  }
}

/*
** Add the size of memory allocation "p" to the count in







>

>



>

>







440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
** Free memory previously obtained from sqlite3Malloc().
*/
void sqlite3_free(void *p){
  if( p==0 ) return;  /* IMP: R-49053-54554 */
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
  if( sqlite3GlobalConfig.bMemstat ){
#ifndef SQLITE_ATOMIC_STATUS_DOWN
    sqlite3_mutex_enter(mem0.mutex);
#endif
    sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
    sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
    sqlite3GlobalConfig.m.xFree(p);
#ifndef SQLITE_ATOMIC_STATUS_DOWN
    sqlite3_mutex_leave(mem0.mutex);
#endif
  }else{
    sqlite3GlobalConfig.m.xFree(p);
  }
}

/*
** Add the size of memory allocation "p" to the count in
Changes to src/sqliteInt.h.
224
225
226
227
228
229
230









231
232
233
234
235
236
237
#  define SQLITE_NOINLINE  __attribute__((noinline))
#elif defined(_MSC_VER) && _MSC_VER>=1310
#  define SQLITE_NOINLINE  __declspec(noinline)
#else
#  define SQLITE_NOINLINE
#endif










/*
** Make sure that the compiler intrinsics we desire are enabled when
** compiling with an appropriate version of MSVC unless prevented by
** the SQLITE_DISABLE_INTRINSIC define.
*/
#if !defined(SQLITE_DISABLE_INTRINSIC)
#  if defined(_MSC_VER) && _MSC_VER>=1400







>
>
>
>
>
>
>
>
>







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#  define SQLITE_NOINLINE  __attribute__((noinline))
#elif defined(_MSC_VER) && _MSC_VER>=1310
#  define SQLITE_NOINLINE  __declspec(noinline)
#else
#  define SQLITE_NOINLINE
#endif

/*
** The SQLITE_ATOMIC_STATUS_DOWN macro is defined if and only if
** the sqlite3StatusDown() function is threadsafe.
*/
#if !defined(SQLITE_DISABLE_INTRINSIC) \
    && defined(__GNUC__) && GCC_VERSION>=4004000
# define SQLITE_ATOMIC_STATUS_DOWN 1
#endif

/*
** Make sure that the compiler intrinsics we desire are enabled when
** compiling with an appropriate version of MSVC unless prevented by
** the SQLITE_DISABLE_INTRINSIC define.
*/
#if !defined(SQLITE_DISABLE_INTRINSIC)
#  if defined(_MSC_VER) && _MSC_VER>=1400
Changes to src/status.c.
96
97
98
99
100
101
102





103
104
105
106
107

108
109
110
111
112
113
114
  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
    wsdStat.mxValue[op] = wsdStat.nowValue[op];
  }
}
void sqlite3StatusDown(int op, int N){
  wsdStatInit;
  assert( N>=0 );





  assert( op>=0 && op<ArraySize(statMutex) );
  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
                                           : sqlite3MallocMutex()) );
  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
  wsdStat.nowValue[op] -= N;

}

/*
** Adjust the highwater mark if necessary.
** The caller must hold the appropriate mutex.
*/
void sqlite3StatusHighwater(int op, int X){







>
>
>
>
>



<

>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
    wsdStat.mxValue[op] = wsdStat.nowValue[op];
  }
}
void sqlite3StatusDown(int op, int N){
  wsdStatInit;
  assert( N>=0 );
  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
#if !defined(SQLITE_DISABLE_INTRINSIC) \
    && defined(__GNUC__) && GCC_VERSION>=4004000
  (void)__sync_fetch_and_sub(&wsdStat.nowValue[op], N);
#else
  assert( op>=0 && op<ArraySize(statMutex) );
  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
                                           : sqlite3MallocMutex()) );

  wsdStat.nowValue[op] -= N;
#endif
}

/*
** Adjust the highwater mark if necessary.
** The caller must hold the appropriate mutex.
*/
void sqlite3StatusHighwater(int op, int X){