/* Including the OpenMP header file */
#include <omp.h>

#include <iostream>
#include <sstream>


int main (int argc, char *argv[])
{
    /* Inserting OpenMP pragma to make the following code block parallel */
    #pragma omp parallel
    {
        std::stringstream ss;

        /*
         * Getting the individual thread number in 'id'
         * using a runtime routine
         */
        int id = omp_get_thread_num();

        /* Print Hello world from each thread */
        ss << "Hello World from thread "<< id << std::endl;
        std::cout << ss.str();
        ss.str("");

        /*
         * Making sure each thread has printed "Hello World",
         * before we move forward
         */

        #pragma omp barrier

        /* Making the master thread to identify itself! */
        #pragma omp master
        {
            ss << "Hi, I am MASTER, my id is always "<< id << std::endl;
            std::cout << ss.str();
            ss.str("");
        }

        /*
         * Now print Hello OpenMP from each thread
         * (after all everybody needs to learn OpenMP!)
         */
        ss << "Hello OpenMP from thread "<< id << std::endl;
        std::cout << ss.str();
    }

    return 0;
}
