Preview Mode Links will not work in preview mode

Hi, and welcome.

 

This attempts to be a free-form, (mostly un-cohosted) podcast about tech-oriented hobby-projects. Do not proceed if you're looking for a high-quality production.

On a semi-biweekly basis, Michai and optional cohost talk about software, electronics and mechanical engineering from a hands-on point of view. Most of the time, that means giving excuses for not having done any work at all.

Feb 13, 2019

Finally, the "we" in announcements doesn't just mean the royal we / majestic plural, but there's an actual co-host! Introduction is in the audio contents, so I guess you'll just have to listen. </clickbait>

We talk about first contact with the Rust programming language, coroutines for implementing lightweight tasks/threads, various smaller topics and some upcoming events. 

Links:

Here's a code snippet hopefully illustrating what I called "coroutines" and should probably have been called "protothreads".

Function "print_2nd_word" is a protothread. It can be called repeatedly passing a character each time. Only the 2nd word is printed, one character at a time.

  
void print_2nd_word( char c )
{
CR_BEGIN;

while ( c != ' ' )
CR_YIELD;

CR_YIELD; // skip space

while ( c != ' ' ) {
putchar( c );
CR_YIELD;
}
}

To do this, the function keeps track of where it exited last time it was called, using a number of macros:

      #define CR_BEGIN static void *jmp = &&lbl_crstart; goto *jmp; lbl_crstart: ( void )jmp;

#define CR_YIELD do { jmp = &&GLUE( lbl, __LINE__ ); return; GLUE( lbl, __LINE__ ): ( void )jmp; } while ( 0 )

"CR_BEGIN" is basically setup-code.

"CR_YIELD" is the simplest primitive in this context, and does: exit the protothread function, and resume at this point next time it's called.

More advanced macros - e.g. to repeatedly wait for an event - can be built on top of, or in the same way as "CR_YIELD".

Note that these macros use GCC's "computed gotos" (i.e. take the address of a C label, and jump to that address using "goto"). Here's an implementation of both macros using ANSI C:

      #define CR_BEGIN static int cr_st = 0; switch( cr_st ) { case 0: ;

#define CR_YIELD do { cr_st = __LINE__; return; case __LINE__: ; } while( 0 )

#define CR_END CR_YIELD; }

(In this case, an additional macro "CR_END" is necessary as glue to conform to C syntax/nesting.)

 

Funfact: it's a bit of a PITA to add sourcecode to this page.