// Example 3.3. See page 16 of the FG tutorial. #include "FG.h" #include using namespace std; // Class to store the thumbnail parameters. class My_thumbnail_params : public FG_thumbnail_params { public : int max, min; virtual ~My_thumbnail_params() {} }; // Stage function prototypes. int create(FG_stage, FG_stage_params); int max_min_finder(FG_stage, FG_stage_params); int max_min_printer(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 = 5; // Declare the threads, and store them in a NULL-terminated array. FG_pipeline_thread_helper create_t = new FG_pipeline_thread_helper_info(), maxmin_t = new FG_pipeline_thread_helper_info(), print_t = new FG_pipeline_thread_helper_info(); FG_pipeline_thread_helper threads[] = {create_t, maxmin_t, print_t, NULL}; // Declare the stages. FG_pipeline_stage_helper create_s = new FG_pipeline_stage_helper_info(create_t), maxmin_s = new FG_pipeline_stage_helper_info(maxmin_t), print_s = new FG_pipeline_stage_helper_info(print_t); // Assign a function to each stage. create_s->set_func(create, NULL); maxmin_s->set_func(max_min_finder, NULL); print_s->set_func(max_min_printer, NULL); // Store the stages in a NULL-terminated array. FG_pipeline_stage_helper stages[] = {create_s, maxmin_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); // 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(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; } // Stage to find the max and min values in each buffer. int max_min_finder(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 the buffer holds. int n = thumb->get_size() / sizeof(int); // Create and store a pointer to a My_thumbnail_params object, if // there isn't already one in this pipeline thumbnail. if (thumb->get_params() == NULL) { My_thumbnail_params *thumb_params = new My_thumbnail_params(); thumb->set_params(thumb_params); } // Now get a pointer to the My_thumbnail_params object in the // pipeline thumbnail. It might be a recycled one, or it might be // one that we just created. My_thumbnail_params *thumb_params = (My_thumbnail_params *) thumb->get_params(); // Start with the int in position 0 of the buffer as both max and min. thumb_params->max = thumb_params->min = buff[0]; // Go through the buffer, updating max and min as needed. for (int i = 0; i < n; i++) { if (buff[i] > thumb_params->max) thumb_params->max = buff[i]; if (buff[i] < thumb_params->min) thumb_params->min = buff[i]; } // Convey the thumbnail (now with its parameters) to the next stage. my_stage->convey_thumbnail(thumb); return 0; } // Stage to print the max and min values for a buffer, which have // already been stored in the thumbnail parameters. int max_min_printer(FG_stage my_stage, FG_stage_params my_params) { // Accept a thumbnail from the preceding stage. FG_pipeline_thumbnail thumb = my_stage->accept_thumbnail(); // Get the thumbnail parameters, which we assume are from the class // My_thumbnail_params. My_thumbnail_params *thumb_params = (My_thumbnail_params *) thumb->get_params(); // Print the max and min values. cout << "max = " << thumb_params->max << ", min = " << thumb_params->min << endl; // Convey the thumbnail to the next stage. my_stage->convey_thumbnail(thumb); return 0; }