diff --git a/artifact/src/sim/main.cpp b/artifact/src/sim/main.cpp
index 3c4fa77652de61afedd68fc769ef887a67b7effe..14e4393736d44ccf5e72f6fa3c00c442ffee6883 100644
--- a/artifact/src/sim/main.cpp
+++ b/artifact/src/sim/main.cpp
@@ -475,13 +475,167 @@ void compute_responsetimes() {
 	sequences.push_back(control_jobs);
 }
 
+void process_ntasks(int i, int ntasks, vector<Task> tasks, vector<Task> hps) {
+	unsigned int control_task_id = ntasks - 1;
+
+	// utilization {0.7, 0.80}
+	for (unsigned int u = 0; u <= 1; u++) {
+		U_ts = 70 + u * 10;
+
+		// wc deadline miss load {25%, 100%}
+		for (unsigned int d = 0; d <= 1; d++) {
+
+			if (i == 2 && u == 1) continue;
+
+			// EXTRACT TASKSET FROM FILE
+			tasks.clear();
+			hps.clear();
+
+			dm_frac = 25 + d*75;
+
+			string taskset_path = "../tasksets/";
+			string taskset_name = "n" + std::to_string(ntasks) +
+				"_u" + std::to_string(U_ts) + "taskset_" + std::to_string(dm_frac) + ".csv";
+      cout << "  Handling " << taskset_name << endl;
+
+			ifstream input_tasklist(taskset_path + taskset_name);
+
+			if (input_tasklist.fail())
+				std::cout << "fail to find" << endl;
+
+			while (input_tasklist.peek() == '\n') // skip empty lines
+				input_tasklist.get();
+
+			// skip first line
+			string line;
+			getline(input_tasklist, line); // read a line from the input file
+
+			// Save taskset data
+			for (unsigned int l = 0; l < ntasks; l++) {
+				Task t;
+				getline(input_tasklist, line);
+				std::stringstream ss(line);
+				std::vector<double> vect;
+				string token;
+
+				for (unsigned int el = 0; el < N_SAMPLESEXTIME * 2 + 2; el++) {
+					getline(ss, token, ',');
+					vect.push_back(stod(token.c_str()));
+				}
+
+				t.task_id = vect.at(0);
+				t.period = vect.at(1);
+				for (unsigned int v = 0; v < N_SAMPLESEXTIME; v++)
+					t.exec_times.push_back(vect.at(2 + v));
+				for (unsigned int v = 0; v < N_SAMPLESEXTIME; v++)
+					t.prob_exec_time.push_back(vect.at(2 + N_SAMPLESEXTIME + v));
+				t.wcet = t.exec_times.at(N_SAMPLESEXTIME - 1);
+				t.bcet = t.exec_times.at(0);
+				tasks.push_back(t);
+			}
+			// skip another line
+			getline(input_tasklist, line);
+			// Save control periods
+			getline(input_tasklist, line);
+			std::stringstream ss(line);
+			std::vector<int> vect;
+			string token;
+
+			while (getline(ss, token, ','))
+				vect.push_back(atoi(token.c_str()));
+
+			// Fill hps
+			for (int x = 1; x < tasks.size(); x++)
+				hps.push_back(tasks.at(x - 1));
+
+			tasks.at(control_task_id).period = INT_MAX;
+
+			unsigned int T_max = 2000000;
+			unsigned int T_min = 500000;
+			unsigned int timegap = 100000;
+
+
+      // ----------------------------- STRATEGY-DEPENDANT PART start
+			for (int exp_strat = CONT_STRAT;
+				exp_strat <= SKIP_NEXT_STRAT;
+				exp_strat++) {
+
+				//cout << "------------------------------------------------" << endl;
+				strategy = static_cast<DM_STRATEGIES>(exp_strat);
+
+				// compute minimum time allowed for each strategy
+				unsigned int T_min_strat, T_min_appr;
+
+				//cout << "STRATEGY: ";
+				//switch (strategy) {
+
+				//case CONT_STRAT:
+				//	cout << "queue(1)" << endl;
+				//	break;
+
+				//case KILL_STRAT:
+				//	cout << "kill" << endl;
+				//	break;
+
+				//case SKIP_NEXT_STRAT:
+				//	cout << "skip-next" << endl;
+				//	break;
+
+				//default: break;
+
+				//}
+
+				// compute sequences for each time step
+        
+				for (unsigned int s = 0; s < N_PERIODSTEPS; s++) {
+
+					unsigned int Td = T_min + timegap*s;
+
+					tasks.at(control_task_id).period = Td;
+					//cout << " - control period " << tasks.at(control_task_id).period << endl;
+					timewindow = N_JOBS * tasks.at(control_task_id).period;
+
+					// generate worst-case schedule with all
+          // tasks experiencing WCET
+					sequences.clear();
+					generate_seq_jobs(tasks, false);
+					compute_responsetimes();
+					string filename = create_result_path() +
+            "wcet_seq_s" + std::to_string(strategy) +
+						"_t" + std::to_string(Td) + ".csv";
+          
+					write_single_sequence(sequences.at(0), filename);
+
+					// scenario-theoretic part:
+					// generate sequences for the given case
+					sequences.clear();
+					for (unsigned int n = 0; n < N_TESTS; n++) {
+						generate_seq_jobs(tasks, true);
+						compute_responsetimes();
+					}
+					// select worst sequence
+					sequence_selector();
+					//cout << "   worst sequence misses " << worst_seq.num_dm << endl;
+					//cout << "   worst sequence consecutive misses " << worst_seq.max_consec_dm << endl;
+
+					// save files to disk
+					write_sequences_disk(tasks.at(control_task_id).period);
+				} 
+			}
+      // ----------------------------- STRATEGY-DEPENDANT PART end
+    
+			//cout << "------------------------------------------------" << endl;
+		}
+	}
+}
+
 // *******************************************************************
 int main(int argc, char *argv[])
 {
   
-  pid_t child_pid, wpid;
-  int status = 0;
-	
+  int num_numtasks = 3;
+  int i;
+  pid_t pid;
 	unsigned int ntasks_sel[3] = {5, 10, 20};
 	
 	vector<Task> tasks;
@@ -493,168 +647,43 @@ int main(int argc, char *argv[])
   cout << "------------------------------------------------" << endl;
 
 	// number of tasks {5, 10, 20}
-	for (unsigned int i = 0; i <= 2; i++) {
+	//for (unsigned int i = 0; i <= 2; i++) {
     
-    if ((child_pid = fork()) == 0) {
+    pid = fork();   
+    if (pid == 0) {
       
+      i = 0;
   		ntasks = ntasks_sel[i];
-  		unsigned int control_task_id = ntasks - 1;
-
-  		// utilization {0.7, 0.80}
-  		for (unsigned int u = 0; u <= 1; u++) {
-  			U_ts = 70 + u * 10;
-
-  			// wc deadline miss load {25%, 100%}
-  			for (unsigned int d = 0; d <= 1; d++) {
-
-  				if (i == 2 && u == 1) continue;
-
-  				// EXTRACT TASKSET FROM FILE
-  				tasks.clear();
-  				hps.clear();
-
-  				dm_frac = 25 + d*75;
-
-  				string taskset_path = "../tasksets/";
-  				string taskset_name = "n" + std::to_string(ntasks) +
-  					"_u" + std::to_string(U_ts) + "taskset_" + std::to_string(dm_frac) + ".csv";
-          cout << "  Handling " << taskset_name << endl;
-
-  				ifstream input_tasklist(taskset_path + taskset_name);
-
-  				if (input_tasklist.fail())
-  					std::cout << "fail to find" << endl;
-
-  				while (input_tasklist.peek() == '\n') // skip empty lines
-  					input_tasklist.get();
-
-  				// skip first line
-  				string line;
-  				getline(input_tasklist, line); // read a line from the input file
-
-  				// Save taskset data
-  				for (unsigned int l = 0; l < ntasks; l++) {
-  					Task t;
-  					getline(input_tasklist, line);
-  					std::stringstream ss(line);
-  					std::vector<double> vect;
-  					string token;
-
-  					for (unsigned int el = 0; el < N_SAMPLESEXTIME * 2 + 2; el++) {
-  						getline(ss, token, ',');
-  						vect.push_back(stod(token.c_str()));
-  					}
-
-  					t.task_id = vect.at(0);
-  					t.period = vect.at(1);
-  					for (unsigned int v = 0; v < N_SAMPLESEXTIME; v++)
-  						t.exec_times.push_back(vect.at(2 + v));
-  					for (unsigned int v = 0; v < N_SAMPLESEXTIME; v++)
-  						t.prob_exec_time.push_back(vect.at(2 + N_SAMPLESEXTIME + v));
-  					t.wcet = t.exec_times.at(N_SAMPLESEXTIME - 1);
-  					t.bcet = t.exec_times.at(0);
-  					tasks.push_back(t);
-  				}
-  				// skip another line
-  				getline(input_tasklist, line);
-  				// Save control periods
-  				getline(input_tasklist, line);
-  				std::stringstream ss(line);
-  				std::vector<int> vect;
-  				string token;
-
-  				while (getline(ss, token, ','))
-  					vect.push_back(atoi(token.c_str()));
-
-  				// Fill hps
-  				for (int x = 1; x < tasks.size(); x++)
-  					hps.push_back(tasks.at(x - 1));
-
-  				tasks.at(control_task_id).period = INT_MAX;
-
-  				unsigned int T_max = 2000000;
-  				unsigned int T_min = 500000;
-  				unsigned int timegap = 100000;
-
-
-          // ----------------------------- STRATEGY-DEPENDANT PART start
-  				for (int exp_strat = CONT_STRAT;
-  					exp_strat <= SKIP_NEXT_STRAT;
-  					exp_strat++) {
-
-  					//cout << "------------------------------------------------" << endl;
-  					strategy = static_cast<DM_STRATEGIES>(exp_strat);
-
-  					// compute minimum time allowed for each strategy
-  					unsigned int T_min_strat, T_min_appr;
-
-  					//cout << "STRATEGY: ";
-  					//switch (strategy) {
-
-  					//case CONT_STRAT:
-  					//	cout << "queue(1)" << endl;
-  					//	break;
-
-  					//case KILL_STRAT:
-  					//	cout << "kill" << endl;
-  					//	break;
-
-  					//case SKIP_NEXT_STRAT:
-  					//	cout << "skip-next" << endl;
-  					//	break;
-
-  					//default: break;
-
-  					//}
-
-  					// compute sequences for each time step
-            
-  					for (unsigned int s = 0; s < N_PERIODSTEPS; s++) {
-
-  						unsigned int Td = T_min + timegap*s;
-
-  						tasks.at(control_task_id).period = Td;
-  						//cout << " - control period " << tasks.at(control_task_id).period << endl;
-  						timewindow = N_JOBS * tasks.at(control_task_id).period;
-
-  						// generate worst-case schedule with all
-              // tasks experiencing WCET
-  						sequences.clear();
-  						generate_seq_jobs(tasks, false);
-  						compute_responsetimes();
-  						string filename = create_result_path() +
-                "wcet_seq_s" + std::to_string(strategy) +
-  							"_t" + std::to_string(Td) + ".csv";
-              
-  						write_single_sequence(sequences.at(0), filename);
-
-  						// scenario-theoretic part:
-  						// generate sequences for the given case
-  						sequences.clear();
-  						for (unsigned int n = 0; n < N_TESTS; n++) {
-  							generate_seq_jobs(tasks, true);
-  							compute_responsetimes();
-  						}
-  						// select worst sequence
-  						sequence_selector();
-  						//cout << "   worst sequence misses " << worst_seq.num_dm << endl;
-  						//cout << "   worst sequence consecutive misses " << worst_seq.max_consec_dm << endl;
-
-  						// save files to disk
-  						write_sequences_disk(tasks.at(control_task_id).period);
-  					} 
-  				}
-          // ----------------------------- STRATEGY-DEPENDANT PART end
-        
-  				//cout << "------------------------------------------------" << endl;
-  			}
-  		}
-      exit(0);
-    
-    }
-    while ((wpid = wait(&status)) > 0) {
-        printf("Thread %d completed sequence generation\n", (int) wpid);
+      cout <<"[worker] pid " << getpid() << " from [parent] pid " << getppid() << " processing " << ntasks << endl;
+      process_ntasks(i, ntasks, tasks, hps);
+      cout <<"[worker] pid " << getpid() << " from [parent] pid " << getppid() << " terminated " << ntasks << endl;
+      exit(0); 
     }
+    else {
+      pid = fork();   
+      if (pid == 0) {
+      
+        i = 1;
+    		ntasks = ntasks_sel[i];
+        cout <<"[worker] pid " << getpid() << " from [parent] pid " << getppid() << " processing " << ntasks << endl;
+        process_ntasks(i, ntasks, tasks, hps);
+        cout <<"[worker] pid " << getpid() << " from [parent] pid " << getppid() << " terminated " << ntasks << endl;
+        exit(0); 
+      }
+    else {
+      pid = fork();   
+      if (pid == 0) {
+      
+        i = 2;
+    		ntasks = ntasks_sel[i];
+        cout <<"[worker] pid " << getpid() << " from [parent] pid " << getppid() << " processing " << ntasks << endl;
+        process_ntasks(i, ntasks, tasks, hps);
+        cout <<"[worker] pid " << getpid() << " from [parent] pid " << getppid() << " terminated " << ntasks << endl;
+        exit(0); 
+      }
+      else
+        for (int thr = 0; thr < 3; thr++) wait(NULL);
+    } 
 	}
 	return 0;
 }