2014-05-18 20:07:58
Czy dysk się kręci?

Zaskakujące jest, że mimo wszechobecności laptopów, tak mało aplikacji działa na nich poprawnie. Koronnym przykładem owej niepoprawności jest świadome ignorowanie stanu zasilania poszczególnych komponentów, co (czasami bardzo) negatywnie odbija się na czasie pracy laptopa na baterii, np. gdy jakaś aplikacja nagle uznaje, że akurat 5 sekund po zatrzymaniu (talerzowego) dysku bezwzględnie potrzebuje wysrać pół tony plików tymczasowych albo zrobić pusty autozapis (tj. zapisać plik auozapisu w sytuacji, gdy tak naprawdę od ostatniego zapisu nic się nie zmieniło). Windows 2000 i nowsze dają możliwość określenia w jakim stanie zasilania jest dane urządzenie, m. in. do określenia czy dysk się kręci, można użyć funkcji GetDevicePowerState, która wcale nie jest trywialna, jeśli chodzi o poprawne używanie.

Oczywistym scenariuszem w którym można wykorzystać tę funkcję jest indeksacja w tle, zapis/odczyt niekluczowych danych lub operacje I/O które mogą poczekać. Wywołujemy GetDevicePowerState na uchwycie do dysku/katalogu/pliku i już wiemy, czy dysk się kręci czy nie. Jeśli nie i można sobie na to pozwolić, wychodzimy nic nie robiąc (w tym - nie rozpędzając dysku). Brzmi fajnie? To pora na haczyki. Nie można podać po prostu nazwy pliku/katalogu/dysku - trzeba podać uchwyt, a samo utworzenie uchwytu może spowodować operację I/O. Nie można też podać byle jakiej nazwy na konkretnym dysku, bo może zostać zwrócony błąd (gdyż np. plik faktycznie nie istnieje) i nie uzyskamy uchwytu. A jeśli podamy ścieżkę o której system nic nie wie (bo nie ma jej w cache'u katalogów), to wymusimy odczyt katalogu (i rozpędzenie dysku). Jedyna sensowna opcja w takim przypadku to otworzyć uchwyt do głównego katalogu, ale tego z kolei nie można zrobić "ot tak", w funkcji CreateFile jako jeden z argumentów należy podać FILE_FLAG_BACKUP_SEMANTICS (co, zgodnie z dokumentacją, nie musi skończyć się powodzeniem). Do tego, mimo że funkcja ta (tj. CreateFile) jest dostępna w każdym wydaniu Win32 API, to oczywiście nie zadziała pod Win9x, bo nie obsługuje rzeczonej flagi (inna sprawa, że Win9x nie ma w ogóle funkcji GetDevicePowerState, więc problem sam się rozwiązuje).

Z ciekawostek jakie wynikły podczas badania tematu - system zareaguje błędem "Nieprawidłowa funkcja" na takie zabawy na ramdyskach. :)

Po krótkich eksperymentach wyprodukowałem moduł z funkcją DiskSpinning, której podaje się dysk (w postaci ścieżki do głównego katalogu, np. "C:"), a która zwraca prawdę bądź fałsz w zależności od tego, czy wskazany dysk jest włączony czy nie. Jeżeli wystąpi jakikolwiek błąd albo funkcja GetDevicePowerState nie jest obsługiwana przez system, funkcja DiskSpinning zwraca prawdę. Przez chwilę myślałem czy takie podejście ma sens, ale uznałem, że jeśli ktoś weźmie sobie do serca to co funkcja zwraca, to mógłbym niechcący przyczynić się do posadzenia w czyimś kodzie niszczących dane bugów (gdy ktoś będzie zbyt długo zwlekał z zapisem, aż dane szlag trafi). ;)

Moduł z funkcją można pobrać z Branchware.


Może Cię zainteresować...

Link | Komentarzy: 17 | Programowanie, Tech, Techblog
Pokazuj komentarze.
Powered by:
Hellcore Mailer - polski program pocztowyOpera Web BrowserFreeBSD - The Power to Serve!Slackware
RSSy:
Sidekick:
Projekty:
O autorze:
Zobacz:
Kategorie:
Archiwum:
Szukaj: