SQLite

Check-in [a726d98122]
Login

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

Overview
Comment:Add code to this branch to emit a log message after each cumulative second that the WRITER lock has been held.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | server-edition
Files: files | file ages | folders
SHA3-256: a726d98122704e1e702cfa7ae61d680497df6a826d98082161e0823e115d40a5
User & Date: dan 2017-05-22 08:01:58.394
Context
2017-06-07
15:55
Add too/tserver.c - the implementation of a simple multi-threaded server designed for interactive testing of concurrency between connections used by different threads of the same process. (check-in: 05b4fc4340 user: dan tags: server-edition)
2017-05-22
08:01
Add code to this branch to emit a log message after each cumulative second that the WRITER lock has been held. (check-in: a726d98122 user: dan tags: server-edition)
2017-05-15
19:32
Avoid writer starvation by adding a RESERVED state to page locks. (check-in: 9b7f80246f user: dan tags: server-edition)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/pager.c.
7546
7547
7548
7549
7550
7551
7552

7553

7554
7555
7556
7557
7558
7559
7560
    /* Close any rollback journal previously open */
    sqlite3OsClose(pPager->jfd);

    rc = pagerOpenWal(pPager);
    if( rc==SQLITE_OK ){
      pPager->journalMode = PAGER_JOURNALMODE_WAL;
      pPager->eState = PAGER_OPEN;

      sqlite3WalServer(pPager->pWal, pPager->pServer);

    }
  }else{
    *pbOpen = 1;
  }

  return rc;
}







>

>







7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
    /* Close any rollback journal previously open */
    sqlite3OsClose(pPager->jfd);

    rc = pagerOpenWal(pPager);
    if( rc==SQLITE_OK ){
      pPager->journalMode = PAGER_JOURNALMODE_WAL;
      pPager->eState = PAGER_OPEN;
#ifdef SQLITE_SERVER_EDITION
      sqlite3WalServer(pPager->pWal, pPager->pServer);
#endif
    }
  }else{
    *pbOpen = 1;
  }

  return rc;
}
Changes to src/server.c.
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
  ino_t st_ino;
};

struct Server {
  ServerHMA *pHma;                /* Hma file object */
  int iClient;                    /* Client id */
  Pager *pPager;                  /* Associated pager object */


  int nAlloc;                     /* Allocated size of aLock[] array */
  int nLock;                      /* Number of entries in aLock[] */
  u32 *aLock;                     /* Mapped lock file */
};

#define SERVER_WRITE_LOCK 3
#define SERVER_READ_LOCK  2







|
>







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  ino_t st_ino;
};

struct Server {
  ServerHMA *pHma;                /* Hma file object */
  int iClient;                    /* Client id */
  Pager *pPager;                  /* Associated pager object */
  i64 nUsWrite;                   /* Cumulative us holding WRITER lock */
  i64 iUsWrite;                   /* Time WRITER lock was taken */
  int nAlloc;                     /* Allocated size of aLock[] array */
  int nLock;                      /* Number of entries in aLock[] */
  u32 *aLock;                     /* Mapped lock file */
};

#define SERVER_WRITE_LOCK 3
#define SERVER_READ_LOCK  2
450
451
452
453
454
455
456












457
458
459
460
461
462
463
      u32 n = v;
      if( (v>>HMA_CLIENT_SLOTS)==p->iClient+1 ){
        n = n & ((1 << HMA_CLIENT_SLOTS)-1);
      }
      n = n & ~(1 << p->iClient);
      if( __sync_val_compare_and_swap(pSlot, v, n)==v ) break;
    }












  }
  p->nLock = 0;
#if 1
  return posixLock(p->pHma->fd, p->iClient+1, SERVER_READ_LOCK, 0);
#endif
  return SQLITE_OK;
}







>
>
>
>
>
>
>
>
>
>
>
>







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
      u32 n = v;
      if( (v>>HMA_CLIENT_SLOTS)==p->iClient+1 ){
        n = n & ((1 << HMA_CLIENT_SLOTS)-1);
      }
      n = n & ~(1 << p->iClient);
      if( __sync_val_compare_and_swap(pSlot, v, n)==v ) break;
    }
    if( p->aLock[i]==0 ){
      struct timeval t2;
      i64 nUs;
      gettimeofday(&t2, 0);
      nUs = (i64)t2.tv_sec * 1000000 + t2.tv_usec - p->iUsWrite; 
      p->nUsWrite += nUs;
      if( (p->nUsWrite / 1000000)!=((p->nUsWrite + nUs)/1000000) ){
        sqlite3_log(SQLITE_WARNING, 
            "Cumulative WRITER time: %lldms\n", p->nUsWrite/1000
        );
      }
    }
  }
  p->nLock = 0;
#if 1
  return posixLock(p->pHma->fd, p->iClient+1, SERVER_READ_LOCK, 0);
#endif
  return SQLITE_OK;
}
564
565
566
567
568
569
570





571
572
573
574
575
576
577
578
579
580
581
582
583
    do{
      v = *pSlot;
      assert( serverWriteLocker(v)==p->iClient );
      n = v & ((1<<HMA_CLIENT_SLOTS)-1);
    }while( __sync_val_compare_and_swap(pSlot, v, n)!=v );
  }






  assert( rc!=SQLITE_OK || sqlite3ServerHasLock(p, pgno, bWrite) );
  return rc;
}

int sqlite3ServerHasLock(Server *p, Pgno pgno, int bWrite){
  u32 v = *serverPageLockSlot(p, pgno);
  if( bWrite ){
    return (v>>HMA_CLIENT_SLOTS)==(p->iClient+1);
  }
  return (v & (1 << p->iClient))!=0;
}

#endif /* ifdef SQLITE_SERVER_EDITION */







>
>
>
>
>













577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
    do{
      v = *pSlot;
      assert( serverWriteLocker(v)==p->iClient );
      n = v & ((1<<HMA_CLIENT_SLOTS)-1);
    }while( __sync_val_compare_and_swap(pSlot, v, n)!=v );
  }

  if( pgno==0 ){
    struct timeval t1;
    gettimeofday(&t1, 0);
    p->iUsWrite = ((i64)t1.tv_sec * 1000000) + (i64)t1.tv_usec;
  }
  assert( rc!=SQLITE_OK || sqlite3ServerHasLock(p, pgno, bWrite) );
  return rc;
}

int sqlite3ServerHasLock(Server *p, Pgno pgno, int bWrite){
  u32 v = *serverPageLockSlot(p, pgno);
  if( bWrite ){
    return (v>>HMA_CLIENT_SLOTS)==(p->iClient+1);
  }
  return (v & (1 << p->iClient))!=0;
}

#endif /* ifdef SQLITE_SERVER_EDITION */