/ Check-in [9fb5e212]
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:Improvements to comments. Store some extra information in SqliteThread that is useful for debugging.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | threads
Files: files | file ages | folders
SHA1: 9fb5e212089d85cdd3b4787dd69c72e6d84560b6
User & Date: drh 2014-04-24 12:28:28
Context
2014-05-02
16:03
Remove a faulty assert() from vdbesort.c. check-in: d95d68aa user: dan tags: threads
2014-04-24
12:28
Improvements to comments. Store some extra information in SqliteThread that is useful for debugging. check-in: 9fb5e212 user: drh tags: threads
2014-04-23
12:57
Merge all recent trunk changes into the threads branch. check-in: e2c9f71a user: drh tags: threads
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/threads.c.

    33     33   #if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0
    34     34   
    35     35   #define SQLITE_THREADS_IMPLEMENTED 1  /* Prevent the single-thread code below */
    36     36   #include <pthread.h>
    37     37   
    38     38   /* A running thread */
    39     39   struct SQLiteThread {
    40         -  pthread_t tid;
    41         -  int done;
    42         -  void *pOut;
           40  +  pthread_t tid;                 /* Thread ID */
           41  +  int done;                      /* Set to true when thread finishes */
           42  +  void *pOut;                    /* Result returned by the thread */
           43  +  void *(*xTask)(void*);         /* The thread routine */
           44  +  void *pIn;                     /* Argument to the thread */
    43     45   };
    44     46   
    45     47   /* Create a new thread */
    46     48   int sqlite3ThreadCreate(
    47     49     SQLiteThread **ppThread,  /* OUT: Write the thread object here */
    48     50     void *(*xTask)(void*),    /* Routine to run in a separate thread */
    49     51     void *pIn                 /* Argument passed into xTask() */
................................................................................
    52     54   
    53     55     assert( ppThread!=0 );
    54     56     assert( xTask!=0 );
    55     57     *ppThread = 0;
    56     58     p = sqlite3Malloc(sizeof(*p));
    57     59     if( p==0 ) return SQLITE_NOMEM;
    58     60     memset(p, 0, sizeof(*p));
           61  +  p->xTask = xTask;
           62  +  p->pIn = pIn;
    59     63     if( sqlite3GlobalConfig.bCoreMutex==0
    60     64       || pthread_create(&p->tid, 0, xTask, pIn)!=0 
    61     65     ){
    62     66       p->done = 1;
    63     67       p->pOut = xTask(pIn);
    64     68     }
    65     69     *ppThread = p;

Changes to src/vdbesort.c.

    11     11   *************************************************************************
    12     12   ** This file contains code for the VdbeSorter object, used in concert with
    13     13   ** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements
    14     14   ** or by SELECT statements with ORDER BY clauses that cannot be satisfied
    15     15   ** using indexes and without LIMIT clauses.
    16     16   **
    17     17   ** The VdbeSorter object implements a multi-threaded external merge sort
    18         -** algorithm that is efficient even if the number of element being sorted
           18  +** algorithm that is efficient even if the number of elements being sorted
    19     19   ** exceeds the available memory.
    20     20   **
    21     21   ** Here is the (internal, non-API) interface between this module and the
    22     22   ** rest of the SQLite system:
    23     23   **
    24     24   **    sqlite3VdbeSorterInit()       Create a new VdbeSorter object.
    25     25   **
................................................................................
   100    100   ** The sorter is running in multi-threaded mode if (a) the library was built
   101    101   ** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater
   102    102   ** than zero, and (b) worker threads have been enabled at runtime by calling
   103    103   ** sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, ...).
   104    104   **
   105    105   ** When Rewind() is called, any data remaining in memory is flushed to a 
   106    106   ** final PMA. So at this point the data is stored in some number of sorted
   107         -** PMAs within temporary files on disk. Within a single file sorter is 
   108         -** running in single threaded mode, or distributed between one or more files
   109         -** for multi-threaded sorters.
          107  +** PMAs within temporary files on disk.
   110    108   **
   111    109   ** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the
   112    110   ** sorter is running in single-threaded mode, then these PMAs are merged
   113    111   ** incrementally as keys are retreived from the sorter by the VDBE. See
   114    112   ** comments above object MergeEngine below for details.
   115    113   **
   116    114   ** Or, if running in multi-threaded mode, then a background thread is
................................................................................
   154    152   typedef struct MergeEngine MergeEngine;     /* Merge PMAs together */
   155    153   typedef struct PmaReader PmaReader;         /* Incrementally read one PMA */
   156    154   typedef struct PmaWriter PmaWriter;         /* Incrementally write one PMA */
   157    155   typedef struct SorterRecord SorterRecord;   /* A record being sorted */
   158    156   typedef struct SortSubtask SortSubtask;     /* A sub-task in the sort process */
   159    157   typedef struct SorterFile SorterFile;       /* Temporary file object wrapper */
   160    158   typedef struct SorterList SorterList;       /* In-memory list of records */
   161         -typedef struct IncrMerger IncrMerger;
          159  +typedef struct IncrMerger IncrMerger;       /* Read & merge multiple PMAs */
   162    160   
   163    161   /*
   164    162   ** A container for a temp file handle and the current amount of data 
   165    163   ** stored in the file.
   166    164   */
   167    165   struct SorterFile {
   168    166     sqlite3_file *pFd;              /* File handle */
   169    167     i64 iEof;                       /* Bytes of data stored in pFd */
   170    168   };
   171    169   
   172    170   /*
   173         -** In memory linked list of records.
          171  +** An in-memory list of objects to be sorted.
          172  +**
          173  +** If aMemory==0 then each object is allocated separately and the objects
          174  +** are connected using SorterRecord.u.pNext.  If aMemory!=0 then all objects
          175  +** are stored in the aMemory[] bulk memory, one right after the other, and
          176  +** are connected using SorterRecord.u.iNext.
   174    177   */
   175    178   struct SorterList {
   176    179     SorterRecord *pList;            /* Linked list of records */
   177         -  u8 *aMemory;                    /* If non-NULL, blob of memory for pList */
          180  +  u8 *aMemory;                    /* If non-NULL, bulk memory to hold pList */
   178    181     int szPMA;                      /* Size of pList as PMA in bytes */
   179    182   };
   180    183   
   181    184   /*
   182    185   ** The MergeEngine object is used to combine two or more smaller PMAs into
   183    186   ** one big PMA using a merge operation.  Separate PMAs all need to be
   184    187   ** combined into one big PMA in order to be able to step through the sorted