SQLite

Check-in [33c7ef7aca]
Login

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

Overview
Comment:Add calls to sqlite3_log() when sqlite3_mutex_enter() takes more than 100,000 CPU cycles.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | debug
Files: files | file ages | folders
SHA1: 33c7ef7aca69f9b714bc25b2af5ae2a189d3ba78
User & Date: drh 2016-07-29 14:10:43.773
Context
2016-07-29
14:23
Use __sync_synchronous(), when available, instead of a mutex when a memory barrier is needed. (check-in: 7d4562e9d5 user: drh tags: debug)
14:10
Add calls to sqlite3_log() when sqlite3_mutex_enter() takes more than 100,000 CPU cycles. (check-in: 33c7ef7aca user: drh tags: debug)
2016-07-16
11:47
Temporarily add extra sqlite3_log() calls to this version to help with debugging a performance problem. (check-in: 613c1ceaf4 user: dan tags: debug)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/mutex_unix.c.
196
197
198
199
200
201
202







203
204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
static void pthreadMutexFree(sqlite3_mutex *p){
  assert( p->nRef==0 );
  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
  pthread_mutex_destroy(&p->mutex);
  sqlite3_free(p);
}








/*
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
** be entered multiple times by the same thread.  In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter.  If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/
static void pthreadMutexEnter(sqlite3_mutex *p){

  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );

#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  /* If recursive mutexes are not available, then we have to grow
  ** our own.  This implementation assumes that pthread_equal()
  ** is atomic - that it cannot be deceived into thinking self
  ** and p->owner are equal if p->owner changes between two values







>
>
>
>
>
>
>












>







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
static void pthreadMutexFree(sqlite3_mutex *p){
  assert( p->nRef==0 );
  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
  pthread_mutex_destroy(&p->mutex);
  sqlite3_free(p);
}

#include "hwtime.h"
#ifdef SQLITE_MUTEX_NREF
# define MUTEX_ID(p)  (p->id)
#else
# define MUTEX_ID(p)  0
#endif

/*
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
** be entered multiple times by the same thread.  In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter.  If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/
static void pthreadMutexEnter(sqlite3_mutex *p){
  sqlite3_uint64 iTimer = sqlite3Hwtime();
  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );

#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
  /* If recursive mutexes are not available, then we have to grow
  ** our own.  This implementation assumes that pthread_equal()
  ** is atomic - that it cannot be deceived into thinking self
  ** and p->owner are equal if p->owner changes between two values
241
242
243
244
245
246
247





248
249
250
251
252
253
254
  */
  pthread_mutex_lock(&p->mutex);
#if SQLITE_MUTEX_NREF
  assert( p->nRef>0 || p->owner==0 );
  p->owner = pthread_self();
  p->nRef++;
#endif





#endif

#ifdef SQLITE_DEBUG
  if( p->trace ){
    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
  }
#endif







>
>
>
>
>







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  */
  pthread_mutex_lock(&p->mutex);
#if SQLITE_MUTEX_NREF
  assert( p->nRef>0 || p->owner==0 );
  p->owner = pthread_self();
  p->nRef++;
#endif
  iTimer = sqlite3Hwtime() - iTimer;
  if( iTimer>100000 ){
    sqlite3_log(SQLITE_NOTICE, "slow mutex: %lld cycles on %d/%p",
                iTimer, MUTEX_ID(p), p);
  }
#endif

#ifdef SQLITE_DEBUG
  if( p->trace ){
    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
  }
#endif