/ Check-in [1b598c68]
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 SQLITE_LIMIT_WORKER_THREADS for controlling the maximum number of worker threads.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | threads
Files: files | file ages | folders
SHA1: 1b598c68f32db635d1cea1373bedc434aa60cf08
User & Date: drh 2014-08-29 16:20:47
Context
2014-08-29
18:06
Fix the speedtest1.c test program to set the worker thread count using the threads pragma. check-in: 2ab4b5ad user: drh tags: threads
16:20
Add SQLITE_LIMIT_WORKER_THREADS for controlling the maximum number of worker threads. check-in: 1b598c68 user: drh tags: threads
14:40
Merge recent performance enhancements from trunk onto the threads branch. check-in: 35c44a3c user: drh tags: threads
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

  2074   2074     SQLITE_MAX_COMPOUND_SELECT,
  2075   2075     SQLITE_MAX_VDBE_OP,
  2076   2076     SQLITE_MAX_FUNCTION_ARG,
  2077   2077     SQLITE_MAX_ATTACHED,
  2078   2078     SQLITE_MAX_LIKE_PATTERN_LENGTH,
  2079   2079     SQLITE_MAX_VARIABLE_NUMBER,      /* IMP: R-38091-32352 */
  2080   2080     SQLITE_MAX_TRIGGER_DEPTH,
         2081  +  SQLITE_MAX_WORKER_THREADS,
  2081   2082   };
  2082   2083   
  2083   2084   /*
  2084   2085   ** Make sure the hard limits are set to reasonable values
  2085   2086   */
  2086   2087   #if SQLITE_MAX_LENGTH<100
  2087   2088   # error SQLITE_MAX_LENGTH must be at least 100
................................................................................
  2109   2110   #endif
  2110   2111   #if SQLITE_MAX_COLUMN>32767
  2111   2112   # error SQLITE_MAX_COLUMN must not exceed 32767
  2112   2113   #endif
  2113   2114   #if SQLITE_MAX_TRIGGER_DEPTH<1
  2114   2115   # error SQLITE_MAX_TRIGGER_DEPTH must be at least 1
  2115   2116   #endif
         2117  +#if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50
         2118  +# error SQLITE_MAX_WORKER_THREADS must be between 0 and 50
         2119  +#endif
  2116   2120   
  2117   2121   
  2118   2122   /*
  2119   2123   ** Change the value of a limit.  Report the old value.
  2120   2124   ** If an invalid limit index is supplied, report -1.
  2121   2125   ** Make no changes but still report the old value if the
  2122   2126   ** new limit is negative.
................................................................................
  2142   2146     assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
  2143   2147     assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
  2144   2148     assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
  2145   2149     assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
  2146   2150                                                  SQLITE_MAX_LIKE_PATTERN_LENGTH );
  2147   2151     assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
  2148   2152     assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
  2149         -  assert( SQLITE_LIMIT_TRIGGER_DEPTH==(SQLITE_N_LIMIT-1) );
         2153  +  assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
         2154  +  assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) );
  2150   2155   
  2151   2156   
  2152   2157     if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
  2153   2158       return -1;
  2154   2159     }
  2155   2160     oldLimit = db->aLimit[limitId];
  2156   2161     if( newLimit>=0 ){                   /* IMP: R-52476-28732 */
................................................................................
  2489   2494     db->errMask = 0xff;
  2490   2495     db->nDb = 2;
  2491   2496     db->magic = SQLITE_MAGIC_BUSY;
  2492   2497     db->aDb = db->aDbStatic;
  2493   2498   
  2494   2499     assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
  2495   2500     memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
         2501  +  db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = 0;
  2496   2502     db->autoCommit = 1;
  2497   2503     db->nextAutovac = -1;
  2498   2504     db->szMmap = sqlite3GlobalConfig.szMmap;
  2499   2505     db->nextPagesize = 0;
  2500   2506     db->nMaxSorterMmap = 0x7FFFFFFF;
  2501   2507     db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
  2502   2508   #if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX

Changes to src/pragma.c.

  2283   2283     **   PRAGMA threads = N
  2284   2284     **
  2285   2285     ** Configure the maximum number of worker threads.  Return the new
  2286   2286     ** maximum, which might be less than requested.
  2287   2287     */
  2288   2288     case PragTyp_THREADS: {
  2289   2289       sqlite3_int64 N;
  2290         -    if( sqlite3GlobalConfig.bCoreMutex
  2291         -     && zRight
         2290  +    if( zRight
  2292   2291        && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
  2293   2292        && N>=0
  2294   2293       ){
  2295         -      if( N>SQLITE_MAX_WORKER_THREADS ) N = SQLITE_MAX_WORKER_THREADS;
  2296         -      db->mxWorker = N&0xff;
         2294  +      sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
  2297   2295       }
  2298         -    returnSingleInt(pParse, "soft_heap_limit",  db->mxWorker);
         2296  +    returnSingleInt(pParse, "threads",
         2297  +                    sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
  2299   2298       break;
  2300   2299     }
  2301   2300   
  2302   2301   #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
  2303   2302     /*
  2304   2303     ** Report the current state of file logs for all databases
  2305   2304     */

Changes to src/sqlite.h.in.

  3069   3069   **
  3070   3070   ** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
  3071   3071   ** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
  3072   3072   ** <dd>The maximum index number of any [parameter] in an SQL statement.)^
  3073   3073   **
  3074   3074   ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
  3075   3075   ** <dd>The maximum depth of recursion for triggers.</dd>)^
         3076  +**
         3077  +** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
         3078  +** <dd>The maximum number of separate worker threads that a single
         3079  +** [database connection] may start to help it with a computation.</dd>)^
  3076   3080   ** </dl>
  3077   3081   */
  3078   3082   #define SQLITE_LIMIT_LENGTH                    0
  3079   3083   #define SQLITE_LIMIT_SQL_LENGTH                1
  3080   3084   #define SQLITE_LIMIT_COLUMN                    2
  3081   3085   #define SQLITE_LIMIT_EXPR_DEPTH                3
  3082   3086   #define SQLITE_LIMIT_COMPOUND_SELECT           4
  3083   3087   #define SQLITE_LIMIT_VDBE_OP                   5
  3084   3088   #define SQLITE_LIMIT_FUNCTION_ARG              6
  3085   3089   #define SQLITE_LIMIT_ATTACHED                  7
  3086   3090   #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
  3087   3091   #define SQLITE_LIMIT_VARIABLE_NUMBER           9
  3088   3092   #define SQLITE_LIMIT_TRIGGER_DEPTH            10
         3093  +#define SQLITE_LIMIT_WORKER_THREADS           11
  3089   3094   
  3090   3095   /*
  3091   3096   ** CAPI3REF: Compiling An SQL Statement
  3092   3097   ** KEYWORDS: {SQL statement compiler}
  3093   3098   **
  3094   3099   ** To execute an SQL query, it must first be compiled into a byte-code
  3095   3100   ** program using one of these routines.

Changes to src/sqliteInt.h.

   937    937   #define DB_UnresetViews    0x0002  /* Some views have defined column names */
   938    938   #define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */
   939    939   
   940    940   /*
   941    941   ** The number of different kinds of things that can be limited
   942    942   ** using the sqlite3_limit() interface.
   943    943   */
   944         -#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1)
          944  +#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)
   945    945   
   946    946   /*
   947    947   ** Lookaside malloc is a set of fixed-size buffers that can be used
   948    948   ** to satisfy small transient memory allocation requests for objects
   949    949   ** associated with a particular database connection.  The use of
   950    950   ** lookaside malloc provides a significant performance enhancement
   951    951   ** (approx 10%) by avoiding numerous malloc/free requests while parsing
................................................................................
  1009   1009     u8 temp_store;                /* 1: file 2: memory 0: default */
  1010   1010     u8 mallocFailed;              /* True if we have seen a malloc failure */
  1011   1011     u8 dfltLockMode;              /* Default locking-mode for attached dbs */
  1012   1012     signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
  1013   1013     u8 suppressErr;               /* Do not issue error messages if true */
  1014   1014     u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
  1015   1015     u8 isTransactionSavepoint;    /* True if the outermost savepoint is a TS */
  1016         -  u8 mxWorker;                  /* Maximum number of worker threads */
  1017   1016     int nextPagesize;             /* Pagesize after VACUUM if >0 */
  1018   1017     u32 magic;                    /* Magic number for detect library misuse */
  1019   1018     int nChange;                  /* Value returned by sqlite3_changes() */
  1020   1019     int nTotalChange;             /* Value returned by sqlite3_total_changes() */
  1021   1020     int aLimit[SQLITE_N_LIMIT];   /* Limits */
  1022   1021     int nMaxSorterMmap;           /* Maximum size of regions mapped by sorter */
  1023   1022     struct sqlite3InitInfo {      /* Information used during initialization */

Changes to src/vdbesort.c.

   792    792     KeyInfo *pKeyInfo;              /* Copy of pCsr->pKeyInfo with db==0 */
   793    793     int szKeyInfo;                  /* Size of pCsr->pKeyInfo in bytes */
   794    794     int sz;                         /* Size of pSorter in bytes */
   795    795     int rc = SQLITE_OK;
   796    796   #if SQLITE_MAX_WORKER_THREADS==0
   797    797   # define nWorker 0
   798    798   #else
   799         -  int nWorker = sqlite3TempInMemory(db) ? 0 : db->mxWorker ;
          799  +  int nWorker;
          800  +#endif
          801  +
          802  +  /* Initialize the upper limit on the number of worker threads */
          803  +#if SQLITE_MAX_WORKER_THREADS>0
          804  +  if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){
          805  +    nWorker = 0;
          806  +  }else{
          807  +    nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS];
          808  +  }
   800    809   #endif
   801    810   
   802    811     /* Do not allow the total number of threads (main thread + all workers)
   803    812     ** to exceed the maximum merge count */
   804    813   #if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT
   805    814     if( nWorker>=SORTER_MAX_MERGE_COUNT ){
   806    815       nWorker = SORTER_MAX_MERGE_COUNT-1;