Hi,
Ik zit met een klein probleempje.. Ik ben bezig een device driver voor linux te schrijven voor een character device. Er zijn bepaalde lezers die input kunnen lezen zodra schrijvers iets wegschrijven in het (virtuele device).
Echter wil ik graag dat lezers alleen input gaan lezen als dat er ook echt is, vandaar dat ik een completion gebruik, zodat een schrijver de lezers "wakker" maakt als er werkt te doen is.
Zo gezegd zo gedaan, kom je op het volgende stukje uit: (includes en inits daargelaten)
Een schrijver maakt nu alle lezers wakker als er iets geschreven wordt. Echter vervolgens gaat een lezer weer iets lezen, maar wacht hij niet meer op de completion.
Nu ben ik er al achtergekomen dat dit komt omdat je de completion opnieuw moet initialiseren, echter zit daar ook mijn probleem.
Zodra ik de completion opnieuw initialiseer nadat de schrijver een complete_all() gedaan heeft(zo dus):
krijgen mijn lezers niet meer het bericht dat ze verder mogen lezen.
Ik heb een beetje lopen zoeken op internet, maar er zijn maar weinig cases waar ik complete_all echt gebruikt zie worden, terwijl dit mij op deze plek wel de oplossing lijkt.
Kunnen jullie me vertellen waar/hoe ik mijn completion opnieuw moet initen, of dat ik toch maar beter een ander concurrency-hulpmiddel kan gebruiken?
Ik zit met een klein probleempje.. Ik ben bezig een device driver voor linux te schrijven voor een character device. Er zijn bepaalde lezers die input kunnen lezen zodra schrijvers iets wegschrijven in het (virtuele device).
Echter wil ik graag dat lezers alleen input gaan lezen als dat er ook echt is, vandaar dat ik een completion gebruik, zodat een schrijver de lezers "wakker" maakt als er werkt te doen is.
Zo gezegd zo gedaan, kom je op het volgende stukje uit: (includes en inits daargelaten)
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| #include <linux/completion.h> struct completion messagesAvailable; //voor lezers om te slapen als er geen berichten zijn /File operation functies int rn_open(struct inode *inode, struct file *filp){ return 0; } ssize_t rn_read(struct file *filp, char __user *userBuff, size_t count, loff_t *offp){ printk( KERN_INFO "waiting for: %p\n", &messagesAvailable ); wait_for_completion( &messagesAvailable); copy_to_user( userBuff, "b", 1); (*offp) += 1; return 1; } ssize_t rn_write(struct file *filp, const char __user *userBuff, size_t count, loff_t *offp){ complete_all( &messagesAvailable); printk( KERN_INFO "inited complete for: %p\n", &messagesAvailable ); return count; } //deze functies worden doorgelinked door gebruikers van het device struct file_operations fops = { .open = rn_open, .release = rn_release, .read = rn_read, .write = rn_write, }; // Module ingeladen door de kernel static int hello_init(void) { int result; printk( KERN_ALERT "Kernelmodule completion: init_module() \n" ); init_completion(&messagesAvailable); result = register_chrdev(0, "completion", &fops); if( result < 0) { printk(KERN_WARNING "Error creating device\n"); return result; } device = result; return 0; } |
Een schrijver maakt nu alle lezers wakker als er iets geschreven wordt. Echter vervolgens gaat een lezer weer iets lezen, maar wacht hij niet meer op de completion.
Nu ben ik er al achtergekomen dat dit komt omdat je de completion opnieuw moet initialiseren, echter zit daar ook mijn probleem.
Zodra ik de completion opnieuw initialiseer nadat de schrijver een complete_all() gedaan heeft(zo dus):
C:
1
2
| complete_all( &messagesAvailable); init_completion( &messagesAvailable ); |
krijgen mijn lezers niet meer het bericht dat ze verder mogen lezen.
Ik heb een beetje lopen zoeken op internet, maar er zijn maar weinig cases waar ik complete_all echt gebruikt zie worden, terwijl dit mij op deze plek wel de oplossing lijkt.
Kunnen jullie me vertellen waar/hoe ik mijn completion opnieuw moet initen, of dat ik toch maar beter een ander concurrency-hulpmiddel kan gebruiken?
[ Voor 11% gewijzigd door Enfer op 10-08-2010 17:51 ]