The thread state is now a property of the worker

A worker's state is not statistics, but transient information.
This commit is contained in:
Johan Wikman
2017-04-18 12:56:23 +03:00
parent effa2f5674
commit 722d6da46f
4 changed files with 49 additions and 59 deletions

View File

@ -52,19 +52,6 @@ typedef struct mxs_poll_data
} thread; } thread;
} MXS_POLL_DATA; } MXS_POLL_DATA;
// TODO: Temporarily moved here.
/**
* Internal MaxScale thread states
*/
typedef enum
{
THREAD_STOPPED,
THREAD_IDLE,
THREAD_POLLING,
THREAD_PROCESSING,
THREAD_ZPROCESSING
} THREAD_STATE;
// TODO: Temporarily moved here. // TODO: Temporarily moved here.
/** /**
* The number of buckets used to gather statistics about how many * The number of buckets used to gather statistics about how many
@ -80,7 +67,6 @@ typedef enum
// TODO: Temporarily moved here. // TODO: Temporarily moved here.
typedef struct typedef struct
{ {
THREAD_STATE thread_state; /*< The thread state. */
int64_t n_read; /*< Number of read events */ int64_t n_read; /*< Number of read events */
int64_t n_write; /*< Number of write events */ int64_t n_write; /*< Number of write events */
int64_t n_error; /*< Number of error events */ int64_t n_error; /*< Number of error events */

View File

@ -27,6 +27,15 @@ class Worker : public MXS_WORKER
Worker& operator = (const Worker&); Worker& operator = (const Worker&);
public: public:
enum state_t
{
STOPPED,
IDLE,
POLLING,
PROCESSING,
ZPROCESSING
};
/** /**
* Initialize the worker mechanism. * Initialize the worker mechanism.
* *
@ -54,6 +63,18 @@ public:
return m_id; return m_id;
} }
/**
* Returns the state of the worker.
*
* @return The current state.
*
* @attentions The state might have changed the moment after the function returns.
*/
state_t state() const
{
return m_state;
}
/** /**
* Add a file descriptor to the epoll instance of the worker. * Add a file descriptor to the epoll instance of the worker.
* *
@ -227,15 +248,11 @@ private:
static void thread_main(void* arg); static void thread_main(void* arg);
static void poll_waitevents(int epoll_fd, void poll_waitevents(POLL_STATS* poll_stats, QUEUE_STATS* queue_stats);
int thread_id,
POLL_STATS* poll_stats,
QUEUE_STATS* queue_stats,
bool (*should_shutdown)(void* data),
void* data);
private: private:
int m_id; /*< The id of the worker. */ int m_id; /*< The id of the worker. */
state_t m_state; /*< The state of the worker */
int m_epoll_fd; /*< The epoll file descriptor. */ int m_epoll_fd; /*< The epoll file descriptor. */
POLL_STATS* m_pPoll_stats; /*< Statistics for worker. */ POLL_STATS* m_pPoll_stats; /*< Statistics for worker. */
QUEUE_STATS* m_pQueue_stats; /*< Statistics for queue. */ QUEUE_STATS* m_pQueue_stats; /*< Statistics for queue. */

View File

@ -354,23 +354,26 @@ dShowThreads(DCB *dcb)
dcb_printf(dcb, "----+------------\n"); dcb_printf(dcb, "----+------------\n");
for (int i = 0; i < n_threads; i++) for (int i = 0; i < n_threads; i++)
{ {
Worker* worker = Worker::get(i);
ss_dassert(worker);
const char *state = "Unknown"; const char *state = "Unknown";
switch (pollStats[i].thread_state) switch (worker->state())
{ {
case THREAD_STOPPED: case Worker::STOPPED:
state = "Stopped"; state = "Stopped";
break; break;
case THREAD_IDLE: case Worker::IDLE:
state = "Idle"; state = "Idle";
break; break;
case THREAD_POLLING: case Worker::POLLING:
state = "Polling"; state = "Polling";
break; break;
case THREAD_PROCESSING: case Worker::PROCESSING:
state = "Processing"; state = "Processing";
break; break;
case THREAD_ZPROCESSING: case Worker::ZPROCESSING:
state = "Collecting"; state = "Collecting";
break; break;

View File

@ -141,6 +141,7 @@ Worker::Worker(int id,
POLL_STATS* pPoll_stats, POLL_STATS* pPoll_stats,
QUEUE_STATS* pQueue_stats) QUEUE_STATS* pQueue_stats)
: m_id(id) : m_id(id)
, m_state(STOPPED)
, m_epoll_fd(epoll_fd) , m_epoll_fd(epoll_fd)
, m_pPoll_stats(pPoll_stats) , m_pPoll_stats(pPoll_stats)
, m_pQueue_stats(pQueue_stats) , m_pQueue_stats(pQueue_stats)
@ -173,11 +174,6 @@ void Worker::init()
exit(-1); exit(-1);
} }
for (int i = 0; i < this_unit.n_workers; i++)
{
pollStats[i].thread_state = THREAD_STOPPED;
}
queueStats = (QUEUE_STATS*)MXS_CALLOC(this_unit.n_workers, sizeof(QUEUE_STATS)); queueStats = (QUEUE_STATS*)MXS_CALLOC(this_unit.n_workers, sizeof(QUEUE_STATS));
if (!queueStats) if (!queueStats)
{ {
@ -361,9 +357,7 @@ bool should_shutdown(void* pData)
void Worker::run() void Worker::run()
{ {
this_thread.current_worker_id = m_id; this_thread.current_worker_id = m_id;
poll_waitevents(m_epoll_fd, m_id, poll_waitevents(m_pPoll_stats, m_pQueue_stats);
m_pPoll_stats, m_pQueue_stats,
::should_shutdown, this);
this_thread.current_worker_id = WORKER_ABSENT_ID; this_thread.current_worker_id = WORKER_ABSENT_ID;
MXS_NOTICE("Worker %d has shut down.", m_id); MXS_NOTICE("Worker %d has shut down.", m_id);
@ -545,34 +539,23 @@ void Worker::thread_main(void* pArg)
/** /**
* The main polling loop * The main polling loop
* *
* @param epoll_fd The epoll descriptor.
* @param thread_id The id of the calling thread.
* @param poll_stats The polling stats of the calling thread. * @param poll_stats The polling stats of the calling thread.
* @param queue_stats The queue stats of the calling thread. * @param queue_stats The queue stats of the calling thread.
* @param should_shutdown Pointer to function returning true if the polling should
* be terminated.
* @param data Data provided to the @c should_shutdown function.
*/ */
//static void Worker::poll_waitevents(POLL_STATS* poll_stats, QUEUE_STATS* queue_stats)
void Worker::poll_waitevents(int epoll_fd,
int thread_id,
POLL_STATS* poll_stats,
QUEUE_STATS* queue_stats,
bool (*should_shutdown)(void* data),
void* data)
{ {
struct epoll_event events[MAX_EVENTS]; struct epoll_event events[MAX_EVENTS];
int i, nfds, timeout_bias = 1; int i, nfds, timeout_bias = 1;
int poll_spins = 0; int poll_spins = 0;
poll_stats->thread_state = THREAD_IDLE; m_state = IDLE;
while (!should_shutdown(data)) while (!should_shutdown())
{ {
poll_stats->thread_state = THREAD_POLLING; m_state = POLLING;
atomic_add_int64(&poll_stats->n_polls, 1); atomic_add_int64(&poll_stats->n_polls, 1);
if ((nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, 0)) == -1) if ((nfds = epoll_wait(m_epoll_fd, events, MAX_EVENTS, 0)) == -1)
{ {
int eno = errno; int eno = errno;
errno = 0; errno = 0;
@ -597,7 +580,7 @@ void Worker::poll_waitevents(int epoll_fd,
timeout_bias++; timeout_bias++;
} }
atomic_add_int64(&poll_stats->blockingpolls, 1); atomic_add_int64(&poll_stats->blockingpolls, 1);
nfds = epoll_wait(epoll_fd, nfds = epoll_wait(m_epoll_fd,
events, events,
MAX_EVENTS, MAX_EVENTS,
(this_unit.max_poll_sleep * timeout_bias) / 10); (this_unit.max_poll_sleep * timeout_bias) / 10);
@ -626,7 +609,7 @@ void Worker::poll_waitevents(int epoll_fd,
nfds); nfds);
atomic_add_int64(&poll_stats->n_pollev, 1); atomic_add_int64(&poll_stats->n_pollev, 1);
poll_stats->thread_state = THREAD_PROCESSING; m_state = PROCESSING;
poll_stats->n_fds[(nfds < MAXNFDS ? (nfds - 1) : MAXNFDS - 1)]++; poll_stats->n_fds[(nfds < MAXNFDS ? (nfds - 1) : MAXNFDS - 1)]++;
} }
@ -652,7 +635,7 @@ void Worker::poll_waitevents(int epoll_fd,
MXS_POLL_DATA *data = (MXS_POLL_DATA*)events[i].data.ptr; MXS_POLL_DATA *data = (MXS_POLL_DATA*)events[i].data.ptr;
uint32_t actions = data->handler(data, thread_id, events[i].events); uint32_t actions = data->handler(data, m_id, events[i].events);
if (actions & MXS_POLL_ACCEPT) if (actions & MXS_POLL_ACCEPT)
{ {
@ -694,20 +677,21 @@ void Worker::poll_waitevents(int epoll_fd,
queue_stats->maxexectime = MXS_MAX(queue_stats->maxexectime, qtime); queue_stats->maxexectime = MXS_MAX(queue_stats->maxexectime, qtime);
} }
dcb_process_idle_sessions(thread_id); dcb_process_idle_sessions(m_id);
poll_stats->thread_state = THREAD_ZPROCESSING; m_state = ZPROCESSING;
/** Process closed DCBs */ /** Process closed DCBs */
dcb_process_zombies(thread_id); dcb_process_zombies(m_id);
poll_check_message(); poll_check_message();
poll_stats->thread_state = THREAD_IDLE; m_state = IDLE;
} /*< while(1) */ } /*< while(1) */
poll_stats->thread_state = THREAD_STOPPED; m_state = STOPPED;
} }
/** /**
* Calls thread_init on all loaded modules. * Calls thread_init on all loaded modules.
* *