I have a server which is multiprocess and multithreaded. The child processes while handling request updates some statistics. This statistics data is a struct updated by all the child processes. Each of these child processes is again multithreaded. The number of child processes is dynamic(increases or decreases) based on the number of requests.
To synchronize the writes to this stat struct, I use mmap. Here is how the map is initialized.
fd = open(mapfile, O_CREAT|O_RDWR, 0666);
write(fd, dummy, MMAP_FILE_SIZE); //dummy is all zeros
void *addr = mmap(0, sizeof(stat_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (addr == (void *)-1) {
mapped = 0;
}
else {
gStat = (stat_t*)addr;
}
// here gStat struct is initialized
Also in the code where I manipulate the stats, I use a lock to synchronize across multiple threads within the process.
Now, the issue I am having is that under heavy load, the writes don't seem to synchronize. The statistics are not updated correctly. Under normal load, the stats get incremented correctly.
According to my understanding, If MAP_SHARED is specified, write references change the underlying object and the mapping type is retained across fork(). What am I missing?