Event Loop and Continuation Thread Affinity Fei Deng

  • Slides: 20
Download presentation
Event Loop and Continuation Thread Affinity Fei Deng 1

Event Loop and Continuation Thread Affinity Fei Deng 1

Introduction • Event loop changes. • Event loop metrics. • Accept thread initialization. •

Introduction • Event loop changes. • Event loop metrics. • Accept thread initialization. • Continuation thread affinity. • New APIs. • Example Usage. 2

Event Loop Changes • Removed condition variable for “fast” signal tracking. • Split “execute_regular”

Event Loop Changes • Removed condition variable for “fast” signal tracking. • Split “execute_regular” function. • Changed thread initialization logic. • Don’t re-purpose main thread as event thread. 3

Event Loop Stalling • Event loop must have a stall point to wait for

Event Loop Stalling • Event loop must have a stall point to wait for external activity. • Two stall points originally. • Condition variable for external event queue. • I/O. • Updated to have a single stall point, I/O. • tail_cb mechanism replaces signal_hook. 4

Event Loop Metrics • • proxy. process. eventloop. count: # of event loops executed.

Event Loop Metrics • • proxy. process. eventloop. count: # of event loops executed. proxy. process. eventloop. events: # of events. proxy. process. eventloop. events. min: min # of events dispatched in a loop. proxy. process. eventloop. events. max: max # of events dispatched in a loop. • proxy. process. eventloop. wait: # of I/O waits period. • proxy. process. eventloop. time. min: Shortest time spent in loop. • proxy. process. eventloop. time. max: Longest time spent in loop. • Three time spans - 10 s, 1000 s 5

Event Loop Metrics Sample Output 6

Event Loop Metrics Sample Output 6

Race Condition with Accept Threads traffic_server: received signal 11 (Segmentation fault) traffic_server - STACK

Race Condition with Accept Threads traffic_server: received signal 11 (Segmentation fault) traffic_server - STACK TRACE: traffic_server(_Z 19 crash_logger_invokei. P 9 siginfo_t. Pv+0 xd 4)[0 x 56401 d 70 d 8 c 0] /lib/x 86_64 -linux -gnu/libpthread. so. 0(+0 x 13150)[0 x 7 f 409 ad 7 d 150] traffic_server(_ZN 7 Event. IO 5 start. EP 14 Poll. Descriptori. P 12 Continuationi+0 x 7 d)[0 x 56401 d 904 e 37] traffic_server(_ZN 7 Event. IO 5 start. EP 14 Poll. Descriptor. P 9 Net. Accepti+0 x 43)[0 x 56401 d 977 a 13] traffic_server(_ZN 9 Net. Accept 22 init_accept_per_thread. Ev+0 x 16 d)[0 x 56401 d 975 d 67] traffic_server(_ZN 16 Unix. Net. Processor 15 accept_internal. EP 12 Continuationi. RKN 12 Net. Processor 13 Acc ept. Options. E+0 x 74 b)[0 x 56401 d 978 cb 1] traffic_server(_ZN 12 Net. Processor 11 main_accept. EP 12 Continuationi. RKNS_13 Accept. Options. E+0 xe 5)[0 x 56401 d 97854 f] traffic_server(_Z 21 start_Http. Proxy. Serverv+0 x 112)[0 x 56401 d 7 dc 853] traffic_server(main+0 x 137 b)[0 x 56401 d 7390 bf] /lib/x 86_64 -linuxgnu/libc. so. 6(__libc_start_main+0 xf 1)[0 x 7 f 4099 eb 41 c 1] traffic_server(_start+0 x 2 a)[0 x 56401 d 6 f 61 ca] • Happens when proxy. config. accept_threads was set to 0. 7

Race Condition with Accept Threads • Added _started counter in Thread. Group. Descriptor. •

Race Condition with Accept Threads • Added _started counter in Thread. Group. Descriptor. • Use condition variable to check whether all ET_NET threads have finished initialization. 8

Race Condition with Accept Threads • Use schedule_spawn to setup checking mechanism. • Use

Race Condition with Accept Threads • Use schedule_spawn to setup checking mechanism. • Use condition variable to check whether ET_NET threads finished initialization. 9

New API Proposal • Thread Affinity • TSReturn. Code TSCont. Thread. Affinity. Set(TSCont contp,

New API Proposal • Thread Affinity • TSReturn. Code TSCont. Thread. Affinity. Set(TSCont contp, TSEvent. Thread ethread) • TSEvent. Thread TSCont. Thread. Affinity. Get(TSCont contp) • void TSCont. Thread. Affinity. Clear(TSCont contp) • TSEvent. Thread. Self(void) • Event Scheduling • TSAction TSCont. Schedule. On(TSCont contp, TSHRTime timeout, TSEvent. Thread ethread) • TSAction TSCont. Schedule. On. Every(TSCont contp, TSHRTime every, TSEvent. Thread ethread) • Modified behavior for TSCont. Schedule and TSCont. Schedule. Every. 10

Thread Affinity • TSReturn. Code TSCont. Thread. Affinity. Set(TSCont contp, TSEvent. Thread ethread) •

Thread Affinity • TSReturn. Code TSCont. Thread. Affinity. Set(TSCont contp, TSEvent. Thread ethread) • Set the thread affinity of continuation TSCont contp to TSEvent. Thread ethread. • TSEvent. Thread TSCont. Thread. Affinity. Get(TSCont contp) • Get the thread affinity information of continuation TSCont contp. • void TSCont. Thread. Affinity. Clear(TSCont contp) • Clear the thread affinity of continuation TSCont contp. • TSEvent. Thread. Self(void) • Get the current event thread. 11

Event Scheduling • TSAction TSCont. Schedule. On(TSCont contp, TSHRTime timeout, TSEvent. Thread ethread) •

Event Scheduling • TSAction TSCont. Schedule. On(TSCont contp, TSHRTime timeout, TSEvent. Thread ethread) • Schedules contp to run approximately timeout milliseconds in the future. The delay will be at least timeout but possibly more. Resolutions finer than roughly 5 milliseconds will not be effective. contp is required to have a mutex, which is provided to TSCont. Create. • The return value can be used to cancel the scheduled event via TSAction. Cancel. This is effective until the continuation contp is being dispatched. However, if it is scheduled on another thread other than the current one, it can be problematic to be correctly timed. The return value can be checked with TSAction. Done to see if the continuation ran before the return, which is possible if timeout is 0. • The continuation is scheduled on the thread as indicated by ethread. 12

Event Scheduling • TSAction TSCont. Schedule. On. Every(TSCont contp, TSHRTime every, TSEvent. Thread ethread)

Event Scheduling • TSAction TSCont. Schedule. On. Every(TSCont contp, TSHRTime every, TSEvent. Thread ethread) • Schedules contp to run approximately every milliseconds. The interval will be at least every but possibly more. Resolutions finer than roughly 5 milliseconds will not be effective. contp is required to have a mutex, which is provided to TSCont. Create. • The return value can be used to cancel the scheduled event via TSAction. Cancel. This is effective until the continuation contp is being dispatched. However, if it is scheduled on another thread other than the current one, it can be problematic to be correctly timed. The return value can be checked with TSAction. Done to see if the continuation ran before the return, which is possible if every is 0. • The continuation is scheduled on the thread as indicated by ethread. 13

Event Scheduling • Modified behavior for TSAction TSCont. Schedule(TSCont contp, TSHRTime timeout, TSThread. Pool

Event Scheduling • Modified behavior for TSAction TSCont. Schedule(TSCont contp, TSHRTime timeout, TSThread. Pool tp) TSAction TSCont. Schedule. Every(TSCont contp, TSHRTime every, TSThread. Pool tp) • If thread affinity was not set for continuation contp, the behavior stays unchanged. • If thread affinity was set for continuation contp, and the thread type is the same as tp, the continuation will be scheduled on the thread specified by thread affinity. 14

Event Scheduling 15

Event Scheduling 15

Example Usage TSHRTime timeout = 5; TSCont contp = TSCont. Create(stubby_stub, nullptr); . .

Example Usage TSHRTime timeout = 5; TSCont contp = TSCont. Create(stubby_stub, nullptr); . . . TSCont. Schedule(contp, timeout, TS_THREAD_POOL_DEFAULT); 16

Example Usage 1 TSHRTime timeout = 5; TSCont contp = TSCont. Create(stubby_stub, nullptr); TSEvent.

Example Usage 1 TSHRTime timeout = 5; TSCont contp = TSCont. Create(stubby_stub, nullptr); TSEvent. Thread ethread = TSEvent. Thread. Self(); . . . TSCont. Schedule. On(contp, timeout, ethread); 17

Example Usage 2 TSHRTime timeout = 5; TSCont contp = TSCont. Create(stubby_stub, nullptr); TSEvent.

Example Usage 2 TSHRTime timeout = 5; TSCont contp = TSCont. Create(stubby_stub, nullptr); TSEvent. Thread ethread = TSEvent. Thread. Self(void); if (TSCont. Thread. Affinity. Get(contp) == nullptr) { TSCont. Thread. Affinity. Set(contp, ethread); }. . . TSCont. Schedule(contp, timeout, TS_THREAD_POOL_DEFAULT); 18

Example Usage 3 TSHRTime timeout = 5; TSCont contp = TSCont. Create(stubby_stub, nullptr); .

Example Usage 3 TSHRTime timeout = 5; TSCont contp = TSCont. Create(stubby_stub, nullptr); . . . TSCont. Thread. Affinity. Clear(contp); TSCont. Schedule(contp, timeout, TS_THREAD_POOL_DEFAULT); 19

Discussion • Do we want to have thread affinity to be set to the

Discussion • Do we want to have thread affinity to be set to the current thread by default? • … 20