View Single Post
Old 12-01-2005, 10:24   #16
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Demandare una operazione ad un altro contesto: i tasklet

Le workqueue sono utili per la maggior parte delle operazioni. Vengono eseguite con priorità molto alta (nice -10).
Se avete bisogno di un work da eseguire con priorità VERAMENTE alta, potete utilizzare i tasklet. Occorre però rinunciare a qualcosa: i tasklet sono eseguiti in contesto di irq (softirq), quindi c'è qualche limitazione.
Questi link descrivono sinteticamente i tasklet e lo scopo delle bottom half in generale:
http://www.opentech.at/papers/embedd...ces/node8.html
http://www.cs.utexas.edu/users/ygz/3...lecture11.html

L'uso è molto simile alle workqueue:
Codice:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/interrupt.h>
#include <linux/delay.h>

static struct task_struct *ktask;

static void kt_tasklet(unsigned long data)
{
	printk(KERN_INFO "%s\n", __func__);
}

static DECLARE_TASKLET(tlet, kt_tasklet, 0);

static int kt_thread(void *arg)
{
	while (!kthread_should_stop()) {
		tasklet_schedule(&tlet);
		msleep(1000);
	}
	return 0;
}

static int __init kt_init(void)
{
	
	ktask = kthread_create(kt_thread, NULL, "kthread");
	if (IS_ERR(ktask))
		return PTR_ERR(ktask);
	else
		wake_up_process(ktask);
	return 0;
}

static void __exit kt_exit(void)
{
	kthread_stop(ktask);
	tasklet_kill(&tlet);
}

module_init(kt_init);
module_exit(kt_exit);

MODULE_AUTHOR("ilsensine");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("sample kernel process");
Note:
- Per disabilitare i tasklet sulla cpu corrente, occorre disabilitare i softirq. Questo avviene tramite le funzioni local_bh_disable. Per sincronizzare da contesto di processo con un tasklet, il lock da usare è spin_lock_bh in contesto di processo e spin_lock in contesto di softirq (dentro il tasklet). La guida sul locking linkata in precedenza ne parla.
- Non esiste un equivalente di flush_workqueue per i tasklet. Utilizzare tasklet_kill.
- L'oggetto tasklet_struct deve essere ancora vivo alla fine del tasklet, quindi non possiamo usare il trucco con il kfree utilizzato con le workqueue.
- Possono essere allocati nuovi softirq, al pari di nuove workqueue. Il loro uso è fortemente scoraggiato. I tasklet non sono però workqueue, anche se ingannevolmente simili; vanno trattati con la dovuta cautela.
- Il contesto softirq può essere interrotto solo da un hardirq.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12

Ultima modifica di ilsensine : 23-02-2006 alle 16:02.
ilsensine è offline