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");
uint64_t g_longwaits = 0;
uint64_t fastlock_getlongwaitcount()
{
return g_longwaits;
}
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)
{
if ((++cloops % 1024*1024) == 0)
{
sched_yield();
++g_longwaits;
}
#if defined(__i386__) || defined(__amd64__)
__asm__ ("pause");
#endif

View File

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

View File

@ -2,6 +2,7 @@ section .text
extern gettid
extern sched_yield
extern g_longwaits
; 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
@ -49,6 +50,8 @@ ALIGN 16
syscall ; give up our timeslice we'll be here a while
pop rax
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
xor ecx, ecx ; Reset our loop counter
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
* a linear scan, but just a constant time operation. */
c->client_list_node = listLast(server.clients);
if (c->fd != -1) atomicIncr(server.rgthreadvar[c->iel].cclients, 1);
uint64_t id = htonu64(c->id);
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);
close(c->fd);
c->fd = -1;
atomicDecr(server.rgthreadvar[c->iel].cclients, 1);
}
/* 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->clients_pending_asyncwrite = listCreate();
pvar->ipfd_count = 0;
pvar->cclients = 0;
pvar->el = aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR);
if (pvar->el == NULL) {
serverLog(LL_WARNING,
@ -3997,6 +3998,12 @@ extern "C" sds genRedisInfoString(const char *section) {
listLength(server.clients)-listLength(server.slaves),
maxin, maxout,
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 */
@ -4401,11 +4408,15 @@ extern "C" sds genRedisInfoString(const char *section) {
"used_cpu_sys:%ld.%06ld\r\n"
"used_cpu_user:%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_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_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 */

View File

@ -1053,6 +1053,7 @@ struct redisServerThreadVars {
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 *clients_pending_asyncwrite;
int cclients;
struct fastlock lockPendingWrite;
};