Add debugging stats to the INFO command
Former-commit-id: ac80a5c6a6676f45ac7d460a9cfb02fef8b48d78
This commit is contained in:
parent
6cdb35815d
commit
fbe1a6c52a
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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. */
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user