#ifndef SCHEDULERS_HPP
#define SCHEDULERS_HPP

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <vector>
#include <cmath>
#include <errno.h>
using namespace std;

class Prolific{
	public:
		static void run(int workers,int total_tasks,void (*task_func)(int)){
			pid_t root=getpid();
			for(int i=0;i<workers;i++){
				if(getpid()!=root) break;
				if(fork()==0){
					for(int t=0;t<total_tasks;t++){
						if(t%workers==i){
							task_func(t);
						}
					}
					_exit(0);
				}
			}
			if(getpid()==root){
				while(waitpid(-1,NULL,0)>0||errno!=ECHILD);
			}
		}
};

class Collective{
	public:
		static void run(int levels,int total_tasks,void (*task_func)(int)){
			pid_t root=getpid();
			for(int i=0;i<levels;i++){
				fork();
			}
			if(getpid()!=root){
				int worker_id=getpid()%root;
				int worker_count=pow(2,levels)-1;
				for(int t=0;t<total_tasks;t++){
					if(t%worker_count==worker_id%worker_count){
						task_func(t);
					}
				}
				_exit(0);
			} else{
				while(waitpid(-1,NULL,0)>0||errno!=ECHILD);
			}
		}
};

#endif
