X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fkernel%2Fsamples%2Fworkqueue%2F.git;a=blobdiff_plain;f=block_wq.c;fp=block_wq.c;h=ae6d8abf8b38a7b2aa13eb98f58f9a363535971d;hp=0000000000000000000000000000000000000000;hb=271a17e550236d7cfc14385a1b20f692e23de0af;hpb=22ee84b81b928deceb560578b1ff40bbcc7a6a0f diff --git a/block_wq.c b/block_wq.c new file mode 100644 index 0000000..ae6d8ab --- /dev/null +++ b/block_wq.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010 Thadeu Lima de Souza Cascardo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * This code demonstrates why a work should not block for too long. + * This is worse in the case that the work is scheduled in keventd. + */ + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Thadeu Lima de Souza Cascardo"); + +static void work_block(struct work_struct *work) +{ + unsigned long tmp = jiffies + 5 * HZ; + printk(KERN_INFO "Blocking other works in the queue\n"); + printk(KERN_INFO "Executing task in CPU %d\n", smp_processor_id()); + /* We also kick the CPU high */ + while (!time_after(jiffies, tmp)) + cpu_relax(); +} + +static void work_print(struct work_struct *work) +{ + printk(KERN_INFO "Phew! That was waiting!\n"); + printk(KERN_INFO "Task done in CPU %d\n", smp_processor_id()); +} + +static struct workqueue_struct *block_wq; +static DECLARE_WORK(block_work, work_block); +static DECLARE_WORK(print_work, work_print); + +static int block_wq_init(void) +{ + block_wq = create_workqueue("block_wq"); + if (!block_wq) + return -ENOMEM; + printk(KERN_INFO "Queueing task in CPU %d\n", get_cpu()); + put_cpu(); + queue_work(block_wq, &block_work); + queue_work(block_wq, &print_work); + return 0; +} + +static void block_wq_exit(void) +{ + destroy_workqueue(block_wq); +} + +module_init(block_wq_init); +module_exit(block_wq_exit);