/ Check-in [f69ce75b]
Login
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 | SQL 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
Context
2017-01-03
20:01
Use the CLANG_VERSION macro to control clang-specific features. check-in: f8ebeec2 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: f69ce75b 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: 82cbebb8 user: drh tags: gnu-safe-math
Changes
Hide Diffs Unified Diffs 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
...
436
437
438
439
440
441
442

443

444
445
446

447

448
449
450
451
452
453
454
    }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);
      }
    }
  }
}

................................................................................
** 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







>

>




>

>







 







>

>



>

>







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
    }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);
      }
    }
  }
}

................................................................................
** 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){