/ Check-in [262baee9]
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:Add some test infrastructure and cases for the new mutex api. (CVS 5230)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 262baee9952b28afe5dc77eb7365ebb11a480906
User & Date: danielk1977 2008-06-18 09:45:56
Context
2008-06-18
13:27
Added new configuration options to query the low-level malloc interface and to provide memory buffers for scratch, page-cache, and heap memory allocators. (CVS 5231) check-in: e36201a3 user: drh tags: trunk
09:45
Add some test infrastructure and cases for the new mutex api. (CVS 5230) check-in: 262baee9 user: danielk1977 tags: trunk
02:01
Remove mem3.c and mem5.c from the amalgamation for the time being, since they do not currently work. We will add them back later once they are fixed. (CVS 5229) check-in: 39b4e1ff user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to main.mk.

   222    222     $(TOP)/src/test_btree.c \
   223    223     $(TOP)/src/test_config.c \
   224    224     $(TOP)/src/test_devsym.c \
   225    225     $(TOP)/src/test_func.c \
   226    226     $(TOP)/src/test_hexio.c \
   227    227     $(TOP)/src/test_malloc.c \
   228    228     $(TOP)/src/test_md5.c \
          229  +  $(TOP)/src/test_mutex.c \
   229    230     $(TOP)/src/test_onefile.c \
   230    231     $(TOP)/src/test_osinst.c \
   231    232     $(TOP)/src/test_schema.c \
   232    233     $(TOP)/src/test_server.c \
   233    234     $(TOP)/src/test_tclvar.c \
   234    235     $(TOP)/src/test_thread.c \
   235    236   

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.446 2008/06/17 18:57:49 danielk1977 Exp $
           17  +** $Id: main.c,v 1.447 2008/06/18 09:45:56 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <ctype.h>
    21     21   
    22     22   #ifdef SQLITE_ENABLE_FTS3
    23     23   # include "fts3.h"
    24     24   #endif
................................................................................
   151    151         sqlite3Config.m = *va_arg(ap, sqlite3_mem_methods*);
   152    152         break;
   153    153       }
   154    154       case SQLITE_CONFIG_MUTEX: {
   155    155         /* Specify an alternative mutex implementation */
   156    156         sqlite3Config.mutex = *va_arg(ap, sqlite3_mutex_methods*);
   157    157         break;
          158  +    }
          159  +    case SQLITE_CONFIG_GETMUTEX: {
          160  +      /* Retrieve the current mutex implementation */
          161  +      *va_arg(ap, sqlite3_mutex_methods*) = sqlite3Config.mutex;
          162  +      break;
   158    163       }
   159    164       case SQLITE_CONFIG_MEMSTATUS: {
   160    165         /* Enable or disable the malloc status collection */
   161    166         sqlite3Config.bMemstat = va_arg(ap, int);
   162    167         break;
   163    168       }
   164    169       default: {

Changes to src/mutex.c.

    15     15   ** exclusion and is thus suitable for use only in applications
    16     16   ** that use SQLite in a single thread.  But this implementation
    17     17   ** does do a lot of error checking on mutexes to make sure they
    18     18   ** are called correctly and at appropriate times.  Hence, this
    19     19   ** implementation is suitable for testing.
    20     20   ** debugging purposes
    21     21   **
    22         -** $Id: mutex.c,v 1.22 2008/06/17 18:57:49 danielk1977 Exp $
           22  +** $Id: mutex.c,v 1.23 2008/06/18 09:45:56 danielk1977 Exp $
    23     23   */
    24     24   #include "sqliteInt.h"
    25     25   
    26     26   #ifndef SQLITE_MUTEX_NOOP
    27     27   /*
    28     28   ** Initialize the mutex system.
    29     29   */
................................................................................
   233    233   /*
   234    234   ** The sqlite3_mutex_leave() routine exits a mutex that was
   235    235   ** previously entered by the same thread.  The behavior
   236    236   ** is undefined if the mutex is not currently entered or
   237    237   ** is not currently allocated.  SQLite will never do either.
   238    238   */
   239    239   static void noopMutexLeave(sqlite3_mutex *p){
   240         -  assert( sqlite3_mutex_held(p) );
          240  +  assert( noopMutexHeld(p) );
   241    241     p->cnt--;
   242         -  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
          242  +  assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) );
   243    243   }
   244    244   
   245    245   sqlite3_mutex_methods *sqlite3DefaultMutex(void){
   246    246     static sqlite3_mutex_methods sMutex = {
   247    247       noopMutexInit,
   248    248       noopMutexAlloc,
   249    249       noopMutexFree,

Changes to src/mutex_unix.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains the C functions that implement mutexes for pthreads
    13     13   **
    14         -** $Id: mutex_unix.c,v 1.9 2008/06/17 17:21:18 danielk1977 Exp $
           14  +** $Id: mutex_unix.c,v 1.10 2008/06/18 09:45:56 danielk1977 Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   
    18     18   /*
    19     19   ** The code in this file is only used if we are compiling threadsafe
    20     20   ** under unix with pthreads.
    21     21   **
................................................................................
   281    281   /*
   282    282   ** The sqlite3_mutex_leave() routine exits a mutex that was
   283    283   ** previously entered by the same thread.  The behavior
   284    284   ** is undefined if the mutex is not currently entered or
   285    285   ** is not currently allocated.  SQLite will never do either.
   286    286   */
   287    287   static void pthreadMutexLeave(sqlite3_mutex *p){
   288         -  assert( sqlite3_mutex_held(p) );
          288  +  assert( pthreadMutexHeld(p) );
   289    289     p->nRef--;
   290    290     assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
   291    291   
   292    292   #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
   293    293     if( p->nRef==0 ){
   294    294       pthread_mutex_unlock(&p->mutex);
   295    295     }

Changes to src/sqlite.h.in.

    26     26   ** on how SQLite interfaces are suppose to operate.
    27     27   **
    28     28   ** The name of this file under configuration management is "sqlite.h.in".
    29     29   ** The makefile makes some minor changes to this file (such as inserting
    30     30   ** the version number) and changes its name to "sqlite3.h" as
    31     31   ** part of the build process.
    32     32   **
    33         -** @(#) $Id: sqlite.h.in,v 1.331 2008/06/17 18:57:49 danielk1977 Exp $
           33  +** @(#) $Id: sqlite.h.in,v 1.332 2008/06/18 09:45:56 danielk1977 Exp $
    34     34   */
    35     35   #ifndef _SQLITE3_H_
    36     36   #define _SQLITE3_H_
    37     37   #include <stdarg.h>     /* Needed for the definition of va_list */
    38     38   
    39     39   /*
    40     40   ** Make sure we can call this stuff from C++.
................................................................................
  1047   1047   */ 
  1048   1048   #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
  1049   1049   #define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
  1050   1050   #define SQLITE_CONFIG_SERIALIZED    3  /* nil */
  1051   1051   #define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
  1052   1052   #define SQLITE_CONFIG_MEMSTATUS     5  /* boolean */
  1053   1053   #define SQLITE_CONFIG_MUTEX         6  /* sqlite3_mutex_methods* */
         1054  +#define SQLITE_CONFIG_GETMUTEX      7  /* sqlite3_mutex_methods* */
  1054   1055   
  1055   1056   /* These options are to be added later.  Currently unused and undocumented. */
  1056         -#define SQLITE_CONFIG_HEAP          6  /* void*, int64, min, max, tmp */
         1057  +#define SQLITE_CONFIG_HEAP          8  /* void*, int64, min, max, tmp */
  1057   1058   
  1058   1059   
  1059   1060   /*
  1060   1061   ** CAPI3REF: Enable Or Disable Extended Result Codes {F12200}
  1061   1062   **
  1062   1063   ** The sqlite3_extended_result_codes() routine enables or disables the
  1063   1064   ** [SQLITE_IOERR_READ | extended result codes] feature of SQLite.

Changes to src/tclsqlite.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** A TCL Interface to SQLite.  Append this file to sqlite3.c and
    13     13   ** compile the whole thing to build a TCL-enabled version of SQLite.
    14     14   **
    15         -** $Id: tclsqlite.c,v 1.217 2008/05/01 17:16:53 drh Exp $
           15  +** $Id: tclsqlite.c,v 1.218 2008/06/18 09:45:56 danielk1977 Exp $
    16     16   */
    17     17   #include "tcl.h"
    18     18   #include <errno.h>
    19     19   
    20     20   /*
    21     21   ** Some additional include files are needed if this file is not
    22     22   ** appended to the amalgamation.
................................................................................
  2524   2524       extern int Sqlitetest8_Init(Tcl_Interp*);
  2525   2525       extern int Sqlitetest9_Init(Tcl_Interp*);
  2526   2526       extern int Sqlitetestasync_Init(Tcl_Interp*);
  2527   2527       extern int Sqlitetest_autoext_Init(Tcl_Interp*);
  2528   2528       extern int Sqlitetest_func_Init(Tcl_Interp*);
  2529   2529       extern int Sqlitetest_hexio_Init(Tcl_Interp*);
  2530   2530       extern int Sqlitetest_malloc_Init(Tcl_Interp*);
         2531  +    extern int Sqlitetest_mutex_Init(Tcl_Interp*);
  2531   2532       extern int Sqlitetestschema_Init(Tcl_Interp*);
  2532   2533       extern int Sqlitetestsse_Init(Tcl_Interp*);
  2533   2534       extern int Sqlitetesttclvar_Init(Tcl_Interp*);
  2534   2535       extern int SqlitetestThread_Init(Tcl_Interp*);
  2535   2536       extern int SqlitetestOnefile_Init();
  2536   2537       extern int SqlitetestOsinst_Init(Tcl_Interp*);
  2537   2538   
................................................................................
  2547   2548       Sqlitetest8_Init(interp);
  2548   2549       Sqlitetest9_Init(interp);
  2549   2550       Sqlitetestasync_Init(interp);
  2550   2551       Sqlitetest_autoext_Init(interp);
  2551   2552       Sqlitetest_func_Init(interp);
  2552   2553       Sqlitetest_hexio_Init(interp);
  2553   2554       Sqlitetest_malloc_Init(interp);
         2555  +    Sqlitetest_mutex_Init(interp);
  2554   2556       Sqlitetestschema_Init(interp);
  2555   2557       Sqlitetesttclvar_Init(interp);
  2556   2558       SqlitetestThread_Init(interp);
  2557   2559       SqlitetestOnefile_Init(interp);
  2558   2560       SqlitetestOsinst_Init(interp);
  2559   2561   
  2560   2562   #ifdef SQLITE_SSE

Added src/test_mutex.c.

            1  +/*
            2  +** 2008 June 18
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +** 
           13  +** $Id: test_mutex.c,v 1.1 2008/06/18 09:45:56 danielk1977 Exp $
           14  +*/
           15  +
           16  +#include "tcl.h"
           17  +#include "sqlite3.h"
           18  +#include <stdlib.h>
           19  +#include <assert.h>
           20  +#include <string.h>
           21  +
           22  +const char *sqlite3TestErrorName(int);
           23  +
           24  +struct sqlite3_mutex {
           25  +  sqlite3_mutex *pReal;
           26  +  int eType;
           27  +};
           28  +
           29  +static struct test_mutex_globals {
           30  +  int isInstalled;
           31  +  sqlite3_mutex_methods m;          /* Interface to "real" mutex system */
           32  +  int aCounter[8];                  /* Number of grabs of each type of mutex */
           33  +  sqlite3_mutex aStatic[6];         /* The six static mutexes */
           34  +} g;
           35  +
           36  +static int counterMutexHeld(sqlite3_mutex *p){
           37  +  return g.m.xMutexHeld(p->pReal);
           38  +}
           39  +
           40  +static int counterMutexNotheld(sqlite3_mutex *p){
           41  +  return g.m.xMutexNotheld(p->pReal);
           42  +}
           43  +
           44  +static int counterMutexInit(void){ 
           45  +  return g.m.xMutexInit();
           46  +}
           47  +
           48  +static int counterMutexEnd(void){ 
           49  +  return g.m.xMutexEnd();
           50  +}
           51  +
           52  +static sqlite3_mutex *counterMutexAlloc(int eType){
           53  +  sqlite3_mutex *pReal;
           54  +  sqlite3_mutex *pRet = 0;
           55  +
           56  +  assert(eType<8 && eType>=0);
           57  +
           58  +  pReal = g.m.xMutexAlloc(eType);
           59  +  if( !pReal ) return 0;
           60  +
           61  +  if( eType==0 || eType==1 ){
           62  +    pRet = (sqlite3_mutex *)malloc(sizeof(sqlite3_mutex));
           63  +  }else{
           64  +    pRet = &g.aStatic[eType-2];
           65  +  }
           66  +
           67  +  pRet->eType = eType;
           68  +  pRet->pReal = pReal;
           69  +  return pRet;
           70  +}
           71  +
           72  +static void counterMutexFree(sqlite3_mutex *p){
           73  +  g.m.xMutexFree(p->pReal);
           74  +  if( p->eType==0 || p->eType==1 ){
           75  +    free(p);
           76  +  }
           77  +}
           78  +
           79  +static void counterMutexEnter(sqlite3_mutex *p){
           80  +  g.aCounter[p->eType]++;
           81  +  g.m.xMutexEnter(p->pReal);
           82  +}
           83  +
           84  +static int counterMutexTry(sqlite3_mutex *p){
           85  +  g.aCounter[p->eType]++;
           86  +  return g.m.xMutexTry(p->pReal);
           87  +}
           88  +
           89  +static void counterMutexLeave(sqlite3_mutex *p){
           90  +  g.m.xMutexLeave(p->pReal);
           91  +}
           92  +
           93  +/*
           94  +** sqlite3_shutdown
           95  +*/
           96  +static int test_shutdown(
           97  +  void * clientData,
           98  +  Tcl_Interp *interp,
           99  +  int objc,
          100  +  Tcl_Obj *CONST objv[]
          101  +){
          102  +  int rc;
          103  +
          104  +  if( objc!=1 ){
          105  +    Tcl_WrongNumArgs(interp, 1, objv, "");
          106  +    return TCL_ERROR;
          107  +  }
          108  +
          109  +  rc = sqlite3_shutdown();
          110  +  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
          111  +  return TCL_OK;
          112  +}
          113  +
          114  +/*
          115  +** sqlite3_initialize
          116  +*/
          117  +static int test_initialize(
          118  +  void * clientData,
          119  +  Tcl_Interp *interp,
          120  +  int objc,
          121  +  Tcl_Obj *CONST objv[]
          122  +){
          123  +  int rc;
          124  +
          125  +  if( objc!=1 ){
          126  +    Tcl_WrongNumArgs(interp, 1, objv, "");
          127  +    return TCL_ERROR;
          128  +  }
          129  +
          130  +  rc = sqlite3_initialize();
          131  +  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
          132  +  return TCL_OK;
          133  +}
          134  +
          135  +/*
          136  +** install_mutex_counters BOOLEAN
          137  +*/
          138  +static int test_install_mutex_counters(
          139  +  void * clientData,
          140  +  Tcl_Interp *interp,
          141  +  int objc,
          142  +  Tcl_Obj *CONST objv[]
          143  +){
          144  +  int rc = SQLITE_OK;
          145  +  int isInstall;
          146  +
          147  +  sqlite3_mutex_methods counter_methods = {
          148  +    counterMutexInit,
          149  +    counterMutexAlloc,
          150  +    counterMutexFree,
          151  +    counterMutexEnter,
          152  +    counterMutexTry,
          153  +    counterMutexLeave,
          154  +    counterMutexEnd,
          155  +    counterMutexHeld,
          156  +    counterMutexNotheld
          157  +  };
          158  +
          159  +  if( objc!=2 ){
          160  +    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
          161  +    return TCL_ERROR;
          162  +  }
          163  +  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){
          164  +    return TCL_ERROR;
          165  +  }
          166  +
          167  +  assert(isInstall==0 || isInstall==1);
          168  +  assert(g.isInstalled==0 || g.isInstalled==1);
          169  +  if( isInstall==g.isInstalled ){
          170  +    Tcl_AppendResult(interp, "mutex counters are ", 0);
          171  +    Tcl_AppendResult(interp, isInstall?"already installed":"not installed", 0);
          172  +    return TCL_ERROR;
          173  +  }
          174  +
          175  +  if( isInstall ){
          176  +    assert( g.m.xMutexAlloc==0 );
          177  +    rc = sqlite3_config(SQLITE_CONFIG_GETMUTEX, &g.m);
          178  +    if( rc==SQLITE_OK ){
          179  +      sqlite3_config(SQLITE_CONFIG_MUTEX, &counter_methods);
          180  +    }
          181  +  }else{
          182  +    assert( g.m.xMutexAlloc );
          183  +    rc = sqlite3_config(SQLITE_CONFIG_MUTEX, &g.m);
          184  +    memset(&g.m, 0, sizeof(sqlite3_mutex_methods));
          185  +  }
          186  +
          187  +  if( rc==SQLITE_OK ){
          188  +    g.isInstalled = isInstall;
          189  +  }
          190  +
          191  +  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
          192  +  return TCL_OK;
          193  +}
          194  +
          195  +/*
          196  +** read_mutex_counters
          197  +*/
          198  +static int test_read_mutex_counters(
          199  +  void * clientData,
          200  +  Tcl_Interp *interp,
          201  +  int objc,
          202  +  Tcl_Obj *CONST objv[]
          203  +){
          204  +  Tcl_Obj *pRet;
          205  +  int ii;
          206  +  char *aName[8] = {
          207  +    "fast",        "recursive",   "static_master", "static_mem", 
          208  +    "static_mem2", "static_prng", "static_lru",    "static_lru2"
          209  +  };
          210  +
          211  +  if( objc!=1 ){
          212  +    Tcl_WrongNumArgs(interp, 1, objv, "");
          213  +    return TCL_ERROR;
          214  +  }
          215  +
          216  +  pRet = Tcl_NewObj();
          217  +  Tcl_IncrRefCount(pRet);
          218  +  for(ii=0; ii<8; ii++){
          219  +    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(aName[ii], -1));
          220  +    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(g.aCounter[ii]));
          221  +  }
          222  +  Tcl_SetObjResult(interp, pRet);
          223  +  Tcl_DecrRefCount(pRet);
          224  +
          225  +  return TCL_OK;
          226  +}
          227  +
          228  +/*
          229  +** clear_mutex_counters
          230  +*/
          231  +static int test_clear_mutex_counters(
          232  +  void * clientData,
          233  +  Tcl_Interp *interp,
          234  +  int objc,
          235  +  Tcl_Obj *CONST objv[]
          236  +){
          237  +  int ii;
          238  +
          239  +  if( objc!=1 ){
          240  +    Tcl_WrongNumArgs(interp, 1, objv, "");
          241  +    return TCL_ERROR;
          242  +  }
          243  +
          244  +  for(ii=0; ii<8; ii++){
          245  +    g.aCounter[ii] = 0;
          246  +  }
          247  +  return TCL_OK;
          248  +}
          249  +
          250  +int Sqlitetest_mutex_Init(Tcl_Interp *interp){
          251  +  static struct {
          252  +    char *zName;
          253  +    Tcl_ObjCmdProc *xProc;
          254  +  } aCmd[] = {
          255  +    { "sqlite3_shutdown",        (Tcl_ObjCmdProc*)test_shutdown },
          256  +    { "sqlite3_initialize",      (Tcl_ObjCmdProc*)test_initialize },
          257  +
          258  +    { "install_mutex_counters",  (Tcl_ObjCmdProc*)test_install_mutex_counters },
          259  +    { "read_mutex_counters",     (Tcl_ObjCmdProc*)test_read_mutex_counters },
          260  +    { "clear_mutex_counters",    (Tcl_ObjCmdProc*)test_clear_mutex_counters },
          261  +  };
          262  +  int i;
          263  +  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
          264  +    Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
          265  +  }
          266  +  memset(&g, 0, sizeof(g));
          267  +  return SQLITE_OK;
          268  +}
          269  +

Added test/mutex1.test.

            1  +# 2008 June 17
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# $Id: mutex1.test,v 1.1 2008/06/18 09:45:56 danielk1977 Exp $
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +
           17  +proc mutex_counters {varname} {
           18  +  upvar $varname var
           19  +  set var(total) 0
           20  +  foreach {name value} [read_mutex_counters] {
           21  +    set var($name) $value
           22  +    incr var(total) $value
           23  +  }
           24  +}
           25  +
           26  +#-------------------------------------------------------------------------
           27  +# Tests mutex1-1.* test that sqlite3_config() returns SQLITE_MISUSE if
           28  +# is called at the wrong time. And that the first time sqlite3_initialize 
           29  +# is called it obtains the 'static_master' mutex. Subsequent calls are
           30  +# no-ops that do not require a mutex.
           31  +#
           32  +do_test mutex1-1.0 {
           33  +  install_mutex_counters 1
           34  +} {SQLITE_MISUSE}
           35  +
           36  +do_test mutex1-1.1 {
           37  +  db close
           38  +  install_mutex_counters 1
           39  +} {SQLITE_MISUSE}
           40  +
           41  +do_test mutex1-1.2 {
           42  +  sqlite3_shutdown
           43  +  install_mutex_counters 1
           44  +} {SQLITE_OK}
           45  +
           46  +do_test mutex1-1.3 {
           47  +  install_mutex_counters 0
           48  +} {SQLITE_OK}
           49  +
           50  +do_test mutex1-1.4 {
           51  +  install_mutex_counters 1
           52  +} {SQLITE_OK}
           53  +
           54  +do_test mutex1-1.5 {
           55  +  mutex_counters counters
           56  +  set counters(total)
           57  +} {0}
           58  +
           59  +do_test mutex1-1.6 {
           60  +  sqlite3_initialize
           61  +} {SQLITE_OK}
           62  +
           63  +do_test mutex1-1.7 {
           64  +  mutex_counters counters
           65  +  list $counters(total) $counters(static_master)
           66  +} {1 1}
           67  +
           68  +do_test mutex1-1.8 {
           69  +  clear_mutex_counters
           70  +  sqlite3_initialize
           71  +} {SQLITE_OK}
           72  +
           73  +do_test mutex1-1.9 {
           74  +  mutex_counters counters
           75  +  list $counters(total) $counters(static_master)
           76  +} {0 0}
           77  +
           78  +
           79  +do_test mutex1-X {
           80  +  sqlite3_shutdown
           81  +  clear_mutex_counters
           82  +  install_mutex_counters 0
           83  +} {SQLITE_OK}
           84  +
           85  +finish_test
           86  +