#include <stdio.h>
#include <stdlib.h>
#include <sam.h>
#include "bs.h"
#include "conf.h"
struct datast
{
int index;
void *pdat;
int doit;
};
int cmp1(utype a, utype b)
{
if (a > b)
return 1;
else if (a < b)
return -1;
else
return 0;
}
int cmp2(utype a, utype b)
{
if (a < b)
return 1;
else if (a > b)
return -1;
else
return 0;
}
void * worker_routine(void *args)
{
SAM_t sam_context; /* Declare a SAM context variable */
void *myargs; /* Pointer to where the arguments are stored */
struct datast *data_arg; /* Pointer to the arguments of the function */
int *result; /* Pointer to the result (total) of the calculation */
SAM_pdif_t dif; /* The differential for the __SAM_ADDR__() macro*/
void *data;
int index;
/* Start the execution of this worker thread */
/* Extract the SAM context and the arguments */
SAM_Execution_start(args, &sam_context, &myargs);
/* Extract the arguments of the function */
data_arg = (struct datast *) myargs;
index = data_arg->index;
data = data_arg->pdat;
if(data_arg->doit)
{
/* Declare the region as read by the worker thread */
SAM_Memory_speculative_read(sam_context, SAM_My_workid(sam_context), data);
/* Prepare the memory region for speculative write and obtain the differential parameter */
dif = SAM_Memory_speculative_write_prepare(sam_context, data);
bubbleSort(data, cmp1, NX, dif);
}
SAM_Execution_finish(sam_context);
result = (int *) malloc(sizeof(int));
*result = 0;
return result;
}
void fillArray(utype *A)
{
int i;
for(i=0; i < NX; i++)
{
A[i] = rand();
}
}
int main()
{
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 */
struct datast data_arg[N]; /* Pointer to the worker threads arguments */
utype *dat;
utype *ldat;
int i;
int j;
int n;
int next;
int sel;
dat = malloc(NX * NY * sizeof(utype));
ldat = malloc(NX * sizeof(utype));
for(i=0; i < NY; i++)
{
fillArray(&dat[i*NX]);
}
fillArray(ldat);
/* Initialize the SAM context */
SAM_Init(&sam_context);
/* Register a region and protect it */
for(i=0; i < NY; i++)
{
SAM_Memory_region_register(sam_context, &dat[i*NX], NX * sizeof(utype));
SAM_Memory_region_protect(sam_context, &dat[i*NX]);
}
for(i=0; i < N; i++)
{
data_arg[i].index = i;
data_arg[i].pdat = &dat[i*NX];
data_arg[i].doit = 1;
/* Create the worker threads running worker_routine */
th[i] = SAM_Execution_create(sam_context, *worker_routine, (void *)(&data_arg[i]));
}
bubbleSort(ldat, cmp2, NX, 0);
for(j=0; j < NX; j++)
{
ldat[j] = ldat[j] % (1024 + j);
}
sel = rand() % NX;
sel = ldat[sel] % NY;
printf("sel: %d\n", sel);
for(i=0;i<N;i++)
{
if(i != sel)
{
SAM_Execution_cancel(sam_context, th[i]);
}
}
result = (int *)SAM_Execution_join(sam_context, th[sel]);
free(result);
/* Release and unregister the memory region*/
for(i=0; i < NY; i++)
{
SAM_Memory_region_release(sam_context, &dat[i*NX]);
SAM_Memory_region_unregister(sam_context, &dat[i*NX]);
}
/* Destroy the SAM context */
SAM_Destroy(&sam_context);
for(i=0; i < NY; i++)
{
for(j=0; j < NX; j++)
{
printf("(%d, %d) --> %d\n", i, j, dat[(i*NX)+j]);
}
}
free(dat);
free(ldat);
return 0;
}