Die plötzliche Erwähnung von hochpräzisen Timern verwirrt mich zumindest. Und wenn man es wörtlich nimmt, ist es ganz einfach, wenn der Timer weniger präzise ist. Das ist zwar schon alles, aber es geht nur um ein paar andere Details.
Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen. Bevor wir anfangen zu reden, schärfen wir zuerst seine Werkzeuge:
2 Mehrere zugehörige Quellcodedateien und ihre Pfade lauten wie folgt:
Hrtimers.txt(linux-3.2.12documentationtimers)
Hrtimer.c(linux-3.2.12kernel)
Hrtimer.h(linux-3.2.12includelinux)
2 Betreiben Sie den Hochpräzisions-Timer einfach im Hochpräzisions-Timer-Modus. Der gesamte Betriebsrahmen ist wie folgt:
Initialisieren Sie hrtimer_init, legen Sie relevante Daten wie Zeitdauer usw. fest. -> Schalten Sie den Timer hrtimer_start ein-> Führen Sie den Interrupt aus, rufen Sie die Interrupt-Rebound-Funktion auf. hrtimer_interrupt-> Hochpräziser Timer entfernen_hrtimer.
Die Leser haben jetzt einen Rahmen im Kopf und die spezifischen Treiberdetails werden im Folgenden einzeln besprochen.
Lassen Sie uns zunächst einen Überblick geben. Es kann sein, dass es einige unangenehme Dinge gibt, die schwer zu verstehen sind. Es wird keine Rolle spielen, ob es relevant ist.
? Hochpräziser Timer sortiert auf einem schwarz-roten Baum nach Zeit.
? Sie sind unabhängig vom Periodentakt Linux-Anwendungstimer und verwenden Pulsbreiten-Zeitstempel anstelle von Sekundenschnelle-Zeitdimensionen.
Nehmen Sie zunächst die Dokumentation zu hochpräzisen Timern im Linux-Code heraus und werfen Sie einen Blick auf die Einführung. Ich werde sie später erklären, den Dokumentpfad: Hrtimers.txt (linux-3.2.12documentationtimers)
Der Inhalt des Dokuments ... Ehrlich gesagt ist das Dokument etwas lang, aber die Wartung von Linux-Dokumenten ist nicht sehr hoch. Ich habe ein paar Sätze aus dem oben Gesagten gefunden, sie übersetzt und sie dann erklärt:
?Dieser Patch führt ein neues Subsystem für hochauflösende Kernel-Timer ein. Der Ausdruck „Patch“ in diesem Satz bedeutet, dass hochpräzise Timer als Patch-Paket im System installiert sind.
Der zweite Punkt ist zu lang, weshalb wir einen hochpräzisen Timer verwenden müssen. Die Genauigkeit ist im Vergleich dazu nicht hoch wird als Timer mit geringer Genauigkeit bezeichnet. Um es ganz klar auszudrücken: Es ist hohe Präzision erforderlich.
?Dritter Punkt: Ein weiteres Merkmal des hochpräzisen Timers besteht darin, dass sein Framework beim Kompilieren im Kernel liegt. Wenn der hochpräzise Timer nicht konfiguriert ist, basiert ein solcher hochpräziser Timer auf einem normalen Timer.
?Letzter Punkt: Der hochpräzise Timer wird mithilfe des Black-Mangrove-Algorithmus implementiert, während der normale Timer mithilfe des Time-Round-Robin-Algorithmus implementiert wird.
?Darüber hinaus erläutert das Dokument auch viele Probleme wie Taktquelle, Datenstruktur, Rot-Schwarz-Baum usw. Diese Probleme werden im Folgenden separat erörtert.
1. Verwandte Datenstrukturen
Struktur data yang terlibat dalam pemasa kadar bingkai tinggi, kami mempertimbangkan dari aspek berikut:
Mengenai sumber: Bagaimana jam ini berasal? Struktur ditakrifkan dalam hrtimer.h, kodnya adalah seperti berikut:
structhrtimer_clock_base{
structhrtimer_cpu_base*cpu_base;
intindex; //Atribut yang digunakan untuk membezakan jam (terdapat dua jenis secara keseluruhan, yang akan disebutkan di bawah)
clockid_tclockid; // ID jam yang disokong oleh setiap CPU
structtimerqueue_headactive;//Nod cawangan hitam dan merah pemasa didayakan
ktime_tresolution;//Kadar bingkai jam, milisaat
ktime_t(*get_time)(void);//Digunakan untuk memulihkan jam semasa
ktime_tsoftirq_time;//Masa untuk menjalankan baris gilir pemasa ketepatan yang luas dalam gangguan lembut
ktime_toffset;//Tukar jumlah offset jam pemasa
};
Mengenai elemen sebelum ini, sila jelaskan beberapa perkara.
Pemasa kadar bingkai tinggi boleh berdasarkan dua jam (dasar jam): satu ialah jam monotonik (CLOCK_MONOTONIC), yang bermula dari 0 apabila sistem bermula; Dalam struktur structhrtimer_clock_base di atas, elemen indeks digunakan untuk membezakan sama ada ia adalah jam CLOCK_MONOTONIC atau CLOCK_REALTIME. Untuk setiap CPU sistem, struktur data yang mengandungi dua pangkalan jam ini disediakan Setiap jumlah pangkalan jam mempunyai pokok merah hitam untuk mengisih semua pemasa ketepatan tinggi yang belum selesaipemasa aplikasi linux , dan setiap CPU menyediakan dua pangkalan jam (monotonik. jam dan masa nyata), dan semua pemasa diisih pada pokok merah hitam mengikut masa tamat Jika pemasa telah tamat tetapi fungsi lantunan pengendalinya masih belum dilaksanakan, maka Berhijrah daripada bakau hitam kepada tatasusunan. Apabila melaraskan jam masa nyata, akan terdapat ralat antara nilai masa tamat pemasa yang disimpan dalam jam CLOCK_REALTIME dan masa sebenar semasa. Tatasusunan offset membantu membetulkan situasi ini. Ia mewakili jumlah ofset yang perlu ditentukur oleh pemasa. Kerana ini hanya kesan sementara dan jarang berlaku.
Sebelum memahami sumber jam, kita juga mungkin perlu mengetahui structhrtimer struktur, kodnya adalah seperti berikut:
structhrtimer{
structtimerqueue_nodenode;//Nod baris gilir pemasa juga mengurus nod.expires Masa tamat tempoh mutlak pemasa ketepatan tinggi adalah dalam algoritma dalamannya ) .
ktime_t_softexpires;//Masa tamat tempoh paling awal mutlak
enumhrtimer_restart(*)(structhrtimer*);//Fungsi lantunan tamat tempoh pemasa
structhrtimer_clock_base*base;//Tangan menunjuk ke pangkalan masa (setiap CPU, setiap jam)
unsignedlongstate;//Maklumat status, digunakan untuk melihat nilai bit
#ifdefCONFIG_TIMER_STATS
intstart_pid; //Pid tugas yang mula pemasaan disimpan dalam kawasan statistik pemasa
void*start_site;//Pemasa menyimpan nilai permulaan semasa pemasa
charstart_comm[16];//Nama kawasan statistik pemasa memulakan proses penyimpanan pemasaan
#endif
};
Untuk struktur di atas, pengguna hanya perlu mengambil berat tentang tiga mata Yang pertama ialah fungsi rebound selepas pemasa tamat tempoh, yang mewakili masa tamat penggunaan struktur pemasa ketepatan tinggi mesti dimulakan oleh fungsi hrtimer_init() Fungsi hrtimer_init() tergolong dalam soket aplikasi, jadi ia disebut di atas. Terdapat satu lagi isu di sini, yang juga merupakan isu teras pemasa ketepatan tinggi, iaitu penggunaan bakau hitam dalam pemasa ketepatan tinggi Sebenarnya, agak awal untuk membincangkan perkara ini sekarang, dan biarkan pembaca mempunyai idea asas dahulu. Pemasa tradisional Linux Pemasa dilaksanakan melalui algoritma roda masa (timer.c), tetapi hrtimer dilaksanakan melalui algoritma bakau hitam. Terdapat medan nod pada structhrtimer, jenisnya ialah structtimerqueue_node Medan ini mewakili kedudukan hrtimer dalam pokok merah hitam Perhatikan bahawa kod sumber yang saya rujuk ialah versi 3.6.X, format ini medan ialah structrb_node. Izinkan saya bertanya khabar terlebih dahulu kepada pembaca.
Dua struktur penting telah selesai Kerana ia perlu serasi dengan pemproses berbilang teras, ia akan melibatkan asas masa setiap CPU Struktur structhrtimer_cpu_base digunakan untuk menentukan jam setiap CPU Jam monotonik dan jam masa nyata, strukturnya adalah seperti berikut:
structhrtimer_cpu_base{//Struktur asas masa CPU tunggal
raw_spinlock_tlock;//Kunci pangkalan masa dan pemasa yang berkaitan, kunci pembawa
unsignedlongactive_bases;//Tandai tatasusunan bit asas dengan pemasa aktif
#ifdefCONFIG_HIGH_RES_TIMERS
ktime_texpires_next;//Waktu mutlak masa seterusnya yang akan tamat tempoh
inthres_active; //Status mod kadar bingkai tinggi, pembolehubah Boolean
inthang_detected; // Gangguan pemasa ketepatan tinggi yang belum selesai dikesan
unsignedlongnr_events;//Jumlah gangguan pemasa ketepatan tinggi
unsignedlongnr_retries;//Jumlah percubaan semula gangguan pemasa ketepatan tinggi
unsignedlongnr_hangs;//Jumlah gangguan pemasa ketepatan tinggi terputus
ktime_tmax_hang_time;//Masa maksimum untuk gangguan pemasa ketepatan tinggi dicetuskan
#endif
structhrtimer_clock_baseclock_base[HRTIMER_MAX_CLOCK_BASES];//Jarum asas masa CPU ini
};
Tiga struktur di dalamnya hendaklah yang paling asas, mentakrifkan fungsi dan elemen yang berkaitan dengan pemasa ketepatan tinggi, dan setiap CPU mempunyai set lengkap struktur yang ditentukan, dan kemudian memulakan hrtimer.
Sekarang kita telah selesai bercakap tentang struktur asas, mari mula bercakap tentang soket API.
Yang pertama ialah mengkonfigurasi dan memulakan API hrtimer. Apabila kita bercakap tentang structhrtimer pada mulanya, kita menyebut bahawa untuk menggunakan structhrtimer, kita perlu memulakannya dahulu Kod pengisytiharan fungsi adalah seperti berikut:
voidhrtimer_init(structhrtimer*timer,clockid_tclock_id,
enumhrtimer_modemode)//Diberi pemasa permulaan jam
debug_init(pemasa, id_jam, mod);
__hrtimer_init(pemasa, id_jam, mod);
Fungsi di atas melaksanakan pemulaan pemasa ketepatan tinggi Berikut ialah penjelasan tentang elemen yang berkaitan:
/**
*hrtimer_init – Mulakan pemasa dengan jam yang diberikan
*@timer: Pemasa yang akan dimulakan
*@clock_id: Jam yang akan digunakan
*@mode: mod pemasa abs/rel
*/
mod boleh menggunakan lima pemalar, seperti berikut:
enumhrtimer_mode{
HRTIMER_MODE_ABS=0x0,/*Masa adalah mutlak*/
HRTIMER_MODE_REL=0x1,/*Masa adalah relatif*/
HRTIMER_MODE_PINNED=0x02,/*Pemasa terikat pada CPU*/
HRTIMER_MODE_ABS_PINNED=0x02,
HRTIMER_MODE_REL_PINNED=0x03,
};
Fungsi hrtimer_init() memanggil fungsi __hrtimer_init() Berikut ialah prototaip fungsi ini:
staticvoid__hrtimer_init(structhrtimer*timer,clockid_tclock_id,enumhrtimer_modemode)
structhrtimer_cpu_base*cpu_base;
intbase;
memsettimer,0,sizeof(structhrtimer));
cpu_base=&__raw_get_cpu_var(hrtimer_bases);
jika(id_jam==MASA_SEBENAR&&mod!=HRTIMER_MODE_ABS)
clock_id=JAM_MONOTONIK;
base=hrtimer_clockid_to_base(clock_id);
pemasa->base=&cpu_base->clock_base[base];
timerqueue_init(&timer->nod);
#ifdefCONFIG_TIMER_STATS
타이머->start_site=NULL;
타이머->start_pid=-1;
memset(timer->start_comm,0,TASK_COMM_LEN);
#endif
__hrtimer_init() 함수는 structhrtimer_cpu_base 구조를 호출하여 CPU를 초기화하고 memset() 함수를 사용합니다.
void*memset(void*s,intc,size_tn)
인티;
문자*ss=s;
for(i=0;i ss[i]=c; 반품; 이 함수는 메모리 내용을 지우고 memset(timer,0,sizeof(structhrtimer)) 초기화를 완료합니다. 여기서 언급한 문제는 여전히 문제입니다. 제가 사용한 소스코드는 3.2.12이고, 2.6.X에서 제공하는 소스코드에는 상수가 2개뿐입니다
Das obige ist der detaillierte Inhalt vonRelevante Einführung und Betriebsrahmenanalyse hochpräziser Timer. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!