void task1()   // producer task
     {
		unsigned int data_token = 0;
		
		while(true) {
		  cout << "\ttask 1 " << " starts some computation at t=" << sc_time_stamp() << endl;
		  consume(t_prod);
          cout << "\ttask 1 " << " dumps data on the circular buffer at t=" << sc_time_stamp() << endl;		  
		  
#ifdef _USING_SEMAPHORE_FOR_PROTECTING_THE_ACCESS
		  write_sem.wait();
#endif		
		  unprotected_cbuff.push(data_token);

#ifdef _USING_SEMAPHORE_FOR_PROTECTING_THE_ACCESS
		  read_sem.post();
#endif				  
		  data_token++;
		  
#ifdef _USING_FLAG_FOR_PROTECTING_THE_ACCESS
		  flag1.set();
#endif		  
  
		}
     }
     void task2()  // consumer task
     {
		while(true) {
			cout << "Task 2 waits for data at time " << sc_time_stamp() << endl;
#ifdef _USING_FLAG_FOR_PROTECTING_THE_ACCESS			
			wait(flag1);
#endif

#ifdef _USING_SEMAPHORE_FOR_PROTECTING_THE_ACCESS
			read_sem.wait();
#endif
			// KisTA model
		    cout << "task 2 " << "READ " << unprotected_cbuff.pop() << " from circular buffer at t=" << sc_time_stamp() << endl;
			consume(t_cons);
			cout << "task 2 " << "ends some processing at t=" << sc_time_stamp() << endl;
#ifdef _USING_SEMAPHORE_FOR_PROTECTING_THE_ACCESS
			write_sem.post();
#endif		    
		}
     }
 void run(semaphore & sync_sem)
 {
     running.store(true, boost::memory_order_relaxed);
     sync_sem.post();
     perform();
 }