/* Début de corrigé de la partie 2 * * Ce programme partage un tableau de 32 pages entre 2 process * par des tubes un fork. * Chaque page a un attribut INVALID ou READWRITE. * Chaque attribut et mprotect est protegé par un mutex pour * éviter des race conditions. */ #define _GNU_SOURCE /* a garder TOUT EN HAUT du fichier */ #include #include #include #include #include #include #include #include #include #include #include #define PAGE_SIZE 4096 #define PAGES 32 #define BASEVAL 50 #define ITERATIONS 100 enum status { INVALID, READONLY, READWRITE, }; struct pageattr { enum status status; }; static char *buffer; static struct pageattr attr[PAGES]; static pthread_mutex_t mutex[PAGES]; static int fd_outreq; /* where I send my requests to the other process */ static int fd_inresp; /* where I receive the other process responses to my requests */ static int fd_inreq; /* where I receive requests from the other process */ static int fd_outresp; /* where I send responses to the other process requests */ static void * thread_func(void *data) { char c; printf("[%d] thread starting\n", getpid()); while (read(fd_inreq, &c, 1) == 1) { int index = c; char *page = buffer+index*PAGE_SIZE; // printf("[%d] got need page %x request\n", getpid(), c); pthread_mutex_lock(&mutex[index]); write(fd_outresp, page, PAGE_SIZE); mprotect(page, PAGE_SIZE, PROT_NONE); attr[index].status = INVALID; pthread_mutex_unlock(&mutex[index]); } printf("[%d] thread exiting\n", getpid()); return NULL; } static void segv_handler(int sig, siginfo_t *info, void *_context) { ucontext_t *context = _context; // int writeaccess = (context->uc_mcontext.gregs[REG_ERR] & 2); #ifdef __x86_64__ void *addr = (void *)(context->uc_mcontext.gregs[REG_CR2]); #elif __i386__ void *addr = (void *)(context->uc_mcontext.cr2); #else #error Architecture non support?e #endif char *page = (void *)(((unsigned long) addr) & ~(PAGE_SIZE-1)); int index = (page-buffer)/PAGE_SIZE; pthread_mutex_lock(&mutex[index]); if (attr[index].status == INVALID) { char c = index; // printf("[%d] sending need page %x request\n", getpid(), index); write(fd_outreq, &c, 1); /* request the page */ mprotect(page, PAGE_SIZE, PROT_READ|PROT_WRITE); attr[index].status = READWRITE; read(fd_inresp, page, PAGE_SIZE); } pthread_mutex_unlock(&mutex[index]); } int main(int argc, char *argv[]) { int pipes[8]; struct sigaction act; pthread_t thread; pid_t pid; int i,j; int ret; buffer = memalign(PAGE_SIZE, PAGE_SIZE*PAGES); if (!buffer) { printf("failed to malloc\n"); exit(-1); } /* initialise les donnees */ for(i=0; i