Add some docs and metrics for the new mutex internals.
FossilOrigin-Name: 33d1780b43182d2574adbc1928707af825c485c99762738e58bc6d7c6c52ac6a
This commit is contained in:
+22
-11
@@ -499,19 +499,25 @@ static struct {
|
||||
S3JniEnvCache * aHead /* Linked list of in-use instances */;
|
||||
S3JniEnvCache * aFree /* Linked list of free instances */;
|
||||
sqlite3_mutex * mutex /* mutex for aHead and aFree */;
|
||||
void const * locker /* env mutex is held on this object's behalf */;
|
||||
void const * locker /* env mutex is held on this object's behalf
|
||||
(used only for sanity checking). */;
|
||||
} envCache;
|
||||
struct {
|
||||
S3JniDb * aUsed /* Linked list of in-use instances */;
|
||||
S3JniDb * aFree /* Linked list of free instances */;
|
||||
sqlite3_mutex * mutex /* mutex for aUsed and aFree */;
|
||||
void const * locker /* perDb mutex is held on this object's behalf */;
|
||||
sqlite3_mutex * mutex /* mutex for aUsed and aFree */;
|
||||
void const * locker /* perDb mutex is held on this object's
|
||||
behalf. Unlike envCache.locker, we
|
||||
cannot always have this set to the
|
||||
current JNIEnv object. */;
|
||||
} perDb;
|
||||
struct {
|
||||
unsigned nphCacheHits;
|
||||
unsigned nphCacheMisses;
|
||||
unsigned envCacheHits;
|
||||
unsigned envCacheMisses;
|
||||
unsigned nMutexEnv /* number of times envCache.mutex was entered */;
|
||||
unsigned nMutexPerDb /* number of times perDb.mutex was entered */;
|
||||
unsigned nDestroy /* xDestroy() calls across all types */;
|
||||
struct {
|
||||
/* Number of calls for each type of UDF callback. */
|
||||
@@ -542,30 +548,28 @@ static struct {
|
||||
|
||||
#define MUTEX_ASSERT_LOCKER_ENV \
|
||||
assert( (env) == S3JniGlobal.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" )
|
||||
#define MUTEX_ASSERT_LOCKER_PDB \
|
||||
assert( 0 != S3JniGlobal.perDb.locker && "Misuse of S3JniGlobal.perDb.mutex" )
|
||||
#define MUTEX_ASSERT_NOTLOCKER_ENV \
|
||||
assert( (env) != S3JniGlobal.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" )
|
||||
#define MUTEX_ASSERT_NOTLOCKER_PDB \
|
||||
assert( 0 == S3JniGlobal.perDb.locker && "Misuse of S3JniGlobal.perDb.mutex" )
|
||||
#define MUTEX_ENTER_ENV \
|
||||
/*MARKER(("Entering ENV mutex@%p %s.\n", env, __func__));*/ \
|
||||
MUTEX_ASSERT_NOTLOCKER_ENV; \
|
||||
sqlite3_mutex_enter( S3JniGlobal.envCache.mutex ); \
|
||||
++S3JniGlobal.metrics.nMutexEnv; \
|
||||
S3JniGlobal.envCache.locker = env
|
||||
#define MUTEX_LEAVE_ENV \
|
||||
/*MARKER(("Leaving ENV mutex @%p %s.\n", env, __func__));*/ \
|
||||
MUTEX_ASSERT_LOCKER_ENV; \
|
||||
S3JniGlobal.envCache.locker = 0; \
|
||||
sqlite3_mutex_leave( S3JniGlobal.envCache.mutex )
|
||||
#define MUTEX_ASSERT_LOCKED_PDB \
|
||||
assert( 0 != S3JniGlobal.perDb.locker && "Misuse of S3JniGlobal.perDb.mutex" )
|
||||
#define MUTEX_ENTER_PDB \
|
||||
/*MARKER(("Entering PerDb mutex@%p %s.\n", env, __func__));*/ \
|
||||
MUTEX_ASSERT_NOTLOCKER_PDB; \
|
||||
sqlite3_mutex_enter( S3JniGlobal.perDb.mutex ); \
|
||||
++S3JniGlobal.metrics.nMutexPerDb; \
|
||||
S3JniGlobal.perDb.locker = env;
|
||||
#define MUTEX_LEAVE_PDB \
|
||||
/*MARKER(("Leaving PerDb mutex@%p %s.\n", env, __func__));*/ \
|
||||
MUTEX_ASSERT_LOCKER_PDB; \
|
||||
S3JniGlobal.perDb.locker = 0; \
|
||||
sqlite3_mutex_leave( S3JniGlobal.perDb.mutex )
|
||||
|
||||
@@ -899,7 +903,7 @@ static void S3JniHook_unref(JNIEnv * const env, S3JniHook * const s, int doXDest
|
||||
static void S3JniDb_set_aside(S3JniDb * const s){
|
||||
if(s){
|
||||
JNIEnv * const env = s->env;
|
||||
MUTEX_ASSERT_LOCKER_PDB;
|
||||
MUTEX_ASSERT_LOCKED_PDB;
|
||||
assert(s->pDb && "Else this object is already in the free-list.");
|
||||
//MARKER(("state@%p for db@%p setting aside\n", s, s->pDb));
|
||||
assert(s->pPrev != s);
|
||||
@@ -1035,6 +1039,10 @@ static S3JniNphCache * S3JniGlobal_nph_cache(JNIEnv * const env, const char *zCl
|
||||
you should look them up once and then reuse them. Similarly,
|
||||
looking up class objects can be expensive, so they should be
|
||||
cached as well.
|
||||
|
||||
Reminder: we do not need a mutex for the envRow->nph cache
|
||||
because all nph entries are per-thread and envCache.mutex
|
||||
already guards the fetching of envRow.
|
||||
*/
|
||||
struct S3JniEnvCache * const envRow = S3JniGlobal_env_cache(env);
|
||||
S3JniNphCache * freeSlot = 0;
|
||||
@@ -1153,7 +1161,7 @@ static void * NativePointerHolder_get(JNIEnv * env, jobject pObj, const char *zC
|
||||
static S3JniDb * S3JniDb_alloc(JNIEnv * const env, sqlite3 *pDb,
|
||||
jobject jDb){
|
||||
S3JniDb * rv;
|
||||
MUTEX_ASSERT_LOCKER_PDB;
|
||||
MUTEX_ASSERT_LOCKED_PDB;
|
||||
if(S3JniGlobal.perDb.aFree){
|
||||
rv = S3JniGlobal.perDb.aFree;
|
||||
//MARKER(("state@%p for db allocating for db@%p from free-list\n", rv, pDb));
|
||||
@@ -3496,6 +3504,9 @@ JDECL(void,1do_1something_1for_1developer)(JENV_CSELF){
|
||||
printf("\tJNIEnv cache %u misses, %u hits\n",
|
||||
S3JniGlobal.metrics.envCacheMisses,
|
||||
S3JniGlobal.metrics.envCacheHits);
|
||||
printf("\tMutex entry: %u env, %u perDb\n",
|
||||
S3JniGlobal.metrics.nMutexEnv,
|
||||
S3JniGlobal.metrics.nMutexPerDb);
|
||||
puts("Java-side UDF calls:");
|
||||
#define UDF(T) printf("\t%-8s = %u\n", "x" #T, S3JniGlobal.metrics.udf.n##T)
|
||||
UDF(Func); UDF(Step); UDF(Final); UDF(Value); UDF(Inverse);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C An\sinitial\sattempt\sat\sprotecting\sthe\sJNI\sglobal\sstate\svia\smutexes\sat\sthe\sC\slevel\sinstead\sof\srelying\son\sJava's\ssynchronized\skeyword.\sIt\sseems\sto\swork\sbut\sincreases\sthe\srun\stime\sof\sthe\ssingle-threaded\sbatch\stester\sby\sroughly\s3\stimes.
|
||||
D 2023-08-13T09:53:27.824
|
||||
C Add\ssome\sdocs\sand\smetrics\sfor\sthe\snew\smutex\sinternals.
|
||||
D 2023-08-13T10:28:35.456
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -234,7 +234,7 @@ F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a3
|
||||
F ext/jni/GNUmakefile a9e11b92e620058558cbc1a2d49f8ec53c78d6a989b9db0b7d0b649b9f174881
|
||||
F ext/jni/README.md 7a614a2fa6c561205f7a53fd8626cf93a7b5711ff454fc1814517f796df398eb
|
||||
F ext/jni/jar-dist.make f90a553203a57934bf275bed86479485135a52f48ac5c1cfe6499ae07b0b35a4
|
||||
F ext/jni/src/c/sqlite3-jni.c 93fbeed06441352df68f6c0e4bc2cd895e81d8550dc9972cafb30621958b4784
|
||||
F ext/jni/src/c/sqlite3-jni.c 44c1da6d1ae9d8ea2af16dd5c1d17224a655c9c94135892f81571b2481896431
|
||||
F ext/jni/src/c/sqlite3-jni.h f10d2f38720687c70ecdd5e44f6e8db98efee2caa05fc86b2d9e0c76e6cc0a18
|
||||
F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892
|
||||
F ext/jni/src/org/sqlite/jni/AutoExtension.java 18e83f6f463e306df60b2dceb65247d32af1f78af4bbbae9155411a8c6cdb093
|
||||
@@ -2091,8 +2091,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P fbf99a2423dd20e4544bdeea85f714e9368ce3b92fefe97efb39a0fb4a557abe
|
||||
R 42a3d0d4c63d13c26ffa7bd8f71380ed
|
||||
P c64e6a52ac79164be37fe643a4a39bd187af198a379410def8b8419f7c2224d4
|
||||
R cd02d0fb58628c824a2d7de7efc47b02
|
||||
U stephan
|
||||
Z 5906c49c68c9155fc27b7d9430c5551e
|
||||
Z 6ab46f9c79559c9df9412a6d1bef3261
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
c64e6a52ac79164be37fe643a4a39bd187af198a379410def8b8419f7c2224d4
|
||||
33d1780b43182d2574adbc1928707af825c485c99762738e58bc6d7c6c52ac6a
|
||||
Reference in New Issue
Block a user