Tutorial

## Overview

In this tutorial we will write a stupid example in which we calculate the sum of two numbers and print it.

## Basic version

Let’s write a basic version first. It may look like,

``````#include <stdio.h>

int add(int a, int b) {
return a + b;
}

int main(void) {
printf("The sum of 1 and 2 is %d\n", add(1, 2));
return 0;
}
``````

Ok, now we want to calculate the sum in another process and print it in current process. How can we achieve it?

## Async version

One solution is we do the calculating in another process and then get the result through the channel.

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 `````` ``````#define csp_without_prefix #include #include chan_declare(ss, int, integer); chan_define(ss, int, integer); proc void add(int a, int b, chan_t(integer) *chn) { chan_push(chn, a + b); } int main(void){ chan_t(integer) *chn = chan_new(integer)(0); async(add(1, 2, chn)); int sum; chan_pop(chn, &sum); printf("The sum of 1 and 2 is %d\n", sum); chan_destroy(chn); return 0; }``````

There are many new things. Don’t worry, let’s review it line by line.

In the first line, we defined the macro `csp_without_prefix`. With it we can use the libcsp’s APIs without the prefix `csp_`.

In lines `6~7`, we declared and defined the a single-writer single-reader(that’s what `ss` means) channel consisting of `int` elements. We marked this channel with label `integer` to avoid naming conflicts with other declared channel(e.g. channel declared with `chan_declare(ss, int, num)`).

In lines `9~11`, we defined the calculating function. It has a parameter `chn`, thus we can get the sum through the channel. The keyword `proc` is used to tell the compiler not to inline the function. Libcsp relies on the `noinline`-ed task.

In lines `14`, we created a new channel object. And in line `15` we created and started a new process to run the task `add(1, 2, chn)` by the libcsp API `async`.

In lines `17~19`, the process blocked until it got the result from the channel. Then we printed the result.

In lines `21~22`, we released the channel resource and finally finished.

## Sync version

Ok, the async version solution works fine, congratulations. But wait, can we improve it? Let’s review the async version code again, and we found that,

• We create a new channel object, but we only use it once and then destroy it. The overhead is somewhat heavy.
• The main process relies on the task process. It will block until the task process finishes and thus it shouldn’t be tried to be scheduled by the libcsp scheduler meanwhile .

`libcsp` provides mechanism to solve this, it’s `sync`. Below is the sync version solution.

``````#define csp_without_prefix

#include <stdio.h>
#include <libcsp/csp.h>

proc void add(int a, int b, int *sum) {
*sum = a + b;
}

int main(void){
int sum;
printf("The sum of 1 and 2 is %d\n", sum);
return 0;
}
``````

Compared to the async version, it’s shorter and faster.

## Build

Assume the file is `sum.c`, we build it with following commands,

``````cspcli init
gcc -o sum.o -c sum.c -fplugin=libcsp
cspcli analyze
gcc -o sum sum.o /tmp/libcsp/config.c -lcsp -pthread
``````

Go to Building for more detail about the building.