Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Enhance mutex testing to include APP and VFS static mutexes. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
1025873fdfd9e7e53094c48af1a79c60 |
User & Date: | mistachkin 2015-07-03 23:11:36.336 |
References
2015-07-03
| ||
23:29 | Correction to check-in [1025873fdf], tighten up the number of static test mutexes. (check-in: 4e515897af user: mistachkin tags: trunk) | |
Context
2015-07-03
| ||
23:12 | Update clean target in MSVC makefile. (check-in: e6c03e7201 user: mistachkin tags: trunk) | |
23:11 | Enhance mutex testing to include APP and VFS static mutexes. (check-in: 1025873fdf user: mistachkin tags: trunk) | |
21:38 | Add static mutexes for use by the built-in / third-party VFSs and use the built-in VFS mutex where appropriate. (check-in: b202e2a1d7 user: mistachkin tags: trunk) | |
Changes
Changes to src/test_mutex.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include "tcl.h" #include "sqlite3.h" #include "sqliteInt.h" #include <stdlib.h> #include <assert.h> #include <string.h> /* defined in main.c */ extern const char *sqlite3ErrName(int); /* A countable mutex */ struct sqlite3_mutex { sqlite3_mutex *pReal; int eType; }; /* State variables */ static struct test_mutex_globals { | > > > > > > > > > | | | | | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include "tcl.h" #include "sqlite3.h" #include "sqliteInt.h" #include <stdlib.h> #include <assert.h> #include <string.h> #define MAX_MUTEXES (SQLITE_MUTEX_STATIC_VFS3+1) /* defined in main.c */ extern const char *sqlite3ErrName(int); static const char *aName[MAX_MUTEXES+1] = { "fast", "recursive", "static_master", "static_mem", "static_open", "static_prng", "static_lru", "static_pmem", "static_app1", "static_app2", "static_app3", "static_vfs1", "static_vfs2", "static_vfs3", 0 }; /* A countable mutex */ struct sqlite3_mutex { sqlite3_mutex *pReal; int eType; }; /* State variables */ static struct test_mutex_globals { int isInstalled; /* True if installed */ int disableInit; /* True to cause sqlite3_initalize() to fail */ int disableTry; /* True to force sqlite3_mutex_try() to fail */ int isInit; /* True if initialized */ sqlite3_mutex_methods m; /* Interface to "real" mutex system */ int aCounter[MAX_MUTEXES]; /* Number of grabs of each type of mutex */ sqlite3_mutex aStatic[MAX_MUTEXES]; /* The static mutexes */ } g = {0}; /* Return true if the countable mutex is currently held */ static int counterMutexHeld(sqlite3_mutex *p){ return g.m.xMutexHeld(p->pReal); } |
︙ | ︙ | |||
74 75 76 77 78 79 80 | ** Allocate a countable mutex */ static sqlite3_mutex *counterMutexAlloc(int eType){ sqlite3_mutex *pReal; sqlite3_mutex *pRet = 0; assert( g.isInit ); | | > > > > | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | ** Allocate a countable mutex */ static sqlite3_mutex *counterMutexAlloc(int eType){ sqlite3_mutex *pReal; sqlite3_mutex *pRet = 0; assert( g.isInit ); assert( eType>=SQLITE_MUTEX_FAST ); assert( eType<=SQLITE_MUTEX_STATIC_VFS3 ); pReal = g.m.xMutexAlloc(eType); if( !pReal ) return 0; if( eType==SQLITE_MUTEX_FAST || eType==SQLITE_MUTEX_RECURSIVE ){ pRet = (sqlite3_mutex *)malloc(sizeof(sqlite3_mutex)); }else{ int eStaticType = eType - (SQLITE_MUTEX_RECURSIVE + 1); assert( eStaticType>=0 ); assert( eStaticType<MAX_MUTEXES ); pRet = &g.aStatic[eStaticType]; } pRet->eType = eType; pRet->pReal = pReal; return pRet; } |
︙ | ︙ | |||
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | } /* ** Enter a countable mutex. Block until entry is safe. */ static void counterMutexEnter(sqlite3_mutex *p){ assert( g.isInit ); g.aCounter[p->eType]++; g.m.xMutexEnter(p->pReal); } /* ** Try to enter a mutex. Return true on success. */ static int counterMutexTry(sqlite3_mutex *p){ assert( g.isInit ); g.aCounter[p->eType]++; if( g.disableTry ) return SQLITE_BUSY; return g.m.xMutexTry(p->pReal); } /* Leave a mutex */ | > > > > | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | } /* ** Enter a countable mutex. Block until entry is safe. */ static void counterMutexEnter(sqlite3_mutex *p){ assert( g.isInit ); assert( p->eType>=0 ); assert( p->eType<MAX_MUTEXES ); g.aCounter[p->eType]++; g.m.xMutexEnter(p->pReal); } /* ** Try to enter a mutex. Return true on success. */ static int counterMutexTry(sqlite3_mutex *p){ assert( g.isInit ); assert( p->eType>=0 ); assert( p->eType<MAX_MUTEXES ); g.aCounter[p->eType]++; if( g.disableTry ) return SQLITE_BUSY; return g.m.xMutexTry(p->pReal); } /* Leave a mutex */ |
︙ | ︙ | |||
241 242 243 244 245 246 247 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ Tcl_Obj *pRet; int ii; | < < < < | | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ Tcl_Obj *pRet; int ii; if( objc!=1 ){ Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } pRet = Tcl_NewObj(); Tcl_IncrRefCount(pRet); for(ii=0; ii<MAX_MUTEXES; ii++){ Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(aName[ii], -1)); Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(g.aCounter[ii])); } Tcl_SetObjResult(interp, pRet); Tcl_DecrRefCount(pRet); return TCL_OK; |
︙ | ︙ | |||
279 280 281 282 283 284 285 | int ii; if( objc!=1 ){ Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } | | | 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | int ii; if( objc!=1 ){ Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } for(ii=0; ii<MAX_MUTEXES; ii++){ g.aCounter[ii] = 0; } return TCL_OK; } /* ** Create and free a mutex. Return the mutex pointer. The pointer |
︙ | ︙ | |||
366 367 368 369 370 371 372 373 374 375 376 377 378 379 | db = *((sqlite3 **)info.objClientData); }else{ db = (sqlite3*)sqlite3TestTextToPtr(zCmd); } assert( db ); return db; } static int test_enter_db_mutex( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | db = *((sqlite3 **)info.objClientData); }else{ db = (sqlite3*)sqlite3TestTextToPtr(zCmd); } assert( db ); return db; } static sqlite3_mutex *getStaticMutexPointer( Tcl_Interp *pInterp, Tcl_Obj *pObj ){ int iMutex; if( Tcl_GetIndexFromObj(pInterp, pObj, aName, "mutex name", 0, &iMutex) ){ return 0; } assert( iMutex!=SQLITE_MUTEX_FAST && iMutex!=SQLITE_MUTEX_RECURSIVE ); return counterMutexAlloc(iMutex); } static int test_enter_static_mutex( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_mutex *pMutex; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "NAME"); return TCL_ERROR; } pMutex = getStaticMutexPointer(interp, objv[1]); if( !pMutex ){ return TCL_ERROR; } sqlite3_mutex_enter(pMutex); return TCL_OK; } static int test_leave_static_mutex( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_mutex *pMutex; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "NAME"); return TCL_ERROR; } pMutex = getStaticMutexPointer(interp, objv[1]); if( !pMutex ){ return TCL_ERROR; } sqlite3_mutex_leave(pMutex); return TCL_OK; } static int test_enter_db_mutex( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ |
︙ | ︙ | |||
413 414 415 416 417 418 419 420 421 422 423 424 425 426 | static struct { char *zName; Tcl_ObjCmdProc *xProc; } aCmd[] = { { "sqlite3_shutdown", (Tcl_ObjCmdProc*)test_shutdown }, { "sqlite3_initialize", (Tcl_ObjCmdProc*)test_initialize }, { "sqlite3_config", (Tcl_ObjCmdProc*)test_config }, { "enter_db_mutex", (Tcl_ObjCmdProc*)test_enter_db_mutex }, { "leave_db_mutex", (Tcl_ObjCmdProc*)test_leave_db_mutex }, { "alloc_dealloc_mutex", (Tcl_ObjCmdProc*)test_alloc_mutex }, { "install_mutex_counters", (Tcl_ObjCmdProc*)test_install_mutex_counters }, { "read_mutex_counters", (Tcl_ObjCmdProc*)test_read_mutex_counters }, | > > > | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | static struct { char *zName; Tcl_ObjCmdProc *xProc; } aCmd[] = { { "sqlite3_shutdown", (Tcl_ObjCmdProc*)test_shutdown }, { "sqlite3_initialize", (Tcl_ObjCmdProc*)test_initialize }, { "sqlite3_config", (Tcl_ObjCmdProc*)test_config }, { "enter_static_mutex", (Tcl_ObjCmdProc*)test_enter_static_mutex }, { "leave_static_mutex", (Tcl_ObjCmdProc*)test_leave_static_mutex }, { "enter_db_mutex", (Tcl_ObjCmdProc*)test_enter_db_mutex }, { "leave_db_mutex", (Tcl_ObjCmdProc*)test_leave_db_mutex }, { "alloc_dealloc_mutex", (Tcl_ObjCmdProc*)test_alloc_mutex }, { "install_mutex_counters", (Tcl_ObjCmdProc*)test_install_mutex_counters }, { "read_mutex_counters", (Tcl_ObjCmdProc*)test_read_mutex_counters }, |
︙ | ︙ |
Changes to test/mutex1.test.
︙ | ︙ | |||
33 34 35 36 37 38 39 | set var($name) $value incr var(total) $value } } #------------------------------------------------------------------------- # Tests mutex1-1.* test that sqlite3_config() returns SQLITE_MISUSE if | | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | set var($name) $value incr var(total) $value } } #------------------------------------------------------------------------- # Tests mutex1-1.* test that sqlite3_config() returns SQLITE_MISUSE if # is called at the wrong time. And that the first time sqlite3_initialize # is called it obtains the 'static_master' mutex 3 times and a recursive # mutex (sqlite3Config.pInitMutex) twice. Subsequent calls are no-ops # that do not require any mutexes. # do_test mutex1-1.0 { install_mutex_counters 1 } {SQLITE_MISUSE} do_test mutex1-1.1 { |
︙ | ︙ | |||
98 99 100 101 102 103 104 | # * Single-threaded mode. # ifcapable threadsafe&&shared_cache { set enable_shared_cache [sqlite3_enable_shared_cache 1] foreach {mode mutexes} { singlethread {} multithread { | > | > | > | | > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | # * Single-threaded mode. # ifcapable threadsafe&&shared_cache { set enable_shared_cache [sqlite3_enable_shared_cache 1] foreach {mode mutexes} { singlethread {} multithread { fast static_app1 static_app2 static_app3 static_lru static_master static_mem static_open static_prng static_pmem static_vfs1 static_vfs2 static_vfs3 } serialized { fast recursive static_app1 static_app2 static_app3 static_lru static_master static_mem static_open static_prng static_pmem static_vfs1 static_vfs2 static_vfs3 } } { do_test mutex1.2.$mode.1 { catch {db close} sqlite3_shutdown sqlite3_config $mode |
︙ | ︙ | |||
125 126 127 128 129 130 131 | db eval { INSERT INTO abc VALUES(1, 2, 3); } } {} ifcapable !memorymanage { regsub { static_lru} $mutexes {} mutexes } | > | > > > > > > > > > > > > > > > > > > | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | db eval { INSERT INTO abc VALUES(1, 2, 3); } } {} ifcapable !memorymanage { regsub { static_lru} $mutexes {} mutexes } if {$mode ne "singlethread"} { do_test mutex1.2.$mode.3 { # # NOTE: Make sure all the app and vfs mutexes get used. # enter_static_mutex static_app1 leave_static_mutex static_app1 enter_static_mutex static_app2 leave_static_mutex static_app2 enter_static_mutex static_app3 leave_static_mutex static_app3 enter_static_mutex static_vfs1 leave_static_mutex static_vfs1 enter_static_mutex static_vfs2 leave_static_mutex static_vfs2 enter_static_mutex static_vfs3 leave_static_mutex static_vfs3 } {} } do_test mutex1.2.$mode.4 { mutex_counters counters set res [list] foreach {key value} [array get counters] { if {$key ne "total" && $value > 0} { lappend res $key } } lsort $res |
︙ | ︙ |