October 6, 2016

A Kyu tutorial - blink an LED using a continuation

This behaves exactly the same as the first example, but does things in a different way. It uses a Kyu feature known as a continuation. The idea with a continuation is that when a thread blocks, it specifies a function that it should "come alive" in when it gets unblocked. This allows certain optimizations. In particular, no state needs to be saved (the entire register context can be abandoned when the thread blocks) and when the thread gets unblocked, it is exactly the same as the thread being started up for the first time.
#include <kyu.h>
#include <thread.h>

static struct thread *user_thread;
static int count;

static void
ticker ( void )
{
	++count;
	if ( count > 49 ) {
	    thr_unblock ( user_thread );
	    count = 0;
	}
}

static int led = 0;

static void
blinker ( int xx )
{
	gpio_led_set ( led );
	led = (led+1) % 2;
	thr_block_q ( WAIT );
}

void
user_init ( int xx )
{

	count = 0;
	user_thread = thr_self ();
	gpio_led_init ();
	timer_hookup ( ticker );

	thr_block_c ( WAIT, blinker, 0 );
}
Doing things this way allows the code to be partitioned into two sections. The code in the user_init() function is setup and initialization. the code in blinker() is the code that gets run as the event handler. The call to thr_block_c() specifies the function that the thread should come alive in when unblocked (and the argument passed to it). Note that the call to thr_block_q that is used to "go back to sleep". It does not need to specify a function to resume in, it just abandons all of its context and waits to be reborn. The "_q" is for "quick".


Have any comments? Questions? Drop me a line!

Kyu / tom@mmto.org