Sebuah timerfd Linux menjadi readable ketika timer yang dikonfigurasi mengalami ekspirasi. Byte yang dikembalikan oleh read(2) bukan timestamp atau event record: nilainya mengodekan satu integer unsigned 64-bit yang berisi jumlah ekspirasi sejak successful read sebelumnya. State timer dengan demikian masuk ke mekanisme readiness yang sama dengan socket dan pipe, sementara semantik khusus timer tetap berada di balik batas descriptor.
Readiness merepresentasikan hitungan ekspirasi tertunda
timerfd_create(2) membuat descriptor yang terkait dengan sebuah clock, sedangkan timerfd_settime(2) mengaktifkan atau menonaktifkan timer. Setelah setidaknya satu ekspirasi tertunda, poll(2), select(2), dan epoll(7) dapat melaporkan descriptor sebagai readable.
read(2) yang berhasil memerlukan buffer yang cukup untuk nilai unsigned 64-bit. Operasi itu mengembalikan akumulasi jumlah ekspirasi dan mengonsumsi hitungan tertunda. Timer periodik yang ditangani terlambat dapat mengembalikan nilai lebih besar dari satu. Menganggap setiap notifikasi readable sebagai tepat satu interval akan membuang informasi yang dipertahankan kernel.
Perbedaan ini penting dalam event loop. Readiness menyatakan bahwa sebuah hitungan dapat dikonsumsi; readiness tidak menyatakan bahwa tepat satu deadline baru saja terjadi. Jika pemrosesan tertahan selama lima periode, read berikutnya dapat melaporkan kelima ekspirasi tersebut sekaligus.
Pilihan clock menentukan domain waktu
Clock yang diberikan ke timerfd_create(2) merupakan bagian dari kontrak timer. CLOCK_MONOTONIC bergerak secara monoton dan tidak terpengaruh perubahan wall clock yang diskontinu. CLOCK_REALTIME merepresentasikan waktu sistem dan dapat berubah ketika clock tersebut disetel ulang. Linux juga menyediakan pilihan clock terkait semantik suspend dan alarm jika didukung dan diizinkan.
Tanpa TFD_TIMER_ABSTIME, ekspirasi awal bersifat relatif terhadap nilai saat ini dari clock yang dipilih. Dengan flag tersebut, nilai ekspirasi ditafsirkan sebagai nilai absolut dalam domain clock yang dipilih. Timer absolut berbasis CLOCK_REALTIME karena itu sengaja terkait dengan penyesuaian wall clock, berbeda dari timer relatif berbasis CLOCK_MONOTONIC.
Untuk real-time clock yang didukung, TFD_TIMER_CANCEL_ON_SET dapat digabungkan dengan timer absolut. Perubahan clock diskontinu yang memenuhi syarat kemudian dapat membuat read(2) gagal dengan ECANCELED. Kondisi ini bergantung pada pilihan clock, mode absolut, flag pembatalan, dan perubahan clock; kondisi tersebut bukan properti umum timer monotonik.
Timer periodik mempertahankan overrun sebagai hitungan
Interval pada struct itimerspec membuat timer berjalan periodik setelah ekspirasi awal. Ekspirasi yang belum dibaca terakumulasi pada counter yang dikembalikan descriptor, tanpa memerlukan satu objek event user-space untuk setiap periode.
Perilaku tersebut memisahkan cadence penjadwalan dari cadence consumer. Consumer yang terlambat dapat memproses setiap tick logis yang terlewat, menggabungkan pekerjaan, atau langsung memajukan state berdasarkan hitungan yang dilaporkan. Descriptor tidak memaksakan salah satu kebijakan tersebut. Beberapa ekspirasi dapat menyatu menjadi satu observasi readiness, sedangkan read berikutnya tetap mengekspos jumlahnya.
TFD_NONBLOCK mengubah I/O saat state kosong: ketika tidak ada ekspirasi tertunda, read(2) gagal dengan EAGAIN alih-alih menunggu. TFD_CLOEXEC menetapkan close-on-exec saat pembuatan dan memengaruhi pewarisan descriptor, bukan perilaku timer. Flag descriptor ini terpisah dari clock dan itimerspec yang mendefinisikan perilaku timer.
Rekonfigurasi mengganti state satu timer
Pemanggilan timerfd_settime(2) mengonfigurasi ulang timer yang terkait dengan descriptor. Ekspirasi awal bernilai nol menonaktifkannya; interval bukan nol mengendalikan ekspirasi periodik setelah ekspirasi awal berikutnya. Argumen old-value opsional melaporkan konfigurasi timer sebelumnya, tetapi tidak membentuk transaksi dengan descriptor lain atau state aplikasi yang tidak terkait.
Jika beberapa komponen berbagi satu timer descriptor dan masing-masing melakukan rearm, rekonfigurasi terakhir mengendalikan satu timer kernel tersebut. Descriptor adalah satu objek timer, bukan registry deadline multi-client. Kepemilikan pada level aplikasi harus memperhitungkan perilaku penggantian ini.
Menempatkan timer dan socket dalam satu set epoll juga tidak menciptakan stream dengan ordering global di antara sumber kernel yang independen. Mengonsumsi hitungan timer pun tidak menyinkronkan memori yang dibagi dengan thread lain. timerfd mendefinisikan perilaku timer dan descriptor, bukan memory ordering pada level bahasa.
Batasnya lebih sempit: state timer Linux menjadi state I/O yang dapat dipoll, jumlah ekspirasi tetap tersedia setelah konsumsi yang terlambat, dan semantik clock tetap eksplisit. Sistem berorientasi descriptor dapat mengintegrasikan deadline ke readiness loop yang sudah ada sambil tetap memegang tanggung jawab atas kebijakan penjadwalan, sinkronisasi, dan pilihan clock.