Running multiple Io VM's under OpenMP

Filed under: io openmp 

Io's concurrency is implemented as async cooperative coroutines. This gives great performance, but doesn't take advantage of multiple cores. Luckily the Io VM is threadsafe, so it shouldn't be too hard to write a program that can run multiple VM's, each in its own thread.

I decided to try OpenMP to implement this as it provides a nice way to do this sort of thing.

This example doesn't quite work just yet. It does sometimes, and other times it segfaults. I'm not sure if the problem is my code, Io, or OpenMP at this point (although I'm suspecting OpenMP due to some messages I've seen in forums).

[UPDATE: It turns out it was a static variable introduced into Io's coroutine library. It's fixed in git - thanks Steve!]

In any case, I'm posting it here in the hopes that it might inspire someone or maybe solicit some assistance.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <omp.h>
#include "io/IoState.h"

void usage ( char *program ) {
  fprintf ( stderr, "Usage: %s [-n threads] <script>\n", program );
  exit ( EXIT_FAILURE );
}

void do_io_state ( char *scriptname ) {
#define CMD "doFile(\"%s\")"
  char *cmd;
  IoState *self;

  cmd = (char *) alloca ( strlen ( scriptname ) + strlen ( CMD ) - 1 );
  sprintf ( cmd, CMD, scriptname );

  self = IoState_new ( );
  IoState_init ( self );
  IoState_doCString_ ( self, cmd );
  IoState_free ( self );
}

int main ( int argc, char **argv ) {
  int threadcount = 1;
  char *scriptname = NULL;
  int opt;

  while ( ( opt = getopt ( argc, argv, "n:" ) ) != -1 ) {
    switch ( opt ) {
    case 'n':
       threadcount = atoi ( optarg );
       break;
    default:
      usage ( argv [ 0 ] );
    }
  }

  if ( ! ( scriptname = argv [ optind ] ) )
    usage ( argv [ 0 ] );

  omp_set_num_threads ( threadcount );

#pragma omp parallel
  do_io_state ( scriptname );

  return 0;
}

To compile it, run this:

$ gcc -fopenmp test.c -o test -I/usr/local/include/io -lgomp -liovmall

You'll need to have the Io source headers in /usr/local/include/io (you have to copy them by hand from the source tree).

Then you can run it like so:

$ ./test -n 4 test.io

where test.io has a really useful bit of code such as:

"hello, world" println

You should then get the amazing output:

hello, world
hello, world
hello, world
hello, world

I haven't programmed in C for many years, so don't be too disappointed =)



0 comments Leave a comment