SAM Example 3A
From SoOS
Contents |
[edit] Description
This example shows how to execute speculatively and flash back a worker thread (inefficient version).
[edit] Code
#include <stdio.h>
#include <stdlib.h>
#include <sam.h>
#define N 4
#define ARRAY_SIZE 64
struct datast
{
int *A;
};
void * worker_routine(void *args)
{
SAM_t sam_context; /* Declare a SAM context variable */
void *myargs; /* Pointer to where the arguments are stored */
int *myArray; /* Pointer to the Array of the data */
struct datast *data_arg; /* Pointer to the arguments of the function */
int total; /* Store the variable of the calculation */
int *result; /* Pointer to the result (total) of the calculation */
int i;
/* Start the execution of this worker thread */
/* Extract the SAM context and the arguments */
SAM_Execution_start(args, &sam_context, &myargs);
/* Print the SAM worker ID of this worker thread */
printf("SAM worker id: %d\n", (int)SAM_My_workid(sam_context));
/* Extract the arguments of the function */
data_arg = (struct datast *) myargs;
myArray = data_arg->A;
total = 0;
/* Declare the region as read by the worker thread */
SAM_Memory_speculative_read(sam_context, SAM_My_workid(sam_context), myArray);
/* Make some calculations... */
for(i=0; i<ARRAY_SIZE; i++)
{
total += myArray[i];
}
total = total * (int)SAM_My_workid(sam_context);
/* Print the total, but this value might not be valid */
printf("Calculated %d: %d\n", (int)SAM_My_workid(sam_context), total);
/* Finish the execution of this worker trhead */
SAM_Execution_finish(sam_context);
/* Reserve memory for the result and return it */
result = (int *) malloc(sizeof(int));
*result = total;
return result;
}
int main(void)
{
SAM_t sam_context; /* Declare a SAM context variable */
SAM_Workerid_t th[N]; /* For storing the worker threads ID's */
int *result; /* Gets the result of the worker thread */
int *myArray; /* Pointer to the array of the data */
struct datast *data_arg; /* Pointer to the worker threads arguments */
int i;
myArray = (int *) malloc(ARRAY_SIZE *sizeof(int));
data_arg = (struct datast *) malloc(sizeof(struct datast));
/* Set some data into the Array */
for(i=0; i<ARRAY_SIZE; i++)
{
myArray[i] = i + 1000;
}
/* Initialize the SAM context */
SAM_Init(&sam_context);
/* Setup the arguments we are going to send to the worker threads */
data_arg->A = myArray;
/* Register a region and protect it */
SAM_Memory_region_register(sam_context, myArray, ARRAY_SIZE * sizeof(int));
SAM_Memory_region_protect(sam_context, myArray);
for(i=0;i<N;i++)
{
/* Create the worker threads running worker_routine */
th[i] = SAM_Execution_create(sam_context, *worker_routine, (void *)data_arg);
}
/* ---------------------------------------- */
for(i=0; i<ARRAY_SIZE; i++)
{
/* Create a delay to allow some context switches */
usleep(20*1000);
/* Set a new value in the array elements*/
myArray[i] = i;
/* Declare the region as written */
SAM_Memory_write(sam_context, myArray);
}
/* ---------------------------------------- */
for(i=0;i<N;i++)
{
/* Join the worker threads and get the result */
result = (int *)SAM_Execution_join(sam_context, th[i]);
/* Print the result */
printf("RES %d: %d\n", i, *result);
/* Do not forget to free the memory reserved to store the result */
free(result);
}
/* Release and unregister the memory region*/
SAM_Memory_region_release(sam_context, myArray);
SAM_Memory_region_unregister(sam_context, myArray);
/* Destroy the SAM context */
SAM_Destroy(&sam_context);
/* Free the memory */
free(myArray);
free(data_arg);
return 0;
}
[edit] Explanation
This example shows how to register a region, protect it, read from it speculatively and flash back a worker thread when needed.
In the main thread, first the memory region (in this case the integer array myArray) has to be registered and protected (calls to SAM_Memory_region_register() in the line 90 and SAM_Memory_region_protect() in the line 91). As shown in the line 109, after writing to memory the function SAM_Memory_write() must be called. After finishing the speculative access to the region of memory, it should be released and unregistered with the functions SAM_Memory_region_release() and SAM_Memory_region_unregister() as shown in the lines 127 and 128.
As for the speculative worker thread, the function SAM_Memory_speculative_read() must be called before the access to memory (see line 38).
[edit] Compile Command
gcc example3a.c -lsam -lpthread -o example3a