
// example of mmap() system call; can be used for parallel I/O; this
// example uses OpenMP for convenience

// assumes two threads, one of which will write "abcdef" to the file,
// with the other writing "wxyz"; output file is named "outfile"

// #include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>

#include <omp.h>

#define OUTFILESIZE 10

int fd;  // file descriptor for output file
char * mem;  // the mmap region

void writefile()
{
   #pragma omp parallel
   {  int me=omp_get_thread_num();  // my thread ID
      if (me == 0) strncpy(mem,"abcdef",6);
      else strncpy(mem+6,"wxyz",4);
      #pragma omp barrier
   }
}

int main(int argc, char **argv)
{  int err;
   fd = open("outfile", // output file name
             O_RDWR|O_CREAT|O_TRUNC, // we can read/write output file,
                                     // are creating it, and if it
                                     // already exists, we are replacing
                                     // the old version
             0600);  // file will have read/write permission for owner 
                     // and no permissions for other users 
   // check for error
   if (fd == -1) { 
      perror("couldn't open file for writing");
      exit(1);
   }
   // "stretch" file from 0 bytes to OUTFILESIZE by writing something at 
   // the last byte 
   lseek(fd,OUTFILESIZE-1,SEEK_SET);
   write(fd,"",1);
   mem = mmap(0,  // OS chooses location for mem
               OUTFILESIZE,  // number of bytes to be in the map
               PROT_READ|PROT_WRITE,  // allow read/write (must match fd)
               MAP_SHARED,  // map can be accessed by other processes
               fd,  // file descriptor to be mapped,
               0);  // the start offset in file is 0
   // check for error
   if (mem == MAP_FAILED) {
      perror("mmap failed");
      exit(2);
   }
   // start parallel
   writefile();
   // back to single-thread
   err = munmap(mem,OUTFILESIZE);
   if (err == -1) {
      perror("munmap() failed");
      exit(3);
   }
   close(fd);  // file should exist now

}


