Add debugging stats to the INFO command

Former-commit-id: ac80a5c6a6676f45ac7d460a9cfb02fef8b48d78
This commit is contained in:
John Sully 2019-03-19 22:04:33 -04:00
parent 6cdb35815d
commit fbe1a6c52a
6 changed files with 32 additions and 2 deletions

View File

@ -43,6 +43,13 @@
****************************************************/ ****************************************************/
static_assert(sizeof(pid_t) <= sizeof(fastlock::m_pidOwner), "fastlock::m_pidOwner not large enough"); static_assert(sizeof(pid_t) <= sizeof(fastlock::m_pidOwner), "fastlock::m_pidOwner not large enough");
uint64_t g_longwaits = 0;
uint64_t fastlock_getlongwaitcount()
{
return g_longwaits;
}
extern "C" pid_t gettid() extern "C" pid_t gettid()
{ {
@ -75,7 +82,10 @@ extern "C" void fastlock_lock(struct fastlock *lock)
while (__atomic_load_2(&lock->m_ticket.m_active, __ATOMIC_ACQUIRE) != myticket) while (__atomic_load_2(&lock->m_ticket.m_active, __ATOMIC_ACQUIRE) != myticket)
{ {
if ((++cloops % 1024*1024) == 0) if ((++cloops % 1024*1024) == 0)
{
sched_yield(); sched_yield();
++g_longwaits;
}
#if defined(__i386__) || defined(__amd64__) #if defined(__i386__) || defined(__amd64__)
__asm__ ("pause"); __asm__ ("pause");
#endif #endif

View File

@ -13,6 +13,8 @@ int fastlock_trylock(struct fastlock *lock);
void fastlock_unlock(struct fastlock *lock); void fastlock_unlock(struct fastlock *lock);
void fastlock_free(struct fastlock *lock); void fastlock_free(struct fastlock *lock);
uint64_t fastlock_getlongwaitcount(); // this is a global value
/* End C API */ /* End C API */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -2,6 +2,7 @@ section .text
extern gettid extern gettid
extern sched_yield extern sched_yield
extern g_longwaits
; This is the first use of assembly in this codebase, a valid question is WHY? ; This is the first use of assembly in this codebase, a valid question is WHY?
; The spinlock we implement here is performance critical, and simply put GCC ; The spinlock we implement here is performance critical, and simply put GCC
@ -49,6 +50,8 @@ ALIGN 16
syscall ; give up our timeslice we'll be here a while syscall ; give up our timeslice we'll be here a while
pop rax pop rax
pop rsi pop rsi
mov rcx, g_longwaits
inc qword [rcx] ; increment our long wait counter
mov rdi, [rsp] ; our struct pointer is on the stack already mov rdi, [rsp] ; our struct pointer is on the stack already
xor ecx, ecx ; Reset our loop counter xor ecx, ecx ; Reset our loop counter
jmp .LLoop ; Get back in the game jmp .LLoop ; Get back in the game

View File

@ -138,6 +138,7 @@ void linkClient(client *c) {
* this way removing the client in unlinkClient() will not require * this way removing the client in unlinkClient() will not require
* a linear scan, but just a constant time operation. */ * a linear scan, but just a constant time operation. */
c->client_list_node = listLast(server.clients); c->client_list_node = listLast(server.clients);
if (c->fd != -1) atomicIncr(server.rgthreadvar[c->iel].cclients, 1);
uint64_t id = htonu64(c->id); uint64_t id = htonu64(c->id);
raxInsert(server.clients_index,(unsigned char*)&id,sizeof(id),c,NULL); raxInsert(server.clients_index,(unsigned char*)&id,sizeof(id),c,NULL);
} }
@ -1208,6 +1209,8 @@ void unlinkClient(client *c) {
aeDeleteFileEvent(server.rgthreadvar[c->iel].el,c->fd,AE_WRITABLE); aeDeleteFileEvent(server.rgthreadvar[c->iel].el,c->fd,AE_WRITABLE);
close(c->fd); close(c->fd);
c->fd = -1; c->fd = -1;
atomicDecr(server.rgthreadvar[c->iel].cclients, 1);
} }
/* Remove from the list of pending writes if needed. */ /* Remove from the list of pending writes if needed. */

View File

@ -2815,6 +2815,7 @@ static void initServerThread(struct redisServerThreadVars *pvar, int fMain)
pvar->unblocked_clients = listCreate(); pvar->unblocked_clients = listCreate();
pvar->clients_pending_asyncwrite = listCreate(); pvar->clients_pending_asyncwrite = listCreate();
pvar->ipfd_count = 0; pvar->ipfd_count = 0;
pvar->cclients = 0;
pvar->el = aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR); pvar->el = aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR);
if (pvar->el == NULL) { if (pvar->el == NULL) {
serverLog(LL_WARNING, serverLog(LL_WARNING,
@ -3997,6 +3998,12 @@ extern "C" sds genRedisInfoString(const char *section) {
listLength(server.clients)-listLength(server.slaves), listLength(server.clients)-listLength(server.slaves),
maxin, maxout, maxin, maxout,
server.blocked_clients); server.blocked_clients);
for (int ithread = 0; ithread < server.cthreads; ++ithread)
{
info = sdscatprintf(info,
"thread_%d_clients:%d\r\n",
ithread, server.rgthreadvar[ithread].cclients);
}
} }
/* Memory */ /* Memory */
@ -4401,11 +4408,15 @@ extern "C" sds genRedisInfoString(const char *section) {
"used_cpu_sys:%ld.%06ld\r\n" "used_cpu_sys:%ld.%06ld\r\n"
"used_cpu_user:%ld.%06ld\r\n" "used_cpu_user:%ld.%06ld\r\n"
"used_cpu_sys_children:%ld.%06ld\r\n" "used_cpu_sys_children:%ld.%06ld\r\n"
"used_cpu_user_children:%ld.%06ld\r\n", "used_cpu_user_children:%ld.%06ld\r\n"
"server_threads:%d\r\n"
"long_lock_waits:%" PRIu64 "\r\n",
(long)self_ru.ru_stime.tv_sec, (long)self_ru.ru_stime.tv_usec, (long)self_ru.ru_stime.tv_sec, (long)self_ru.ru_stime.tv_usec,
(long)self_ru.ru_utime.tv_sec, (long)self_ru.ru_utime.tv_usec, (long)self_ru.ru_utime.tv_sec, (long)self_ru.ru_utime.tv_usec,
(long)c_ru.ru_stime.tv_sec, (long)c_ru.ru_stime.tv_usec, (long)c_ru.ru_stime.tv_sec, (long)c_ru.ru_stime.tv_usec,
(long)c_ru.ru_utime.tv_sec, (long)c_ru.ru_utime.tv_usec); (long)c_ru.ru_utime.tv_sec, (long)c_ru.ru_utime.tv_usec,
server.cthreads,
fastlock_getlongwaitcount());
} }
/* Command statistics */ /* Command statistics */

View File

@ -1053,6 +1053,7 @@ struct redisServerThreadVars {
list *clients_pending_write; /* There is to write or install handler. */ list *clients_pending_write; /* There is to write or install handler. */
list *unblocked_clients; /* list of clients to unblock before next loop NOT THREADSAFE */ list *unblocked_clients; /* list of clients to unblock before next loop NOT THREADSAFE */
list *clients_pending_asyncwrite; list *clients_pending_asyncwrite;
int cclients;
struct fastlock lockPendingWrite; struct fastlock lockPendingWrite;
}; };