// Maximum performance with optimal count of forks. // HOW TO BUILD // gcc sum.c -lpthread #include #include #include #include #include #include #include #define SEMAPHORES 1 static long *main_result; static long *finished; long sumumatoru_kun (long start, long end) { long num, digit, sum = 0; while (end > start) { num = end; while (num > 0) { digit = num % 10; sum = sum + digit; num /= 10; } end--; } return sum; } int main(int argc, char *argv[]) { long end, start, first, last, shift, i, temp; int p_pid = getpid(); // long f_count = 3 * get_nprocs_conf(); long f_count = 1; pid_t pid; main_result = mmap(NULL, sizeof *main_result, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); finished = mmap(NULL, sizeof *finished, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); sem_t *semaphore = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); *main_result = 0; *finished = 0; start = 0; sem_init (semaphore, 1, 1); printf("This system has %d processors configured. Going to spawn %ld forks.\n", get_nprocs_conf(), f_count); if (argc < 2) { return 228; } end = strtoll(argv[1], NULL, 0); if(f_count >= end) { f_count = 1; } shift = end / f_count; i = 0; while(i < f_count) { if(pid == 0){break;} pid = fork(); if(i + 1 == f_count) { last = end; } else { last = (start + shift*i) + shift; } first = start + shift*i; i++; } if(pid == 0) { printf("Child %d was started. My job is \t%ld \t%ld\n", getpid(), first, last); temp = sumumatoru_kun(first, last); if (SEMAPHORES) sem_wait(semaphore); *main_result = *main_result + temp; if (SEMAPHORES) sem_post(semaphore); } else { i = f_count; } *finished = *finished + 1; if(p_pid == getpid()){ while(*finished < f_count + 1) { usleep(10 * 1000); } if (SEMAPHORES) sem_wait(semaphore); printf("%d - Sumumatoru kun handled %ld forks and got result %ld\n", getpid(), f_count, *main_result); } return 0; }