223
180
* Sets whether or not we accept new connections.
225
void mt_accept_new_conns(const bool do_accept) {
182
void accept_new_conns(const bool do_accept) {
226
183
pthread_mutex_lock(&conn_lock);
227
184
do_accept_new_conns(do_accept);
228
185
pthread_mutex_unlock(&conn_lock);
232
* Pulls a conn structure from the freelist, if one is available.
234
conn *mt_conn_from_freelist() {
237
pthread_mutex_lock(&conn_lock);
238
c = do_conn_from_freelist();
239
pthread_mutex_unlock(&conn_lock);
246
* Adds a conn structure to the freelist.
248
* Returns 0 on success, 1 if the structure couldn't be added.
250
bool mt_conn_add_to_freelist(conn *c) {
253
pthread_mutex_lock(&conn_lock);
254
result = do_conn_add_to_freelist(c);
255
pthread_mutex_unlock(&conn_lock);
261
* Pulls a suffix buffer from the freelist, if one is available.
263
char *mt_suffix_from_freelist() {
266
pthread_mutex_lock(&suffix_lock);
267
s = do_suffix_from_freelist();
268
pthread_mutex_unlock(&suffix_lock);
275
* Adds a suffix buffer to the freelist.
277
* Returns 0 on success, 1 if the buffer couldn't be added.
279
bool mt_suffix_add_to_freelist(char *s) {
282
pthread_mutex_lock(&suffix_lock);
283
result = do_suffix_add_to_freelist(s);
284
pthread_mutex_unlock(&suffix_lock);
290
187
/****************************** LIBEVENT THREADS *****************************/
293
190
* Set up a thread's information.
295
192
static void setup_thread(LIBEVENT_THREAD *me) {
193
me->base = event_init();
296
194
if (! me->base) {
297
me->base = event_init();
299
fprintf(stderr, "Can't allocate event base\n");
195
fprintf(stderr, "Can't allocate event base\n");
304
199
/* Listen for notifications from other threads */
493
390
* Moves an item to the back of the LRU queue.
495
void mt_item_update(item *item) {
392
void item_update(item *item) {
496
393
pthread_mutex_lock(&cache_lock);
497
394
do_item_update(item);
498
395
pthread_mutex_unlock(&cache_lock);
502
* Adds an item to the deferred-delete list so it can be reaped later.
504
char *mt_defer_delete(item *item, time_t exptime) {
507
pthread_mutex_lock(&cache_lock);
508
ret = do_defer_delete(item, exptime);
509
pthread_mutex_unlock(&cache_lock);
514
399
* Does arithmetic on a numeric item value.
516
char *mt_add_delta(conn *c, item *item, int incr, const int64_t delta,
401
enum delta_result_type add_delta(conn *c, item *item, int incr,
402
const int64_t delta, char *buf) {
403
enum delta_result_type ret;
520
405
pthread_mutex_lock(&cache_lock);
521
406
ret = do_add_delta(c, item, incr, delta, buf);
560
445
* Dumps statistics about slab classes
562
char *mt_item_stats(int *bytes) {
447
void item_stats(ADD_STAT add_stats, void *c) {
565
448
pthread_mutex_lock(&cache_lock);
566
ret = do_item_stats(bytes);
449
do_item_stats(add_stats, c);
567
450
pthread_mutex_unlock(&cache_lock);
572
454
* Dumps a list of objects of each size in 32-byte increments
574
char *mt_item_stats_sizes(int *bytes) {
577
pthread_mutex_lock(&cache_lock);
578
ret = do_item_stats_sizes(bytes);
579
pthread_mutex_unlock(&cache_lock);
583
/****************************** HASHTABLE MODULE *****************************/
585
void mt_assoc_move_next_bucket() {
586
pthread_mutex_lock(&cache_lock);
587
do_assoc_move_next_bucket();
588
pthread_mutex_unlock(&cache_lock);
591
/******************************* SLAB ALLOCATOR ******************************/
593
void *mt_slabs_alloc(size_t size, unsigned int id) {
596
pthread_mutex_lock(&slabs_lock);
597
ret = do_slabs_alloc(size, id);
598
pthread_mutex_unlock(&slabs_lock);
602
void mt_slabs_free(void *ptr, size_t size, unsigned int id) {
603
pthread_mutex_lock(&slabs_lock);
604
do_slabs_free(ptr, size, id);
605
pthread_mutex_unlock(&slabs_lock);
608
char *mt_slabs_stats(int *buflen) {
611
pthread_mutex_lock(&slabs_lock);
612
ret = do_slabs_stats(buflen);
613
pthread_mutex_unlock(&slabs_lock);
617
#ifdef ALLOW_SLABS_REASSIGN
618
int mt_slabs_reassign(unsigned char srcid, unsigned char dstid) {
621
pthread_mutex_lock(&slabs_lock);
622
ret = do_slabs_reassign(srcid, dstid);
623
pthread_mutex_unlock(&slabs_lock);
456
void item_stats_sizes(ADD_STAT add_stats, void *c) {
457
pthread_mutex_lock(&cache_lock);
458
do_item_stats_sizes(add_stats, c);
459
pthread_mutex_unlock(&cache_lock);
628
462
/******************************* GLOBAL STATS ******************************/
630
void mt_stats_lock() {
631
465
pthread_mutex_lock(&stats_lock);
634
void mt_stats_unlock() {
468
void STATS_UNLOCK() {
635
469
pthread_mutex_unlock(&stats_lock);
472
void threadlocal_stats_reset(void) {
474
for (ii = 0; ii < settings.num_threads; ++ii) {
475
pthread_mutex_lock(&threads[ii].stats.mutex);
477
threads[ii].stats.get_cmds = 0;
478
threads[ii].stats.get_misses = 0;
479
threads[ii].stats.delete_misses = 0;
480
threads[ii].stats.incr_misses = 0;
481
threads[ii].stats.decr_misses = 0;
482
threads[ii].stats.cas_misses = 0;
483
threads[ii].stats.bytes_read = 0;
484
threads[ii].stats.bytes_written = 0;
485
threads[ii].stats.flush_cmds = 0;
486
threads[ii].stats.conn_yields = 0;
488
for(sid = 0; sid < MAX_NUMBER_OF_SLAB_CLASSES; sid++) {
489
threads[ii].stats.slab_stats[sid].set_cmds = 0;
490
threads[ii].stats.slab_stats[sid].get_hits = 0;
491
threads[ii].stats.slab_stats[sid].delete_hits = 0;
492
threads[ii].stats.slab_stats[sid].incr_hits = 0;
493
threads[ii].stats.slab_stats[sid].decr_hits = 0;
494
threads[ii].stats.slab_stats[sid].cas_hits = 0;
495
threads[ii].stats.slab_stats[sid].cas_badval = 0;
498
pthread_mutex_unlock(&threads[ii].stats.mutex);
502
void threadlocal_stats_aggregate(struct thread_stats *stats) {
504
/* The struct contains a mutex, so I should probably not memset it.. */
506
stats->get_misses = 0;
507
stats->delete_misses = 0;
508
stats->incr_misses = 0;
509
stats->decr_misses = 0;
510
stats->cas_misses = 0;
511
stats->bytes_written = 0;
512
stats->bytes_read = 0;
513
stats->flush_cmds = 0;
514
stats->conn_yields = 0;
516
memset(stats->slab_stats, 0,
517
sizeof(struct slab_stats) * MAX_NUMBER_OF_SLAB_CLASSES);
519
for (ii = 0; ii < settings.num_threads; ++ii) {
520
pthread_mutex_lock(&threads[ii].stats.mutex);
522
stats->get_cmds += threads[ii].stats.get_cmds;
523
stats->get_misses += threads[ii].stats.get_misses;
524
stats->delete_misses += threads[ii].stats.delete_misses;
525
stats->decr_misses += threads[ii].stats.decr_misses;
526
stats->incr_misses += threads[ii].stats.incr_misses;
527
stats->cas_misses += threads[ii].stats.cas_misses;
528
stats->bytes_read += threads[ii].stats.bytes_read;
529
stats->bytes_written += threads[ii].stats.bytes_written;
530
stats->flush_cmds += threads[ii].stats.flush_cmds;
531
stats->conn_yields += threads[ii].stats.conn_yields;
533
for (sid = 0; sid < MAX_NUMBER_OF_SLAB_CLASSES; sid++) {
534
stats->slab_stats[sid].set_cmds +=
535
threads[ii].stats.slab_stats[sid].set_cmds;
536
stats->slab_stats[sid].get_hits +=
537
threads[ii].stats.slab_stats[sid].get_hits;
538
stats->slab_stats[sid].delete_hits +=
539
threads[ii].stats.slab_stats[sid].delete_hits;
540
stats->slab_stats[sid].decr_hits +=
541
threads[ii].stats.slab_stats[sid].decr_hits;
542
stats->slab_stats[sid].incr_hits +=
543
threads[ii].stats.slab_stats[sid].incr_hits;
544
stats->slab_stats[sid].cas_hits +=
545
threads[ii].stats.slab_stats[sid].cas_hits;
546
stats->slab_stats[sid].cas_badval +=
547
threads[ii].stats.slab_stats[sid].cas_badval;
550
pthread_mutex_unlock(&threads[ii].stats.mutex);
554
void slab_stats_aggregate(struct thread_stats *stats, struct slab_stats *out) {
559
out->delete_hits = 0;
565
for (sid = 0; sid < MAX_NUMBER_OF_SLAB_CLASSES; sid++) {
566
out->set_cmds += stats->slab_stats[sid].set_cmds;
567
out->get_hits += stats->slab_stats[sid].get_hits;
568
out->delete_hits += stats->slab_stats[sid].delete_hits;
569
out->decr_hits += stats->slab_stats[sid].decr_hits;
570
out->incr_hits += stats->slab_stats[sid].incr_hits;
571
out->cas_hits += stats->slab_stats[sid].cas_hits;
572
out->cas_badval += stats->slab_stats[sid].cas_badval;
639
577
* Initializes the thread subsystem, creating various worker threads.
641
* nthreads Number of event handler threads to spawn
579
* nthreads Number of worker event handler threads to spawn
642
580
* main_base Event base for main thread
644
582
void thread_init(int nthreads, struct event_base *main_base) {
647
585
pthread_mutex_init(&cache_lock, NULL);
648
pthread_mutex_init(&conn_lock, NULL);
649
pthread_mutex_init(&slabs_lock, NULL);
650
586
pthread_mutex_init(&stats_lock, NULL);
652
588
pthread_mutex_init(&init_lock, NULL);