/ Check-in [a726d981]
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 | SQL 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
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: 05b4fc43 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: a726d981 user: dan tags: server-edition
2017-05-15
19:32
Avoid writer starvation by adding a RESERVED state to page locks. check-in: 9b7f8024 user: dan tags: server-edition
Changes
Hide Diffs Unified Diffs Show Whitespace Changes 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
...
450
451
452
453
454
455
456












457
458
459
460
461
462
463
...
564
565
566
567
568
569
570





571
572
573
574
575
576
577
578
579
580
581
582
583
  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
................................................................................
      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;
}
................................................................................
    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 */







|
>







 







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







 







>
>
>
>
>













89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
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
...
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
  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
................................................................................
      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;
}
................................................................................
    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 */