stack switching for fun and profit

28
Stack switching for fun & profit Saúl Ibarra Corretgé - @saghul FOSDEM 2014

Upload: saul-ibarra-corretge

Post on 19-May-2015

531 views

Category:

Technology


0 download

DESCRIPTION

Slides from the talk I gave at FOSDEM 2014 on how Greenlet works and how I built python-fibers.

TRANSCRIPT

Page 1: Stack switching for fun and profit

Stack switchingfor fun & profitSaúl Ibarra Corretgé - @saghul

FOSDEM 2014

Page 2: Stack switching for fun and profit

Hi!

@saghul

FOSDEM

Open Source

Page 3: Stack switching for fun and profit

import open_source

github.com/saghul

Page 4: Stack switching for fun and profit

Some background

Who knows what greenlet is?

Who has used it (standalone)?

Who understands how it works?

Page 5: Stack switching for fun and profit

Greenlet

Micro-threads with no implicit scheduling

Lightweight

Only one can run at a time

Spin-off Stackless

Page 6: Stack switching for fun and profit

Greenlet APIgreenlet(func, parent=None): creates a greenlet to run ‘func’

greenlet.switch(*args, **kw): switches execution to the target greenlet, the first timefunc(*args, **kw) will be executed

greenlet.throw([typ, [val, [tb]]]): switches execution to the target greenlet and raises the specified exception (GreenletExit by default)

Page 7: Stack switching for fun and profit

Exampleimport greenlet

main = greenlet.getcurrent()

def foo(n): main.switch(n)

def bar(n): foo(n) return 'hello'

g1 = greenlet.greenlet(bar)print g1.switch(42) # 42print g1.switch() # 'hello'print g1.dead # True

Page 8: Stack switching for fun and profit

How does it work?‘Stack switching’

Non portable asm code

Copy stack slices on the heap

State is saved and restored when switching

CPU registers

Current Python frame, recursion depth and exception state

Page 9: Stack switching for fun and profit
Page 10: Stack switching for fun and profit
Page 11: Stack switching for fun and profit
Page 12: Stack switching for fun and profit

How does it work? (II)

Organized in a tree structure

Each greenlet has a ‘parent’, except main

Execution order isn’t always obvious

Page 13: Stack switching for fun and profit

Example (II)import greenlet

main = greenlet.getcurrent()

def foo_async(cb): # Will call cb(result, error) eventually pass

def foo_sync(): current = greenlet.getcurrent() def cb(result, error): if error is not None: current.throw(Exception(error)) else: current.switch(result) foo_async(cb) main.switch()

Page 14: Stack switching for fun and profit

Stackless Python

Fork of CPython, first release in 1999

Provides tasklets and channels

Builtin scheduler

Different approaches to switching

Page 15: Stack switching for fun and profit

Stackless Python (II)Different ways of switching: soft and hard

Soft switching

“Move some pointers around”

Hard switching

Platform dependent assembly code

When soft-switching is not possible

Page 16: Stack switching for fun and profit

Enter PyPy

New shiny and fast implementation of Python

Vast amount of fairy-dust covered unicorns included

Includes implementations of both greenlet and Stackless

Implemented on top of “continulet” objects

Page 17: Stack switching for fun and profit

import _continuation

Continulets are one-shot continuations

Switching code is a standalone C library: stacklet

rpython/translator/c/src/stacklet/

Page 18: Stack switching for fun and profit

Continulet APIcontinulet(func, *args, **kw): create a continulet object which will call fun(cont, *args, **kw)

continulet.switch(value=None, to=None): start the continulet or activate the previously suspended one. If to is specified a ‘double switch’ is performed

continulet.throw(type, value=None, tb=None, to=None): similar to switch, but raise the given exception after the switch is done

Page 19: Stack switching for fun and profit

Stacklet

Tiny library implementing one-shot continuations for C

Single C file (~400 lines) + per-platform asm

Supports x86, x86_64 and ARM

Nice and simple API

Page 20: Stack switching for fun and profit

Stacklet API

stacklet_newthread(): creates a new thread handle

stacklet_new(thread_handle, run_func, run_arg): calls run(arg) in a new stacklet, starts immediately

stacklet_switch(target): switches execution to target stacklet

Page 21: Stack switching for fun and profit

Example#include <assert.h>#include "stacklet.h"

static stacklet_thread_handle thrd;

stacklet_handle empty_callback(stacklet_handle h, void *arg){ assert(arg == (void *)123); return h;}

void test_new(void){ stacklet_handle h = stacklet_new(thrd, empty_callback, (void *)123); assert(h == EMPTY_STACKLET_HANDLE);}

int main(int argc, char **argv){ thrd = stacklet_newthread(); test_new(); stacklet_deletethread(thrd); return 0;}

Page 22: Stack switching for fun and profit

import fibersMicro-threadling library API inspired by Python threads and greenlet

Uses stacklet underneath

Works on CPython and PyPy

On PyPy it uses continulets

github.com/saghul/python-fibers

Or pip install fibers

Page 23: Stack switching for fun and profit

fibers APIFiber(target=None, args=(), kwargs={}, parent=None): creates a new fiber which will run “target(*args, **kwargs)”

Fiber.switch(value=None): switch execution to the target fiber, value can only be passed after the fiber is running

Fiber.throw(typ, [value, [tb]]): switch execution to the target fiber and raise the specified exception

Page 24: Stack switching for fun and profit

Motivation

Couldn’t build the API I wanted on top of greenlet

Early binding

More exceptions in expected places

No magic exceptions (GreenletExit)

No switching on GC

Page 25: Stack switching for fun and profit

Exampleimport fibers

main = fibers.current()

def foo(n): main.switch(n)

def bar(n): foo(n) return 'hello'

g1 = fibers.Fiber(target=bar, args=(42,))print g1.switch() # 42print g1.switch() # 'hello'print g1.is_alive() # False

Page 26: Stack switching for fun and profit

Projects using fibers

github.com/saghul/evergreen

github.com/geertj/gruvi

github.com/benoitc/offset

Should I add yours here?

Page 27: Stack switching for fun and profit

The Stacklet Sandwich (TM)

stacklet

continulet

greenlet / stackless / fibers

Page 28: Stack switching for fun and profit

Questions?

bettercallsaghul.com@saghul