Dowiedziałem się o blokujących funkcjach wejścia/wyjścia do pisania sterownika urządzenia linux i zastanawiam się, jakie jest użycie ERESTARTSYS
. Rozważmy następujący:Do czego służy ERESTARTSYS podczas pisania sterownika Linux?
zmienna globalna:
wait_queue_head_t my_wait_q_head;
int read_avail = 0;
device_init():
init_waitqueue_head(&my_wait_q_head);
device_read():
printk("I'm inside driver read!\n");
wait_event_interruptible(&my_wait_q_head, read_avail != 0);
printk("I'm awaken!\n");
device_write():
read_avail = 1;
wake_up_interruptible(&my_wait_q_head);
Kiedy wezwać read()
z przestrzeni użytkownika, w wierszu polecenia powiesić aż nazywam write()
zgodnie z oczekiwaniami. Komunikaty printk
pojawiają się odpowiednio również w dmesg
. Jednak widzę niektóre sterowniki napisane tak:
Inna wersja device_read():
printk("I'm inside driver read!\n");
if(wait_event_interruptible(&my_wait_q_head, read_avail != 0))
{return -ERESTARTSYS;}
printk("I'm awaken!\n");
Testowałem drugą wersję device_read()
przy użyciu tej samej metody w przestrzeni użytkownika, a wynik jest dokładnie taki sam, więc jaki jest pożytek z ERESTARTSYS?
p/s: Czytałam książkę Linux sterowników urządzeń na ten temat, ale ja nie rozumiem, może ktoś podać przykład do eleborate ?:
Po ominąć tej rozmowy coś obudziła nas, ale nie wiemy, co to jest . Jedną z możliwości jest to, że proces otrzymał sygnał. Instrukcja if, która zawiera wait_event_Anterruptible call, sprawdza w tym przypadku . To stwierdzenie zapewnia prawidłową i oczekiwaną reakcję na sygnały, które mogły być odpowiedzialne za pobudzanie procesu (ponieważ byliśmy w przerywanym śnie). Jeśli nadejdzie sygnał i nie został zablokowany przez proces, właściwym zachowaniem jest zezwolenie górnej części jądra na obsługę zdarzenia. W tym celu do sterownik zwraca -ERESTARTSYS do dzwoniącego; ta wartość to używana wewnętrznie przez warstwę wirtualnego systemu plików (VFS), która albo restartuje wywołanie systemowe, albo zwraca -EINTR do przestrzeni użytkownika. Używamy tego samego rodzaju sprawdzania, aby poradzić sobie z obsługą sygnałów dla każdego zapisu i implementacji zapisu .
Źródło: http://www.makelinux.net/ldd3/chp-6-sect-2
@Noge: Aby zobaczyć różnicę, wyślij procesowi sygnał po wywołaniu 'read()', a przed wywołaniem 'write()'. – caf