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");