// Example 3.2. See page 14 of the FG tutorial. #include "FG.h" #include using namespace std; // Stage function prototypes. int create_stage(FG_stage, FG_stage_params); int rotate_stage(FG_stage, FG_stage_params); int print_stage(FG_stage, FG_stage_params); int main() { // Initialize the seed, because we'll be generating random numbers. srand(time(0)); // Initialize N, the number of ints in each buffer. const int N = 10; // Declare the pipeline variables. int buffer_size = sizeof(int) * N; int num_rounds = 1; int num_aux_buffers = 1; // Declare the threads, and store them in a NULL-terminated array. FG_pipeline_thread_helper create_t = new FG_pipeline_thread_helper_info(), rotate_t = new FG_pipeline_thread_helper_info(), print_t = new FG_pipeline_thread_helper_info(); FG_pipeline_thread_helper threads[] = {create_t, rotate_t, print_t, NULL}; // Declare the stages. FG_pipeline_stage_helper create_s = new FG_pipeline_stage_helper_info(create_t), rotate_s = new FG_pipeline_stage_helper_info(rotate_t), print_s = new FG_pipeline_stage_helper_info(print_t); // Assign a function to each stage. create_s->set_func(create_stage, NULL); rotate_s->set_func(rotate_stage, NULL); print_s->set_func(print_stage, NULL); // Store the stages in a NULL-terminated array. FG_pipeline_stage_helper stages[] = {create_s, rotate_s, print_s, NULL}; // Instantiate the pipeline. FG_pipeline my_pipeline = FG_pipeline_info::create(stages, threads); // Set the pipeline variables. my_pipeline->set_buff_size(buffer_size); my_pipeline->set_num_rounds(num_rounds); my_pipeline->set_num_aux(num_aux_buffers); // Fix the pipeline, which also runs it, and store the return code. int error = my_pipeline->fix(); // Display the return code. cout << "FINISHED PIPELINE WITH ERROR CODE " << error << endl; // Dismantle the pipeline. my_pipeline->dismantle(); return 0; } int create_stage(FG_stage my_stage, FG_stage_params my_params) { // Set a limit for the randomly generated numbers. const int LIMIT = 1024; // Accept a thumbnail from the preceding stage, and store the // location of its buffer. FG_pipeline_thumbnail thumb = my_stage->accept_thumbnail(); int *buff = (int *) thumb->get_address(); // Determine how many ints each buffer holds. int n = thumb->get_size() / sizeof(int); // Randomly generate n integers, store them in the buffer, and print // them. for (int i = 0; i < n; i++) { buff[i] = rand() % LIMIT; cout << buff[i] << " "; } cout << endl; // Convey the thumbnail to the next stage. my_stage->convey_thumbnail(thumb); return 0; } int rotate_stage(FG_stage my_stage, FG_stage_params my_params) { const int ROTATE_BY = 5; // rotate each int by 5 positions. // Accept a thumbnail from the preceding stage, and save the // location of its buffer. FG_pipeline_thumbnail pipeline_thumb = my_stage->accept_thumbnail(); int *pipeline_buff = (int *) pipeline_thumb->get_address(); // Get an auxiliary thumbnail, and save the location of its buffer. FG_aux_thumbnail aux_thumb = my_stage->get_aux_thumbnail(); int *aux_buff = (int *) aux_thumb->get_address(); // Determine how many ints each buffer holds. int n = pipeline_thumb->get_size() / sizeof(int); // Copy each int from its original location in the pipeline buffer // into its new location in the auxiliary buffer. for (int i = 0; i < n; i++) aux_buff[(i + ROTATE_BY) % n] = pipeline_buff[i]; // Swap the auxiliary buffer into the pipeline, and turn the // pipeline buffer into an auxiliary buffer. aux_thumb->swap(pipeline_thumb); // We are done with the auxiliary thumbnail and its buffer. my_stage->release_aux_thumbnail(aux_thumb); // Convey the pipeline thumbnail (with its new buffer) to the next // stage. my_stage->convey_thumbnail(pipeline_thumb); return 0; } int print_stage(FG_stage my_stage, FG_stage_params my_params) { // Accept a thumbnail from the preceding stage, and save the // location of its buffer. FG_pipeline_thumbnail thumb = my_stage->accept_thumbnail(); int *buff = (int *) thumb->get_address(); // Determine how many ints each buffer holds. int n = thumb->get_size() / sizeof(int); // Print each int. for (int i = 0; i < n; i++) cout << buff[i] << " "; cout << endl; // Convey the thumbnail to the next stage. my_stage->convey_thumbnail(thumb); return 0; }