4. The Call Stack
Keeps track of subroutine execution (call + return)
Dynamic, grows up or down depending on machine
architecture
Composed of n-1 stack frames
Frequently includes local data storage, params,
additional return state etc.
Optimized for a single action
Ordered
Usually a single call stack per process, except ...
09/12/09 4
6. Context Switches
A stack per Thread / Fiber
Context specific data
Transient long running contexts are memory
hungry
Guard against transient threads with a pre-
initialized Thread pool
Threaded full stack Web Apps == expensive
context switches
clean_backtrace ?
09/12/09 6
9. Ruby Threads
Scheduled with a timer (SIGVTALRM) every 10ms
Each thread is allowed a 10ms time slice
Not the most efficient scheduler
Coupled with select with IO multiplexing for
portability
Can wait for : fd, select, a PID, sleep state, a join
MRI 1.8: Green Threads, cheap to spawn + switch
MRI 1.9: Native OS threads, GIL, more expensive
to spawn
JRuby: Ruby thread == Java thread
09/12/09 9
12. Fibers
A resumable execution state
Computes a partial result – generator
Yields back to it's caller
Caller resumes
Facilities for data exchange
Initial 4k stack size and very fast context switches
MRI 1.9 and JRuby only
Cooperative scheduling for IO
09/12/09 12
15. Reactor Pattern
Main loop with a tick quantum ( 10 to 100ms )
Operations register themselves with the reactor
Process forked, fd readable, cmd finished, timer
fired, IO timeout etc.
Callbacks and errbacks
Reactor notified by lower level subsystems : select,
epoll, kqueue etc.
Twisted (Python), EventMachine (Ruby, c++, Java)
09/12/09 15
17. Reactor and Threads
Operations fire on the reactor thread
Enumerated and invoked FIFO
Blocking operations block the reactor
Defer: schedule an operation on a background
thread
Schedule: push a deferred context back to the
reactor thread
09/12/09 17
22. Syscalls and the Kernel
Function calls into the OS: read,write,fork,sbrk etc.
User vs Kernel space context switch, much more
expensive than function calls within a process
Usually implies data transfer between User and
Kernel
Important to reduce syscalls for high throughput
environments
Some lift workloads ...
sendfile: request a file to be served directly from
the kernel without User space overhead
09/12/09 22
24. POSIX Realtime (AIO)
Introduced in Linux Kernel 2.6.x
Floating spec for a number of years, currently
defined in POSIX.1b
Implementation resembles browser compat
Fallback to blocking operations in most
implementations
Powers popular reverse proxies like Squid, Nginx,
Varnish etc.
09/12/09 24
28. AIO Control Blocks
File descriptor with proper r/w mode set
Buffer region for read / write
Type of operation: read / write
Priority: higher priority == faster execution
Offset: Position to read from / write to
Bytes: Amount of data to transfer
Callback mechanism: no op, thread or signal
Best wrapped in a custom struct for embedding
domain logic specific to the use cases
09/12/09 28
31. AIO Operations on a single fd
aio_read: sync / async read
aio_write: sync / async write
aio_error: error state, if any, for an operation
aio_error and EINPROGRESS to simulate a
blocking operation
aio_cancel: cancel a submitted job
aio_suspend: pause an in progress operation
aio_sync: forcefully sync a write op to disk
aio_return: return status from a given operation
Uniform API, single AIO Control Block as arg
09/12/09 31
34. AIO list operations
Previously mentioned API still have a syscall per
call overhead
lio_listio: submit a batch of control blocks with a
single syscall
Modes: blocking, non-blocking and no-op
Array of control blocks, number of operations and
an optional callback as arguments
Callback fires when all operations done
Callbacks from individual control blocks still fire
Useful for app specific correlation
09/12/09 34
39. Revisit Threads and Fibers
Concept from James “raggi” Tucker
Cheap switching of MRI green threads
Lets embrace this …
Stopped threads don't have scheduler overhead
09/12/09 39
42. Fibered IO Interpreter
Thread#sleep and Thread#wakeup for pooled or
transient threads
Stopped threads excluded by the scheduler saves
10ms runtime per stopped thread when IO bound
Model fits very well with existing threaded servers
like Mongrel
No need for an IO reactor – we delegate this to the
OS and syscalls
09/12/09 42
44. Links and References
A few related projects
http://github.com/eventmachine/eventmachine
Event Machine repository
http://github/methodmissing/aio
Work in progress AIO extension for MRI, API in
flux, but usable
http://github/methodmissing/callback
A native MRI callback object
http://github/methodmissing/channel
Fixed sized pub sub channels for MRI
09/12/09 44