diff --git a/work/tp3/pipebis3.c b/work/tp3/pipebis3.c
index 9d3edcf8ae01ae06f1167e04f61ec2c4fea55360..269b6b22a075e376e59ac0ca87bf3c9fd5547b50 100644
--- a/work/tp3/pipebis3.c
+++ b/work/tp3/pipebis3.c
@@ -16,9 +16,13 @@
 #include <linux/uaccess.h> /* for get_user and put_user */ 
 #include <linux/version.h> 
 #include <linux/wait.h> /* For putting processes to sleep and waking them up */  
+#include <linux/mutex.h> 
 
 #include <asm/current.h> 
 #include <asm/errno.h> 
+
+#define TRUE 1
+#define FALSE 0
  
 /*  Prototypes - this would normally go in a .h file */ 
 static int device_open(struct inode *, struct file *); 
@@ -43,7 +47,7 @@ static int asee_buf_size = BUF_LEN;
 
 static ssize_t asee_buf_size_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 {
-    return sprintf(buf, "%d\n", asee_buf_size);
+    return sprintf(buf, "asee_buf_size = %d\n", asee_buf_size);
 }
 
 static ssize_t asee_buf_size_store(struct kobject *kobj, struct kobj_attribute *attr, char *buf, size_t count)
@@ -71,7 +75,7 @@ static struct kobj_attribute asee_buf_size_attribute = __ATTR(asee_buf_size, 066
 
 static ssize_t asee_buf_count_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 {
-    return sprintf(buf, "%d\n", asee_buf_count);
+    return sprintf(buf, "asee_buf_count = %d\n", asee_buf_count);
 }
 
 static ssize_t asee_buf_count_store(struct kobject *kobj, struct kobj_attribute *attr, char *buf, size_t count)
@@ -89,11 +93,11 @@ enum {
 }; 
  
 /* Is device open? Used to prevent multiple access to device */ 
-static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED); 
-static atomic_t already_full = ATOMIC_INIT(0); 
+// static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED); 
+static atomic_t already_full = ATOMIC_INIT(FALSE); 
 static DECLARE_WAIT_QUEUE_HEAD(wait_full); 
  
-static atomic_t empty_buffer = ATOMIC_INIT(0); 
+static atomic_t empty_buffer = ATOMIC_INIT(TRUE); 
 static DECLARE_WAIT_QUEUE_HEAD(wait_empty);
 
 static struct class *cls; 
@@ -161,11 +165,13 @@ static int device_open(struct inode *inode, struct file *file)
    // if (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN)) 
     //    return -EBUSY; 
 
-    if ((file->f_flags & O_NONBLOCK) && atomic_read(&already_full)) 
-        return -EAGAIN;
+    pr_info("(file->f_flags & (O_NONBLOCK | O_WRONLY)) && atomic_read(&already_full) == %d\n", (file->f_flags & (O_NONBLOCK | O_WRONLY)) && atomic_read(&already_full));
+    /*if ((file->f_flags & (O_NONBLOCK | O_WRONLY)) && atomic_read(&already_full)) 
+        return -EAGAIN;*/
 
-    if ((file->f_flags & O_NONBLOCK) && atomic_read(&empty_buffer)) 
-        return -EAGAIN;
+    pr_info("(file->f_flags & (O_NONBLOCK | O_RDONLY))  && atomic_read(&empty_buffer) == %d\n", (file->f_flags & (O_NONBLOCK | O_RDONLY))  && atomic_read(&empty_buffer));
+    /*if ((file->f_flags & (O_NONBLOCK | O_RDONLY))  && atomic_read(&empty_buffer)) 
+        return -EAGAIN;*/
 
     try_module_get(THIS_MODULE); 
  
@@ -194,11 +200,12 @@ static int device_release(struct inode *inode, struct file *file)
 
 static int block_empty_buff(void) 
 {
-    while (atomic_cmpxchg(&empty_buffer, 0, 1)) { 
+    while (atomic_cmpxchg(&empty_buffer, FALSE, TRUE) == TRUE) { // true if empty
         int i, is_sig = 0; 
         
-        wait_event_interruptible(wait_empty, !atomic_read(&empty_buffer));    
-        
+        pr_info("wait_event_interruptible(wait_empty, atomic_read(&empty_buffer));\n");
+        wait_event_interruptible(wait_empty, atomic_read(&empty_buffer) == FALSE);    
+        pr_info("wait empty unlock and wqke up \n");
         for (i = 0; i < _NSIG_WORDS && !is_sig; i++) {
             is_sig = current->pending.signal.sig[i] & ~current->blocked.sig[i]; 
         }
@@ -207,12 +214,24 @@ static int block_empty_buff(void)
             module_put(THIS_MODULE);
             return -1;
         }
+
     }
+    pr_info("leaving block empty buff \n");
     return 0;
 }
 
+static void print_buf_now(void) {
+    //for (int i = 0; i < asee_buf_size; i++) {
+    //    pr_info("%x ", msg[i]);
+    //}
+    pr_info("%s \n", msg);
+}
+
 static int last_writen_bytes = 0;
 static int last_read_bytes = 0;
+
+static DEFINE_MUTEX(asse_buf_count_mutex);
+
 static ssize_t device_read(struct file *filp, /* see include/linux/fs.h   */ 
                            char __user *buffer, /* buffer to fill with data */ 
                            size_t length, /* length of the buffer     */ 
@@ -222,32 +241,35 @@ static ssize_t device_read(struct file *filp, /* see include/linux/fs.h   */
     int bytes_read = 0; 
     char *msg_ptr = msg; 
 
+    pr_info("asee_buf_count %d\n", asee_buf_count);
+    
     if (asee_buf_count <= 0) {
+        pr_info("Read blocked\n");
         if (block_empty_buff() < 0) return 0;
     }
  
     /* Actually put the data into the buffer */ 
     while (asee_buf_count > 0) { 
+        //pr_info("while (asee_buf_count > 0) { %d\n", asee_buf_count);
+        print_buf_now();
+        mutex_lock(&asse_buf_count_mutex);
+        pr_info("Number of char to read: %d", asee_buf_count);
         if (last_read_bytes >= asee_buf_size) {
             last_read_bytes = 0;
         }
-        /* The buffer is in the user data segment, not the kernel 
-         * segment so "*" assignment won't work.  We have to use 
-         * put_user which copies data from the kernel data segment to 
-         * the user data segment. 
-         */ 
-        
+        pr_info("Reading at position: %d", last_read_bytes);
+
         put_user(*(msg_ptr + last_read_bytes), buffer++);
+        pr_info("char read now: %x", *(msg_ptr + last_read_bytes));
         // Try to clear the read
         *(msg_ptr + last_read_bytes) = '\0';
         last_read_bytes++;
         asee_buf_count--;
         bytes_read++;
-        atomic_set(&already_full, 0); 
+        atomic_set(&already_full, FALSE); 
+        mutex_unlock(&asse_buf_count_mutex);
+        
         wake_up(&wait_full);
-        //if (asee_buf_count <= 0) {
-        //    if (block_empty_buff() < 0) return 0;
-        //}
     } 
     *offset = last_read_bytes; 
  
@@ -257,10 +279,13 @@ static ssize_t device_read(struct file *filp, /* see include/linux/fs.h   */
 
 static int block_full_buff(void) 
 {
-    while (atomic_cmpxchg(&already_full, 0, 1)) { 
+    while (atomic_cmpxchg(&already_full, FALSE, TRUE) == TRUE) { // if buf full
         int i, is_sig = 0; 
         
-        wait_event_interruptible(wait_full, !atomic_read(&already_full));    
+        mutex_unlock(&asse_buf_count_mutex);
+        pr_info("wait_event_interruptible(wait_full, !atomic_read(&already_full));\n");
+        wait_event_interruptible(wait_full, atomic_read(&already_full) == FALSE);    
+        pr_info("wake up block_full\n");
         
         for (i = 0; i < _NSIG_WORDS && !is_sig; i++) {
             is_sig = current->pending.signal.sig[i] & ~current->blocked.sig[i]; 
@@ -280,32 +305,51 @@ static ssize_t device_write(struct file *filp, const char __user *buff,
 { 
     int bytes_writen = 0;
 
-    int current_bytes = last_writen_bytes;
-
     if (asee_buf_count >= asee_buf_size) {
         if ( block_full_buff() < 0 ) return 0;
     }
 
     for (int cpt = 0; cpt < len; cpt++) {
-        if (current_bytes >= asee_buf_size) {
-            current_bytes = 0;
+        //pr_info("Mutex lock\n");
+        mutex_lock(&asse_buf_count_mutex);
+        //pr_info("Mutex locked\n");
+        
+        if (last_writen_bytes >= asee_buf_size) {
+            last_writen_bytes = 0;
         }
-        get_user(*(msg + current_bytes), buff + cpt);
-        current_bytes++;
+        get_user(*(msg + last_writen_bytes), buff + cpt);
+        pr_info("Writing at: %d", last_writen_bytes);
+
+        last_writen_bytes++;
         bytes_writen++;
 
-        atomic_set(&empty_buffer, 0); 
+        //pr_info("atomic_set(&empty_buffer, 1);\n");
+        atomic_set(&empty_buffer, FALSE); 
+        //pr_info("Waking up empty\n");
         wake_up(&wait_empty);
 
         if (asee_buf_count < asee_buf_size) {
+            //pr_info("asee_buf_count++;\n");
             asee_buf_count++;
+            mutex_unlock(&asse_buf_count_mutex);
         } else {
+            //pr_info("atomic_set(&already_full, 1); \n");
+            atomic_set(&already_full, TRUE); 
+
             if ( block_full_buff() < 0 ) return 0;
         }
     }
-    last_read_bytes = (last_read_bytes + bytes_writen) % asee_buf_count;
 
-    last_writen_bytes = current_bytes;
+    mutex_lock(&asse_buf_count_mutex);
+    // Le probleme est ici, cela donne zero au debut
+    pr_info("last_read_bytes: %d", last_read_bytes);
+    // We change asee_buf_size :TODO handle modulo
+    last_read_bytes = (last_read_bytes + bytes_writen) % asee_buf_size;
+    pr_info("bytes_writen: %d", bytes_writen);
+    pr_info("asee_buf_count: %d", asee_buf_count);
+
+    pr_info("Last read byte update to: %d", last_read_bytes);
+    mutex_unlock(&asse_buf_count_mutex);
     *off = last_writen_bytes; 
 
     return bytes_writen; 
diff --git a/work/tp3/pipebis3.mod.c b/work/tp3/pipebis3.mod.c
index 1508ee4d1860b16736802e186644dd9882ca7251..d4f0c91402bf00ca7f58514cd6fc64b87326c310 100644
--- a/work/tp3/pipebis3.mod.c
+++ b/work/tp3/pipebis3.mod.c
@@ -35,8 +35,11 @@ MODULE_INFO(retpoline, "Y");
 
 static const struct modversion_info ____versions[]
 __used __section("__versions") = {
+	{ 0x1000e51, "schedule" },
+	{ 0x8c26d495, "prepare_to_wait_event" },
 	{ 0x92540fbf, "finish_wait" },
 	{ 0xf0fdf6cb, "__stack_chk_fail" },
+	{ 0x4dfa8d4b, "mutex_lock" },
 	{ 0x167e7f9d, "__get_user_1" },
 	{ 0xe2964344, "__wake_up" },
 	{ 0xc3aaf0a9, "__put_user_1" },
@@ -45,7 +48,6 @@ __used __section("__versions") = {
 	{ 0x6bc3fbc0, "__unregister_chrdev" },
 	{ 0xecc78457, "kobject_put" },
 	{ 0x73895700, "__register_chrdev" },
-	{ 0x122c3a7e, "_printk" },
 	{ 0xeb233a45, "__kmalloc" },
 	{ 0xfb890f0b, "class_create" },
 	{ 0x41b15bc9, "device_create" },
@@ -58,16 +60,16 @@ __used __section("__versions") = {
 	{ 0x5b8239ca, "__x86_return_thunk" },
 	{ 0x3c3ff9fd, "sprintf" },
 	{ 0xab632ed, "module_put" },
+	{ 0x122c3a7e, "_printk" },
 	{ 0x47143bb3, "try_module_get" },
 	{ 0x8470dec7, "pcpu_hot" },
+	{ 0x3213f038, "mutex_unlock" },
 	{ 0xe2c17b5d, "__SCT__might_resched" },
 	{ 0xfe487975, "init_wait_entry" },
-	{ 0x1000e51, "schedule" },
-	{ 0x8c26d495, "prepare_to_wait_event" },
 	{ 0x76800044, "module_layout" },
 };
 
 MODULE_INFO(depends, "");
 
 
-MODULE_INFO(srcversion, "FC2D859DF4303E84366E606");
+MODULE_INFO(srcversion, "D65D0B5D00F7B86A769F376");