Files
sum_counter/sum.c
2020-07-08 05:31:09 +03:00

113 lines
2.3 KiB
C

// Maximum performance with optimal count of forks.
// HOW TO BUILD
// gcc sum.c -lpthread
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysinfo.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <semaphore.h>
#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;
}