/ Check-in [f69ce75b]
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 | 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
21:50
Back out the use of __sync_fetch_and_sub() as it does not appear to work. Closed-Leaf check-in: 4c2efd42 user: drh tags: gnu-safe-math
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 Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/malloc.c.

   372    372       }else{
   373    373         /* Release memory back to the heap */
   374    374         assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
   375    375         assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) );
   376    376         sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
   377    377         if( sqlite3GlobalConfig.bMemstat ){
   378    378           int iSize = sqlite3MallocSize(p);
          379  +#ifndef SQLITE_ATOMIC_STATUS_DOWN
   379    380           sqlite3_mutex_enter(mem0.mutex);
          381  +#endif
   380    382           sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize);
   381    383           sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize);
   382    384           sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
   383    385           sqlite3GlobalConfig.m.xFree(p);
          386  +#ifndef SQLITE_ATOMIC_STATUS_DOWN
   384    387           sqlite3_mutex_leave(mem0.mutex);
          388  +#endif
   385    389         }else{
   386    390           sqlite3GlobalConfig.m.xFree(p);
   387    391         }
   388    392       }
   389    393     }
   390    394   }
   391    395   
................................................................................
   436    440   ** Free memory previously obtained from sqlite3Malloc().
   437    441   */
   438    442   void sqlite3_free(void *p){
   439    443     if( p==0 ) return;  /* IMP: R-49053-54554 */
   440    444     assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
   441    445     assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
   442    446     if( sqlite3GlobalConfig.bMemstat ){
          447  +#ifndef SQLITE_ATOMIC_STATUS_DOWN
   443    448       sqlite3_mutex_enter(mem0.mutex);
          449  +#endif
   444    450       sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
   445    451       sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
   446    452       sqlite3GlobalConfig.m.xFree(p);
          453  +#ifndef SQLITE_ATOMIC_STATUS_DOWN
   447    454       sqlite3_mutex_leave(mem0.mutex);
          455  +#endif
   448    456     }else{
   449    457       sqlite3GlobalConfig.m.xFree(p);
   450    458     }
   451    459   }
   452    460   
   453    461   /*
   454    462   ** Add the size of memory allocation "p" to the count in

Changes to src/sqliteInt.h.

   224    224   #  define SQLITE_NOINLINE  __attribute__((noinline))
   225    225   #elif defined(_MSC_VER) && _MSC_VER>=1310
   226    226   #  define SQLITE_NOINLINE  __declspec(noinline)
   227    227   #else
   228    228   #  define SQLITE_NOINLINE
   229    229   #endif
   230    230   
          231  +/*
          232  +** The SQLITE_ATOMIC_STATUS_DOWN macro is defined if and only if
          233  +** the sqlite3StatusDown() function is threadsafe.
          234  +*/
          235  +#if !defined(SQLITE_DISABLE_INTRINSIC) \
          236  +    && defined(__GNUC__) && GCC_VERSION>=4004000
          237  +# define SQLITE_ATOMIC_STATUS_DOWN 1
          238  +#endif
          239  +
   231    240   /*
   232    241   ** Make sure that the compiler intrinsics we desire are enabled when
   233    242   ** compiling with an appropriate version of MSVC unless prevented by
   234    243   ** the SQLITE_DISABLE_INTRINSIC define.
   235    244   */
   236    245   #if !defined(SQLITE_DISABLE_INTRINSIC)
   237    246   #  if defined(_MSC_VER) && _MSC_VER>=1400

Changes to src/status.c.

    96     96     if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
    97     97       wsdStat.mxValue[op] = wsdStat.nowValue[op];
    98     98     }
    99     99   }
   100    100   void sqlite3StatusDown(int op, int N){
   101    101     wsdStatInit;
   102    102     assert( N>=0 );
          103  +  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
          104  +#if !defined(SQLITE_DISABLE_INTRINSIC) \
          105  +    && defined(__GNUC__) && GCC_VERSION>=4004000
          106  +  (void)__sync_fetch_and_sub(&wsdStat.nowValue[op], N);
          107  +#else
   103    108     assert( op>=0 && op<ArraySize(statMutex) );
   104    109     assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
   105    110                                              : sqlite3MallocMutex()) );
   106         -  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
   107    111     wsdStat.nowValue[op] -= N;
          112  +#endif
   108    113   }
   109    114   
   110    115   /*
   111    116   ** Adjust the highwater mark if necessary.
   112    117   ** The caller must hold the appropriate mutex.
   113    118   */
   114    119   void sqlite3StatusHighwater(int op, int X){