/ Check-in [ba772cff]
Login

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

Overview
Comment:Further enhancements to threadtest3 stress tests.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ba772cff602ca7c3c0c91451e701f52a872e7a14
User & Date: dan 2014-12-13 17:41:48
Context
2014-12-15
08:46
Fix errors in threadtest3 tests caused by earlier tests neglecting to close database handles. check-in: 1d44f1b1 user: dan tags: trunk
2014-12-13
17:41
Further enhancements to threadtest3 stress tests. check-in: ba772cff user: dan tags: trunk
2014-12-12
23:17
Add extra tests to threadtest4.c. Fix a benign data race accessing the text encoding using ENC(db). check-in: d7bb7ea4 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to test/threadtest3.c.

    43     43   
    44     44   /* Functions to execute SQL */
    45     45   #define sql_script(x,y,z)       (SEL(x), sql_script_x(x,y,z))
    46     46   #define integrity_check(x,y)    (SEL(x), integrity_check_x(x,y))
    47     47   #define execsql_i64(x,y,...)    (SEL(x), execsql_i64_x(x,y,__VA_ARGS__))
    48     48   #define execsql_text(x,y,z,...) (SEL(x), execsql_text_x(x,y,z,__VA_ARGS__))
    49     49   #define execsql(x,y,...)        (SEL(x), (void)execsql_i64_x(x,y,__VA_ARGS__))
           50  +#define sql_script_printf(x,y,z,...) (                \
           51  +    SEL(x), sql_script_printf_x(x,y,z,__VA_ARGS__)    \
           52  +) 
    50     53   
    51     54   /* Thread functions */
    52         -#define launch_thread(w,x,y,z)  (SEL(w), launch_thread_x(w,x,y,z))
    53         -#define join_all_threads(y,z)   (SEL(y), join_all_threads_x(y,z))
           55  +#define launch_thread(w,x,y,z)     (SEL(w), launch_thread_x(w,x,y,z))
           56  +#define join_all_threads(y,z)      (SEL(y), join_all_threads_x(y,z))
    54     57   
    55     58   /* Timer functions */
    56     59   #define setstoptime(y,z)        (SEL(y), setstoptime_x(y,z))
    57     60   #define timetostop(z)           (SEL(z), timetostop_x(z))
    58     61   
    59     62   /* Report/clear errors. */
    60     63   #define test_error(z, ...)      test_error_x(z, sqlite3_mprintf(__VA_ARGS__))
    61     64   #define clear_error(y,z)        clear_error_x(y, z)
    62     65   
    63     66   /* File-system operations */
    64     67   #define filesize(y,z)           (SEL(y), filesize_x(y,z))
    65     68   #define filecopy(x,y,z)         (SEL(x), filecopy_x(x,y,z))
    66     69   
           70  +#define PTR2INT(x) ((int)((intptr_t)x))
           71  +#define INT2PTR(x) ((void*)((intptr_t)x))
           72  +
    67     73   /*
    68     74   ** End of test code/infrastructure interface macros.
    69     75   *************************************************************************/
    70     76   
    71     77   
    72     78   
    73     79   
................................................................................
   330    336     /* Append length in bits and transform */
   331    337     ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
   332    338     ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
   333    339   
   334    340     MD5Transform(ctx->buf, (uint32 *)ctx->in);
   335    341     byteReverse((unsigned char *)ctx->buf, 4);
   336    342     memcpy(digest, ctx->buf, 16);
   337         -  memset(ctx, 0, sizeof(ctx));    /* In case it is sensitive */
          343  +  memset(ctx, 0, sizeof(*ctx));    /* In case it is sensitive */
   338    344   }
   339    345   
   340    346   /*
   341    347   ** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
   342    348   */
   343    349   static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
   344    350     static char const zEncode[] = "0123456789abcdef";
................................................................................
   394    400   
   395    401   typedef struct Threadset Threadset;
   396    402   typedef struct Thread Thread;
   397    403   
   398    404   /* Total number of errors in this process so far. */
   399    405   static int nGlobalErr = 0;
   400    406   
   401         -/* Set to true to run in "process" instead of "thread" mode. */
   402         -static int bProcessMode = 0;
   403         -
   404    407   struct Error {
   405    408     int rc;
   406    409     int iLine;
   407    410     char *zErr;
   408    411   };
   409    412   
   410    413   struct Sqlite {
................................................................................
   417    420   struct Statement {
   418    421     sqlite3_stmt *pStmt;            /* Pre-compiled statement handle */
   419    422     Statement *pNext;               /* Next statement in linked-list */
   420    423   };
   421    424   
   422    425   struct Thread {
   423    426     int iTid;                       /* Thread number within test */
   424         -  int iArg;                       /* Integer argument passed by caller */
          427  +  void* pArg;                     /* Pointer argument passed by caller */
   425    428   
   426    429     pthread_t tid;                  /* Thread id */
   427         -  char *(*xProc)(int, int);       /* Thread main proc */
          430  +  char *(*xProc)(int, void*);     /* Thread main proc */
   428    431     Thread *pNext;                  /* Next in this list of threads */
   429    432   };
   430    433   
   431    434   struct Threadset {
   432    435     int iMaxTid;                    /* Largest iTid value allocated so far */
   433    436     Thread *pThread;                /* Linked list of threads */
   434    437   };
................................................................................
   502    505     Error *pErr,                    /* IN/OUT: Error code */
   503    506     Sqlite *pDb,                    /* OUT: Database handle */
   504    507     const char *zFile,              /* Database file name */
   505    508     int bDelete                     /* True to delete db file before opening */
   506    509   ){
   507    510     if( pErr->rc==SQLITE_OK ){
   508    511       int rc;
          512  +    int flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI;
   509    513       if( bDelete ) unlink(zFile);
   510         -    rc = sqlite3_open(zFile, &pDb->db);
          514  +    rc = sqlite3_open_v2(zFile, &pDb->db, flags, 0);
   511    515       if( rc ){
   512    516         sqlite_error(pErr, pDb, "open");
   513    517         sqlite3_close(pDb->db);
   514    518         pDb->db = 0;
   515    519       }else{
   516    520         sqlite3_create_function(
   517    521             pDb->db, "md5sum", -1, SQLITE_UTF8, 0, 0, md5step, md5finalize
................................................................................
   551    555     Sqlite *pDb,                    /* Database handle */
   552    556     const char *zSql                /* SQL script to execute */
   553    557   ){
   554    558     if( pErr->rc==SQLITE_OK ){
   555    559       pErr->rc = sqlite3_exec(pDb->db, zSql, 0, 0, &pErr->zErr);
   556    560     }
   557    561   }
          562  +
          563  +static void sql_script_printf_x(
          564  +  Error *pErr,                    /* IN/OUT: Error code */
          565  +  Sqlite *pDb,                    /* Database handle */
          566  +  const char *zFormat,            /* SQL printf format string */
          567  +  ...                             /* Printf args */
          568  +){
          569  +  va_list ap;                     /* ... printf arguments */
          570  +  va_start(ap, zFormat);
          571  +  if( pErr->rc==SQLITE_OK ){
          572  +    char *zSql = sqlite3_vmprintf(zFormat, ap);
          573  +    pErr->rc = sqlite3_exec(pDb->db, zSql, 0, 0, &pErr->zErr);
          574  +    sqlite3_free(zSql);
          575  +  }
          576  +  va_end(ap);
          577  +}
   558    578   
   559    579   static Statement *getSqlStatement(
   560    580     Error *pErr,                    /* IN/OUT: Error code */
   561    581     Sqlite *pDb,                    /* Database handle */
   562    582     const char *zSql                /* SQL statement */
   563    583   ){
   564    584     Statement *pRet;
................................................................................
   620    640     Sqlite *pDb,                    /* Database handle */
   621    641     ...                             /* SQL and pointers to parameter values */
   622    642   ){
   623    643     i64 iRet = 0;
   624    644     if( pErr->rc==SQLITE_OK ){
   625    645       sqlite3_stmt *pStmt;          /* SQL statement to execute */
   626    646       va_list ap;                   /* ... arguments */
   627         -    int i;                        /* Used to iterate through parameters */
   628    647       va_start(ap, pDb);
   629    648       pStmt = getAndBindSqlStatement(pErr, pDb, ap);
   630    649       if( pStmt ){
   631         -      int rc;
   632    650         int first = 1;
   633    651         while( SQLITE_ROW==sqlite3_step(pStmt) ){
   634    652           if( first && sqlite3_column_count(pStmt)>0 ){
   635    653             iRet = sqlite3_column_int64(pStmt, 0);
   636    654           }
   637    655           first = 0;
   638    656         }
................................................................................
   659    677       memset(&pDb->aText[pDb->nText], 0, sizeof(char*)*(iSlot+1-pDb->nText));
   660    678       pDb->nText = iSlot+1;
   661    679     }
   662    680   
   663    681     if( pErr->rc==SQLITE_OK ){
   664    682       sqlite3_stmt *pStmt;          /* SQL statement to execute */
   665    683       va_list ap;                   /* ... arguments */
   666         -    int i;                        /* Used to iterate through parameters */
   667    684       va_start(ap, iSlot);
   668    685       pStmt = getAndBindSqlStatement(pErr, pDb, ap);
   669    686       if( pStmt ){
   670         -      int rc;
   671    687         int first = 1;
   672    688         while( SQLITE_ROW==sqlite3_step(pStmt) ){
   673    689           if( first && sqlite3_column_count(pStmt)>0 ){
   674    690             zRet = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
   675    691             sqlite3_free(pDb->aText[iSlot]);
   676    692             pDb->aText[iSlot] = zRet;
   677    693           }
................................................................................
   689    705   
   690    706   static void integrity_check_x(
   691    707     Error *pErr,                    /* IN/OUT: Error code */
   692    708     Sqlite *pDb                     /* Database handle */
   693    709   ){
   694    710     if( pErr->rc==SQLITE_OK ){
   695    711       Statement *pStatement;        /* Statement to execute */
   696         -    int rc;                       /* Return code */
   697    712       char *zErr = 0;               /* Integrity check error */
   698    713   
   699    714       pStatement = getSqlStatement(pErr, pDb, "PRAGMA integrity_check");
   700    715       if( pStatement ){
   701    716         sqlite3_stmt *pStmt = pStatement->pStmt;
   702    717         while( SQLITE_ROW==sqlite3_step(pStmt) ){
   703         -        const char *z = sqlite3_column_text(pStmt, 0);
          718  +        const char *z = (const char*)sqlite3_column_text(pStmt, 0);
   704    719           if( strcmp(z, "ok") ){
   705    720             if( zErr==0 ){
   706    721               zErr = sqlite3_mprintf("%s", z);
   707    722             }else{
   708    723               zErr = sqlite3_mprintf("%z\n%s", zErr, z);
   709    724             }
   710    725           }
................................................................................
   717    732         }
   718    733       }
   719    734     }
   720    735   }
   721    736   
   722    737   static void *launch_thread_main(void *pArg){
   723    738     Thread *p = (Thread *)pArg;
   724         -  return (void *)p->xProc(p->iTid, p->iArg);
          739  +  return (void *)p->xProc(p->iTid, p->pArg);
   725    740   }
   726    741   
   727    742   static void launch_thread_x(
   728    743     Error *pErr,                    /* IN/OUT: Error code */
   729    744     Threadset *pThreads,            /* Thread set */
   730         -  char *(*xProc)(int, int),       /* Proc to run */
   731         -  int iArg                        /* Argument passed to thread proc */
          745  +  char *(*xProc)(int, void*),     /* Proc to run */
          746  +  void *pArg                      /* Argument passed to thread proc */
   732    747   ){
   733    748     if( pErr->rc==SQLITE_OK ){
   734    749       int iTid = ++pThreads->iMaxTid;
   735    750       Thread *p;
   736    751       int rc;
   737    752   
   738    753       p = (Thread *)sqlite3_malloc(sizeof(Thread));
   739    754       memset(p, 0, sizeof(Thread));
   740    755       p->iTid = iTid;
   741         -    p->iArg = iArg;
          756  +    p->pArg = pArg;
   742    757       p->xProc = xProc;
   743    758   
   744    759       rc = pthread_create(&p->tid, NULL, launch_thread_main, (void *)p);
   745    760       if( rc!=0 ){
   746    761         system_error(pErr, rc);
   747    762         sqlite3_free(p);
   748    763       }else{
................................................................................
   891    906   **************************************************************************
   892    907   ** End infrastructure. Begin tests.
   893    908   */
   894    909   
   895    910   #define WALTHREAD1_NTHREAD  10
   896    911   #define WALTHREAD3_NTHREAD  6
   897    912   
   898         -static char *walthread1_thread(int iTid, int iArg){
          913  +static char *walthread1_thread(int iTid, void *pArg){
   899    914     Error err = {0};                /* Error code and message */
   900    915     Sqlite db = {0};                /* SQLite database connection */
   901    916     int nIter = 0;                  /* Iterations so far */
   902    917   
   903    918     opendb(&err, &db, "test.db", 0);
   904    919     while( !timetostop(&err) ){
   905    920       const char *azSql[] = {
................................................................................
   930    945     }
   931    946     closedb(&err, &db);
   932    947   
   933    948     print_and_free_err(&err);
   934    949     return sqlite3_mprintf("%d iterations", nIter);
   935    950   }
   936    951   
   937         -static char *walthread1_ckpt_thread(int iTid, int iArg){
          952  +static char *walthread1_ckpt_thread(int iTid, void *pArg){
   938    953     Error err = {0};                /* Error code and message */
   939    954     Sqlite db = {0};                /* SQLite database connection */
   940    955     int nCkpt = 0;                  /* Checkpoints so far */
   941    956   
   942    957     opendb(&err, &db, "test.db", 0);
   943    958     while( !timetostop(&err) ){
   944    959       usleep(500*1000);
................................................................................
   973    988     }
   974    989     launch_thread(&err, &threads, walthread1_ckpt_thread, 0);
   975    990     join_all_threads(&err, &threads);
   976    991   
   977    992     print_and_free_err(&err);
   978    993   }
   979    994   
   980         -static char *walthread2_thread(int iTid, int iArg){
          995  +static char *walthread2_thread(int iTid, void *pArg){
   981    996     Error err = {0};                /* Error code and message */
   982    997     Sqlite db = {0};                /* SQLite database connection */
   983    998     int anTrans[2] = {0, 0};        /* Number of WAL and Rollback transactions */
          999  +  int iArg = PTR2INT(pArg);
   984   1000   
   985   1001     const char *zJournal = "PRAGMA journal_mode = WAL";
   986   1002     if( iArg ){ zJournal = "PRAGMA journal_mode = DELETE"; }
   987   1003   
   988   1004     while( !timetostop(&err) ){
   989   1005       int journal_exists = 0;
   990   1006       int wal_exists = 0;
................................................................................
  1022   1038     opendb(&err, &db, "test.db", 1);
  1023   1039     sql_script(&err, &db, "CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE)");
  1024   1040     closedb(&err, &db);
  1025   1041   
  1026   1042     setstoptime(&err, nMs);
  1027   1043     launch_thread(&err, &threads, walthread2_thread, 0);
  1028   1044     launch_thread(&err, &threads, walthread2_thread, 0);
  1029         -  launch_thread(&err, &threads, walthread2_thread, 1);
  1030         -  launch_thread(&err, &threads, walthread2_thread, 1);
         1045  +  launch_thread(&err, &threads, walthread2_thread, (void*)1);
         1046  +  launch_thread(&err, &threads, walthread2_thread, (void*)1);
  1031   1047     join_all_threads(&err, &threads);
  1032   1048   
  1033   1049     print_and_free_err(&err);
  1034   1050   }
  1035   1051   
  1036         -static char *walthread3_thread(int iTid, int iArg){
         1052  +static char *walthread3_thread(int iTid, void *pArg){
  1037   1053     Error err = {0};                /* Error code and message */
  1038   1054     Sqlite db = {0};                /* SQLite database connection */
  1039   1055     i64 iNextWrite;                 /* Next value this thread will write */
         1056  +  int iArg = PTR2INT(pArg);
  1040   1057   
  1041   1058     opendb(&err, &db, "test.db", 0);
  1042   1059     sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 10");
  1043   1060   
  1044   1061     iNextWrite = iArg+1;
  1045   1062     while( 1 ){
  1046   1063       i64 sum1;
................................................................................
  1083   1100         "CREATE INDEX i2 ON t1(sum2);"
  1084   1101         "INSERT INTO t1 VALUES(0, 0, 0);"
  1085   1102     );
  1086   1103     closedb(&err, &db);
  1087   1104   
  1088   1105     setstoptime(&err, nMs);
  1089   1106     for(i=0; i<WALTHREAD3_NTHREAD; i++){
  1090         -    launch_thread(&err, &threads, walthread3_thread, i);
         1107  +    launch_thread(&err, &threads, walthread3_thread, INT2PTR(i));
  1091   1108     }
  1092   1109     join_all_threads(&err, &threads);
  1093   1110   
  1094   1111     print_and_free_err(&err);
  1095   1112   }
  1096   1113   
  1097         -static char *walthread4_reader_thread(int iTid, int iArg){
         1114  +static char *walthread4_reader_thread(int iTid, void *pArg){
  1098   1115     Error err = {0};                /* Error code and message */
  1099   1116     Sqlite db = {0};                /* SQLite database connection */
  1100   1117   
  1101   1118     opendb(&err, &db, "test.db", 0);
  1102   1119     while( !timetostop(&err) ){
  1103   1120       integrity_check(&err, &db);
  1104   1121     }
  1105   1122     closedb(&err, &db);
  1106   1123   
  1107   1124     print_and_free_err(&err);
  1108   1125     return 0;
  1109   1126   }
  1110   1127   
  1111         -static char *walthread4_writer_thread(int iTid, int iArg){
         1128  +static char *walthread4_writer_thread(int iTid, void *pArg){
  1112   1129     Error err = {0};                /* Error code and message */
  1113   1130     Sqlite db = {0};                /* SQLite database connection */
  1114   1131     i64 iRow = 1;
  1115   1132   
  1116   1133     opendb(&err, &db, "test.db", 0);
  1117   1134     sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 15;");
  1118   1135     while( !timetostop(&err) ){
................................................................................
  1144   1161     launch_thread(&err, &threads, walthread4_reader_thread, 0);
  1145   1162     launch_thread(&err, &threads, walthread4_writer_thread, 0);
  1146   1163     join_all_threads(&err, &threads);
  1147   1164   
  1148   1165     print_and_free_err(&err);
  1149   1166   }
  1150   1167   
  1151         -static char *walthread5_thread(int iTid, int iArg){
         1168  +static char *walthread5_thread(int iTid, void *pArg){
  1152   1169     Error err = {0};                /* Error code and message */
  1153   1170     Sqlite db = {0};                /* SQLite database connection */
  1154   1171     i64 nRow;
  1155   1172   
  1156   1173     opendb(&err, &db, "test.db", 0);
  1157   1174     nRow = execsql_i64(&err, &db, "SELECT count(*) FROM t1");
  1158   1175     closedb(&err, &db);
................................................................................
  1276   1293   ** Test case "dynamic_triggers"
  1277   1294   **
  1278   1295   **   Two threads executing statements that cause deeply nested triggers
  1279   1296   **   to fire. And one thread busily creating and deleting triggers. This
  1280   1297   **   is an attempt to find a bug reported to us.
  1281   1298   */
  1282   1299   
  1283         -static char *dynamic_triggers_1(int iTid, int iArg){
         1300  +static char *dynamic_triggers_1(int iTid, void *pArg){
  1284   1301     Error err = {0};                /* Error code and message */
  1285   1302     Sqlite db = {0};                /* SQLite database connection */
  1286   1303     int nDrop = 0;
  1287   1304     int nCreate = 0;
  1288   1305   
  1289   1306     opendb(&err, &db, "test.db", 0);
  1290   1307     while( !timetostop(&err) ){
................................................................................
  1327   1344       }
  1328   1345     }
  1329   1346   
  1330   1347     print_and_free_err(&err);
  1331   1348     return sqlite3_mprintf("%d created, %d dropped", nCreate, nDrop);
  1332   1349   }
  1333   1350   
  1334         -static char *dynamic_triggers_2(int iTid, int iArg){
         1351  +static char *dynamic_triggers_2(int iTid, void *pArg){
  1335   1352     Error err = {0};                /* Error code and message */
  1336   1353     Sqlite db = {0};                /* SQLite database connection */
  1337   1354     i64 iVal = 0;
  1338   1355     int nInsert = 0;
  1339   1356     int nDelete = 0;
  1340   1357   
  1341   1358     opendb(&err, &db, "test.db", 0);
................................................................................
  1378   1395     );
  1379   1396   
  1380   1397     setstoptime(&err, nMs);
  1381   1398   
  1382   1399     sqlite3_enable_shared_cache(1);
  1383   1400     launch_thread(&err, &threads, dynamic_triggers_2, 0);
  1384   1401     launch_thread(&err, &threads, dynamic_triggers_2, 0);
  1385         -  sqlite3_enable_shared_cache(0);
  1386   1402   
  1387   1403     sleep(2);
         1404  +  sqlite3_enable_shared_cache(0);
  1388   1405   
  1389   1406     launch_thread(&err, &threads, dynamic_triggers_2, 0);
  1390   1407     launch_thread(&err, &threads, dynamic_triggers_1, 0);
  1391   1408   
  1392   1409     join_all_threads(&err, &threads);
  1393   1410   
  1394   1411     print_and_free_err(&err);
................................................................................
  1421   1438       { checkpoint_starvation_1, "checkpoint_starvation_1", 10000 },
  1422   1439       { checkpoint_starvation_2, "checkpoint_starvation_2", 10000 },
  1423   1440   
  1424   1441       { create_drop_index_1, "create_drop_index_1", 10000 },
  1425   1442       { lookaside1,          "lookaside1", 10000 },
  1426   1443       { vacuum1,             "vacuum1", 10000 },
  1427   1444       { stress1,             "stress1", 10000 },
         1445  +    { stress2,             "stress2", 10000 },
  1428   1446     };
  1429   1447   
  1430   1448     int i;
  1431   1449     char *zTest = 0;
  1432   1450     int nTest = 0;
  1433   1451     int bTestfound = 0;
  1434   1452     int bPrefix = 0;
................................................................................
  1439   1457       nTest = strlen(zTest);
  1440   1458       if( zTest[nTest-1]=='*' ){
  1441   1459         nTest--;
  1442   1460         bPrefix = 1;
  1443   1461       }
  1444   1462     }
  1445   1463   
         1464  +  sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
  1446   1465     sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
  1447   1466   
  1448   1467     for(i=0; i<sizeof(aTest)/sizeof(aTest[0]); i++){
  1449   1468       char const *z = aTest[i].zTest;
  1450   1469       int n = strlen(z);
  1451   1470       if( !zTest || ((bPrefix || n==nTest) && 0==strncmp(zTest, z, nTest)) ){
  1452   1471         printf("Running %s for %d seconds...\n", z, aTest[i].nMs/1000);

Changes to test/tt3_checkpoint.c.

    62     62     }
    63     63     if( nFrame>=CHECKPOINT_STARVATION_FRAMELIMIT ){
    64     64       sqlite3_wal_checkpoint_v2(db, zDb, p->eMode, 0, 0);
    65     65     }
    66     66     return SQLITE_OK;
    67     67   }
    68     68   
    69         -static char *checkpoint_starvation_reader(int iTid, int iArg){
           69  +static char *checkpoint_starvation_reader(int iTid, void *pArg){
    70     70     Error err = {0};
    71     71     Sqlite db = {0};
    72     72   
    73     73     opendb(&err, &db, "test.db", 0);
    74     74     while( !timetostop(&err) ){
    75     75       i64 iCount1, iCount2;
    76     76       sql_script(&err, &db, "BEGIN");

Changes to test/tt3_index.c.

    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   **     create_drop_index_1
    14     14   */
    15     15   
    16     16   
    17         -static char *create_drop_index_thread(int iTid, int iArg){
           17  +static char *create_drop_index_thread(int iTid, void *pArg){
    18     18     Error err = {0};                /* Error code and message */
    19     19     Sqlite db = {0};                /* SQLite database connection */
    20     20   
    21     21     while( !timetostop(&err) ){
    22     22       opendb(&err, &db, "test.db", 0);
    23     23   
    24     24       sql_script(&err, &db, 

Changes to test/tt3_lookaside1.c.

    14     14   */
    15     15   
    16     16   /*
    17     17   ** The test in this file attempts to expose a specific race condition
    18     18   ** that is suspected to exist at time of writing.
    19     19   */
    20     20   
    21         -static char *lookaside1_thread_reader(int iTid, int iArg){
           21  +static char *lookaside1_thread_reader(int iTid, void *pArg){
    22     22     Error err = {0};                /* Error code and message */
    23     23     Sqlite db = {0};                /* SQLite database connection */
    24     24   
    25     25     opendb(&err, &db, "test.db", 0);
    26     26   
    27     27     while( !timetostop(&err) ){
    28     28       sqlite3_stmt *pStmt = 0;
................................................................................
    39     39     }
    40     40   
    41     41     closedb(&err, &db);
    42     42     print_and_free_err(&err);
    43     43     return sqlite3_mprintf("ok");
    44     44   }
    45     45   
    46         -static char *lookaside1_thread_writer(int iTid, int iArg){
           46  +static char *lookaside1_thread_writer(int iTid, void *pArg){
    47     47     Error err = {0};                /* Error code and message */
    48     48     Sqlite db = {0};                /* SQLite database connection */
    49     49   
    50     50     opendb(&err, &db, "test.db", 0);
    51     51   
    52     52     do{
    53     53       sql_script(&err, &db, 

Changes to test/tt3_stress.c.

    13     13   **
    14     14   */
    15     15   
    16     16   
    17     17   /*
    18     18   ** Thread 1. CREATE and DROP a table.
    19     19   */
    20         -static char *stress_thread_1(int iTid, int iArg){
           20  +static char *stress_thread_1(int iTid, void *pArg){
    21     21     Error err = {0};                /* Error code and message */
    22     22     Sqlite db = {0};                /* SQLite database connection */
    23     23   
    24     24     opendb(&err, &db, "test.db", 0);
    25     25     while( !timetostop(&err) ){
    26     26       sql_script(&err, &db, "CREATE TABLE IF NOT EXISTS t1(a PRIMARY KEY, b)");
    27     27       clear_error(&err, SQLITE_LOCKED);
................................................................................
    32     32     print_and_free_err(&err);
    33     33     return sqlite3_mprintf("ok");
    34     34   }
    35     35   
    36     36   /*
    37     37   ** Thread 2. Open and close database connections.
    38     38   */
    39         -static char *stress_thread_2(int iTid, int iArg){
           39  +static char *stress_thread_2(int iTid, void *pArg){
    40     40     Error err = {0};                /* Error code and message */
    41     41     Sqlite db = {0};                /* SQLite database connection */
    42     42     while( !timetostop(&err) ){
    43     43       opendb(&err, &db, "test.db", 0);
    44     44       sql_script(&err, &db, "SELECT * FROM sqlite_master;");
    45     45       clear_error(&err, SQLITE_LOCKED);
    46     46       closedb(&err, &db);
................................................................................
    48     48     print_and_free_err(&err);
    49     49     return sqlite3_mprintf("ok");
    50     50   }
    51     51   
    52     52   /*
    53     53   ** Thread 3. Attempt many small SELECT statements.
    54     54   */
    55         -static char *stress_thread_3(int iTid, int iArg){
           55  +static char *stress_thread_3(int iTid, void *pArg){
    56     56     Error err = {0};                /* Error code and message */
    57     57     Sqlite db = {0};                /* SQLite database connection */
    58     58   
    59     59     int i1 = 0;
    60     60     int i2 = 0;
    61     61   
    62     62     opendb(&err, &db, "test.db", 0);
................................................................................
    71     71     print_and_free_err(&err);
    72     72     return sqlite3_mprintf("read t1 %d/%d attempts", i2, i1);
    73     73   }
    74     74   
    75     75   /*
    76     76   ** Thread 5. Attempt INSERT statements.
    77     77   */
    78         -static char *stress_thread_4(int iTid, int iArg){
           78  +static char *stress_thread_4(int iTid, void *pArg){
    79     79     Error err = {0};                /* Error code and message */
    80     80     Sqlite db = {0};                /* SQLite database connection */
    81     81     int i1 = 0;
    82     82     int i2 = 0;
           83  +  int iArg = PTR2INT(pArg);
           84  +
    83     85     opendb(&err, &db, "test.db", 0);
    84     86     while( !timetostop(&err) ){
    85     87       if( iArg ){
    86     88         closedb(&err, &db);
    87     89         opendb(&err, &db, "test.db", 0);
    88     90       }
    89     91       sql_script(&err, &db, 
................................................................................
    99    101     print_and_free_err(&err);
   100    102     return sqlite3_mprintf("wrote t1 %d/%d attempts", i2, i1);
   101    103   }
   102    104   
   103    105   /*
   104    106   ** Thread 6. Attempt DELETE operations.
   105    107   */
   106         -static char *stress_thread_5(int iTid, int iArg){
          108  +static char *stress_thread_5(int iTid, void *pArg){
   107    109     Error err = {0};                /* Error code and message */
   108    110     Sqlite db = {0};                /* SQLite database connection */
          111  +  int iArg = PTR2INT(pArg);
   109    112   
   110    113     int i1 = 0;
   111    114     int i2 = 0;
   112    115   
   113    116     opendb(&err, &db, "test.db", 0);
   114    117     while( !timetostop(&err) ){
   115    118       i64 i = (i1 % 4);
................................................................................
   127    130     print_and_free_err(&err);
   128    131     return sqlite3_mprintf("deleted from t1 %d/%d attempts", i2, i1);
   129    132   }
   130    133   
   131    134   
   132    135   static void stress1(int nMs){
   133    136     Error err = {0};
   134         -  Sqlite db = {0};
   135    137     Threadset threads = {0};
   136    138   
   137         -
   138    139     setstoptime(&err, nMs);
   139         -
   140    140     sqlite3_enable_shared_cache(1);
   141    141   
   142    142     launch_thread(&err, &threads, stress_thread_1, 0);
   143    143     launch_thread(&err, &threads, stress_thread_1, 0);
   144    144   
   145    145     launch_thread(&err, &threads, stress_thread_2, 0);
   146    146     launch_thread(&err, &threads, stress_thread_2, 0);
................................................................................
   148    148     launch_thread(&err, &threads, stress_thread_3, 0);
   149    149     launch_thread(&err, &threads, stress_thread_3, 0);
   150    150   
   151    151     launch_thread(&err, &threads, stress_thread_4, 0);
   152    152     launch_thread(&err, &threads, stress_thread_4, 0);
   153    153   
   154    154     launch_thread(&err, &threads, stress_thread_5, 0);
   155         -  launch_thread(&err, &threads, stress_thread_5, 1);
          155  +  launch_thread(&err, &threads, stress_thread_5, (void*)1);
   156    156   
   157    157     join_all_threads(&err, &threads);
   158    158     sqlite3_enable_shared_cache(0);
   159    159   
   160    160     print_and_free_err(&err);
   161    161   }
          162  +
          163  +/**************************************************************************
          164  +***************************************************************************
          165  +** Start of test case "stress2"
          166  +*/
          167  +
          168  +
          169  +
          170  +/*
          171  +** 1.  CREATE TABLE statements.
          172  +** 2.  DROP TABLE statements.
          173  +** 3.  Small SELECT statements.
          174  +** 4.  Big SELECT statements.
          175  +** 5.  Small INSERT statements.
          176  +** 6.  Big INSERT statements.
          177  +** 7.  Small UPDATE statements.
          178  +** 8.  Big UPDATE statements.
          179  +** 9.  Small DELETE statements.
          180  +** 10. Big DELETE statements.
          181  +** 11. VACUUM.
          182  +** 14. Integrity-check.
          183  +** 17. Switch the journal mode from delete to wal and back again.
          184  +** 19. Open and close database connections rapidly.
          185  +*/
          186  +
          187  +#define STRESS2_TABCNT 5
          188  +
          189  +static void stress2_workload1(Error *pErr, Sqlite *pDb, int i){
          190  +  int iTab = (i % STRESS2_TABCNT);
          191  +  sql_script_printf(pErr, pDb, 
          192  +      "CREATE TABLE IF NOT EXISTS t%d(x PRIMARY KEY, y, z);", iTab
          193  +  );
          194  +}
          195  +
          196  +static void stress2_workload2(Error *pErr, Sqlite *pDb, int i){
          197  +  int iTab = (i % STRESS2_TABCNT);
          198  +  sql_script_printf(pErr, pDb, "DROP TABLE IF EXISTS t%d;", iTab);
          199  +}
          200  +
          201  +static void stress2_workload3(Error *pErr, Sqlite *pDb, int i){
          202  +  int iTab = (i % STRESS2_TABCNT);
          203  +  sql_script_printf(pErr, pDb, "SELECT * FROM t%d WHERE z = 'small'", iTab);
          204  +}
          205  +
          206  +static void stress2_workload4(Error *pErr, Sqlite *pDb, int i){
          207  +  int iTab = (i % STRESS2_TABCNT);
          208  +  sql_script_printf(pErr, pDb, "SELECT * FROM t%d WHERE z = 'big'", iTab);
          209  +}
          210  +
          211  +static void stress2_workload5(Error *pErr, Sqlite *pDb, int i){
          212  +  int iTab = (i % STRESS2_TABCNT);
          213  +  sql_script_printf(pErr, pDb,
          214  +      "INSERT INTO t%d VALUES(random(), hex(randomblob(57)), 'small');", iTab
          215  +  );
          216  +}
          217  +
          218  +static void stress2_workload6(Error *pErr, Sqlite *pDb, int i){
          219  +  int iTab = (i % STRESS2_TABCNT);
          220  +  sql_script_printf(pErr, pDb,
          221  +      "INSERT INTO t%d VALUES(random(), hex(randomblob(2000)), 'big');", iTab
          222  +  );
          223  +}
          224  +
          225  +static void stress2_workload7(Error *pErr, Sqlite *pDb, int i){
          226  +  int iTab = (i % STRESS2_TABCNT);
          227  +  sql_script_printf(pErr, pDb,
          228  +      "UPDATE t%d SET y = hex(randomblob(57)) "
          229  +      "WHERE (x %% 5)==(%d %% 5) AND z='small';"
          230  +      ,iTab, i
          231  +  );
          232  +}
          233  +static void stress2_workload8(Error *pErr, Sqlite *pDb, int i){
          234  +  int iTab = (i % STRESS2_TABCNT);
          235  +  sql_script_printf(pErr, pDb,
          236  +      "UPDATE t%d SET y = hex(randomblob(2000)) "
          237  +      "WHERE (x %% 5)==(%d %% 5) AND z='big';"
          238  +      ,iTab, i
          239  +  );
          240  +}
          241  +
          242  +static void stress2_workload9(Error *pErr, Sqlite *pDb, int i){
          243  +  int iTab = (i % STRESS2_TABCNT);
          244  +  sql_script_printf(pErr, pDb,
          245  +      "DELETE FROM t%d WHERE (x %% 5)==(%d %% 5) AND z='small';"
          246  +      ,iTab, i
          247  +  );
          248  +}
          249  +static void stress2_workload10(Error *pErr, Sqlite *pDb, int i){
          250  +  int iTab = (i % STRESS2_TABCNT);
          251  +  sql_script_printf(pErr, pDb,
          252  +      "DELETE FROM t%d WHERE (x %% 5)==(%d %% 5) AND z='big';"
          253  +      ,iTab, i
          254  +  );
          255  +}
          256  +
          257  +static void stress2_workload11(Error *pErr, Sqlite *pDb, int i){
          258  +  sql_script(pErr, pDb, "VACUUM");
          259  +}
          260  +
          261  +static void stress2_workload14(Error *pErr, Sqlite *pDb, int i){
          262  +  sql_script(pErr, pDb, "PRAGMA integrity_check");
          263  +}
          264  +
          265  +static void stress2_workload17(Error *pErr, Sqlite *pDb, int i){
          266  +  sql_script_printf(pErr, pDb, 
          267  +      "PRAGMA journal_mode = %q", (i%2) ? "delete" : "wal"
          268  +  );
          269  +}
          270  +
          271  +static char *stress2_workload19(int iTid, void *pArg){
          272  +  Error err = {0};                /* Error code and message */
          273  +  Sqlite db = {0};                /* SQLite database connection */
          274  +  const char *zDb = (const char*)pArg;
          275  +  while( !timetostop(&err) ){
          276  +    opendb(&err, &db, zDb, 0);
          277  +    sql_script(&err, &db, "SELECT * FROM sqlite_master;");
          278  +    clear_error(&err, SQLITE_LOCKED);
          279  +    closedb(&err, &db);
          280  +  }
          281  +  print_and_free_err(&err);
          282  +  return sqlite3_mprintf("ok");
          283  +}
          284  +
          285  +
          286  +typedef struct Stress2Ctx Stress2Ctx;
          287  +struct Stress2Ctx {
          288  +  const char *zDb;
          289  +  void (*xProc)(Error*, Sqlite*, int);
          290  +};
          291  +
          292  +static char *stress2_thread_wrapper(int iTid, void *pArg){
          293  +  Stress2Ctx *pCtx = (Stress2Ctx*)pArg;
          294  +  Error err = {0};                /* Error code and message */
          295  +  Sqlite db = {0};                /* SQLite database connection */
          296  +  int i1 = 0;
          297  +  int i2 = 0;
          298  +
          299  +  opendb(&err, &db, pCtx->zDb, 0);
          300  +  while( !timetostop(&err) ){
          301  +    pCtx->xProc(&err, &db, i1);
          302  +    i2 += (err.rc==SQLITE_OK);
          303  +    clear_error(&err, SQLITE_LOCKED);
          304  +    clear_error(&err, SQLITE_ERROR);
          305  +    i1++;
          306  +  }
          307  +
          308  +  print_and_free_err(&err);
          309  +  return sqlite3_mprintf("ok %d/%d", i2, i1);
          310  +}
          311  +
          312  +static void stress2_launch_thread_loop(
          313  +  Error *pErr,                    /* IN/OUT: Error code */
          314  +  Threadset *pThreads,            /* Thread set */
          315  +  const char *zDb,                /* Database name */
          316  +  void (*x)(Error*,Sqlite*,int)   /* Run this until error or timeout */
          317  +){
          318  +  Stress2Ctx *pCtx = sqlite3_malloc(sizeof(Stress2Ctx));
          319  +  pCtx->zDb = zDb;
          320  +  pCtx->xProc = x;
          321  +  launch_thread(pErr, pThreads, stress2_thread_wrapper, (void*)pCtx);
          322  +}
          323  +
          324  +static void stress2(int nMs){
          325  +  struct Stress2Task {
          326  +    void (*x)(Error*,Sqlite*,int);
          327  +  } aTask[] = {
          328  +    { stress2_workload1 },
          329  +    { stress2_workload2 },
          330  +    { stress2_workload3 },
          331  +    { stress2_workload4 },
          332  +    { stress2_workload5 },
          333  +    { stress2_workload6 },
          334  +    { stress2_workload7 },
          335  +    { stress2_workload8 },
          336  +    { stress2_workload9 },
          337  +    { stress2_workload10 },
          338  +    { stress2_workload11 },
          339  +    { stress2_workload14 },
          340  +    { stress2_workload17 },
          341  +  };
          342  +  const char *azDb[] = {
          343  +    "test.db",
          344  +    "file::memory:?cache=shared"
          345  +  };
          346  +  int j;
          347  +
          348  +  for(j=0; j<sizeof(azDb)/sizeof(azDb[0]); j++){
          349  +    int i;
          350  +    Error err = {0};
          351  +    Sqlite db = {0};
          352  +    Threadset threads = {0};
          353  +    const char *zDb = azDb[j];
          354  +
          355  +    /* To make sure the db file is empty before commencing */
          356  +    opendb(&err, &db, zDb, 1);
          357  +    closedb(&err, &db);
          358  +
          359  +    setstoptime(&err, nMs);
          360  +    sqlite3_enable_shared_cache(1);
          361  +
          362  +    for(i=0; i<sizeof(aTask)/sizeof(aTask[0]); i++){
          363  +      stress2_launch_thread_loop(&err, &threads, zDb, aTask[i].x);
          364  +    }
          365  +    launch_thread(&err, &threads, stress2_workload19, (void*)zDb);
          366  +    launch_thread(&err, &threads, stress2_workload19, (void*)zDb);
          367  +
          368  +    join_all_threads(&err, &threads);
          369  +    sqlite3_enable_shared_cache(0);
          370  +    print_and_free_err(&err);
          371  +    if( j==0 ){
          372  +      printf("Running stress2 (again, with in-memory db) for %d seconds...\n",
          373  +          nMs / 1000
          374  +      );
          375  +    }
          376  +  }
          377  +}
          378  +
          379  +
          380  +
          381  +

Changes to test/tt3_vacuum.c.

    16     16   ** Tests:
    17     17   **
    18     18   **     vacuum1
    19     19   **
    20     20   */
    21     21   
    22     22   
    23         -static char *vacuum1_thread_writer(int iTid, int iArg){
           23  +static char *vacuum1_thread_writer(int iTid, void *pArg){
    24     24     Error err = {0};                /* Error code and message */
    25     25     Sqlite db = {0};                /* SQLite database connection */
    26     26     opendb(&err, &db, "test.db", 0);
    27     27     i64 i = 0;
    28     28   
    29     29     while( !timetostop(&err) ){
    30     30       i++;
................................................................................
    45     45     }
    46     46   
    47     47     closedb(&err, &db);
    48     48     print_and_free_err(&err);
    49     49     return sqlite3_mprintf("ok");
    50     50   }
    51     51   
    52         -static char *vacuum1_thread_vacuumer(int iTid, int iArg){
           52  +static char *vacuum1_thread_vacuumer(int iTid, void *pArg){
    53     53     Error err = {0};                /* Error code and message */
    54     54     Sqlite db = {0};                /* SQLite database connection */
    55     55     opendb(&err, &db, "test.db", 0);
    56     56   
    57     57     do{
    58     58       sql_script(&err, &db, "VACUUM");
    59     59       clear_error(&err, SQLITE_LOCKED);