From 68d3fc10925dc7b748130a41b9c440b76600d112 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 26 Oct 2016 23:42:33 +0300 Subject: [PATCH] Remove the DCB write queue locking Since only one thread can append to the DCBs write queue at a time, there is no need to lock it. --- server/core/dcb.c | 24 ++++--------------- .../MySQL/MySQLBackend/mysql_backend.c | 2 -- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index df6068e6f..6ac136048 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1122,19 +1122,14 @@ dcb_basic_read_SSL(DCB *dcb, int *nsingleread) *nsingleread = -1; return NULL; } - spinlock_acquire(&dcb->writeqlock); + /* If we were in a retry situation, need to clear flag and attempt write */ if (dcb->ssl_read_want_write || dcb->ssl_read_want_read) { dcb->ssl_read_want_write = false; dcb->ssl_read_want_read = false; - spinlock_release(&dcb->writeqlock); dcb_drain_writeq(dcb); } - else - { - spinlock_release(&dcb->writeqlock); - } break; case SSL_ERROR_ZERO_RETURN: @@ -1153,10 +1148,8 @@ dcb_basic_read_SSL(DCB *dcb, int *nsingleread) pthread_self(), __func__ ); - spinlock_acquire(&dcb->writeqlock); dcb->ssl_read_want_write = false; dcb->ssl_read_want_read = true; - spinlock_release(&dcb->writeqlock); *nsingleread = 0; break; @@ -1166,10 +1159,8 @@ dcb_basic_read_SSL(DCB *dcb, int *nsingleread) pthread_self(), __func__ ); - spinlock_acquire(&dcb->writeqlock); dcb->ssl_read_want_write = true; dcb->ssl_read_want_read = false; - spinlock_release(&dcb->writeqlock); *nsingleread = 0; break; @@ -1253,7 +1244,6 @@ dcb_write(DCB *dcb, GWBUF *queue) return 0; } - spinlock_acquire(&dcb->writeqlock); empty_queue = (dcb->writeq == NULL); /* * Add our data to the write queue. If the queue already had data, @@ -1261,10 +1251,10 @@ dcb_write(DCB *dcb, GWBUF *queue) * If it did not already have data, we call the drain write queue * function immediately to attempt to write the data. */ - atomic_add(&dcb->writeqlen, gwbuf_length(queue)); + dcb->writeqlen += gwbuf_length(queue); dcb->writeq = gwbuf_append(dcb->writeq, queue); - spinlock_release(&dcb->writeqlock); dcb->stats.n_buffered++; + MXS_DEBUG("%lu [dcb_write] Append to writequeue. %d writes " "buffered for dcb %p in state %s fd %d", pthread_self(), @@ -1494,7 +1484,6 @@ dcb_drain_writeq(DCB *dcb) */ if (stop_writing) { - spinlock_acquire(&dcb->writeqlock); dcb->writeq = gwbuf_append(local_writeq, dcb->writeq); if (dcb->drain_called_while_busy) @@ -1502,13 +1491,11 @@ dcb_drain_writeq(DCB *dcb) local_writeq = dcb->writeq; dcb->writeq = NULL; dcb->drain_called_while_busy = false; - spinlock_release(&dcb->writeqlock); continue; } else { dcb->draining_flag = false; - spinlock_release(&dcb->writeqlock); goto wrap_up; } } @@ -1532,7 +1519,7 @@ wrap_up: */ if (total_written) { - atomic_add(&dcb->writeqlen, -total_written); + dcb->writeqlen -= total_written; /* Check if the draining has taken us from above water to below water */ if (above_water && dcb->writeqlen < dcb->low_water) @@ -1566,7 +1553,6 @@ static GWBUF * dcb_grab_writeq(DCB *dcb, bool first_time) { GWBUF *local_writeq = NULL; - spinlock_acquire(&dcb->writeqlock); if (first_time && dcb->ssl_read_want_write) { @@ -1583,7 +1569,7 @@ dcb_grab_writeq(DCB *dcb, bool first_time) dcb->draining_flag = local_writeq ? true : false; dcb->writeq = NULL; } - spinlock_release(&dcb->writeqlock); + return local_writeq; } diff --git a/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c b/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c index 67b602cdc..ec4a3c204 100644 --- a/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c +++ b/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c @@ -884,13 +884,11 @@ static int gw_write_backend_event(DCB *dcb) uint8_t* data = NULL; bool com_quit = false; - spinlock_acquire(&dcb->writeqlock); if (dcb->writeq) { data = (uint8_t *) GWBUF_DATA(dcb->writeq); com_quit = MYSQL_IS_COM_QUIT(data); } - spinlock_release(&dcb->writeqlock); if (data) {