Objek eventfd menyimpan counter unsigned 64-bit di kernel dan mengekspos state tersebut melalui file descriptor. Operasi write menambah counter dalam batas yang ditentukan; operasi read mengonsumsi state counter; antarmuka readiness menunjukkan apakah suatu operasi dapat berjalan tanpa blocking. Hasilnya adalah batas sinkronisasi ringkas yang cocok dengan event loop berbasis descriptor tanpa mengubah counter menjadi byte stream.

Antarmuka ini khusus Linux. Jaminannya berasal dari kontrak system call eventfd dan semantik descriptor kernel, bukan dari bahasa C atau POSIX.

Counter menjadi objek state bersama

Pemanggilan eventfd() membuat descriptor yang merujuk ke objek eventfd dengan nilai awal unsigned yang diberikan:

int fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);

Counter yang tersimpan memiliki nilai maksimum yang dapat dipakai sebesar UINT64_MAX - 1. Operasi write() dari userspace memasok tepat delapan byte yang ditafsirkan sebagai uint64_t. Penulisan UINT64_MAX tidak valid dan gagal dengan EINVAL.

Dalam mode eventfd biasa, write yang berhasil menambahkan nilai tersebut ke counter saat ini. Jika penambahan akan melewati nilai maksimum yang dapat dipakai, descriptor blocking menunggu sampai write dapat berjalan; descriptor dengan EFD_NONBLOCK gagal dengan EAGAIN.

Antarmuka ini bersifat aritmetis, bukan penyimpanan pesan. Dua write bernilai 3 dan 5 dapat menghasilkan state counter 8; objek tidak mempertahankan dua record yang dapat diakses secara terpisah.

Read biasa menukar state terakumulasi dengan nol

Tanpa EFD_SEMAPHORE, read() yang berhasil memindahkan nilai counter saat ini sebagai satu uint64_t delapan byte lalu mereset counter menjadi nol. Jika counter sudah nol, read blocking akan menunggu. Dalam mode nonblocking, operasi gagal dengan EAGAIN.

Operasi reset tersebut memberi reader jumlah notifikasi yang terakumulasi pada saat kernel menjalankan read. Writer konkuren dapat menambahkan state baru setelah read, sehingga nilai yang dikembalikan tidak dapat diperlakukan sebagai pernyataan permanen bahwa tidak ada event tambahan.

Ukuran transfer merupakan bagian dari kontrak API. Read yang lebih kecil dari delapan byte gagal dengan EINVAL; read yang berhasil mengembalikan delapan byte. Descriptor ini karena itu tidak memiliki perilaku partial-record seperti stream generik.

Mode semaphore mengubah konsumsi read

EFD_SEMAPHORE hanya mengubah aturan konsumsi pada sisi read. Saat counter bukan nol, setiap read yang berhasil mengembalikan nilai 1 dan mengurangi counter sebesar 1, bukan mengembalikan seluruh nilai terakumulasi lalu meresetnya menjadi nol.

Counter bernilai 4 dengan demikian memungkinkan empat read mode semaphore yang berhasil sebelum mencapai nol. Writer tetap menambahkan nilai unsigned dengan batas counter yang sama.

Mode ini dapat merepresentasikan unit ketersediaan, tetapi tidak menetapkan kepemilikan resource eksternal. Jika program mengaitkan satu unit counter dengan elemen queue atau permit, konsistensi di antara objek tersebut tetap menjadi invariant pada level aplikasi.

Readiness mengikuti operasi counter yang diizinkan

Descriptor eventfd bersifat readable ketika counter lebih besar dari nol. Descriptor bersifat writable ketika setidaknya nilai 1 dapat ditambahkan tanpa blocking. poll(), epoll, dan antarmuka multiplexing descriptor Linux terkait dapat mengamati state ini.

Readiness dengan demikian berasal dari state counter, bukan dari jumlah byte yang diantrekan. Notifikasi readable menyatakan bahwa read dapat mengonsumsi state counter; notifikasi itu tidak mengidentifikasi producer, mempertahankan batas write, atau mendeskripsikan work item eksternal.

Kondisi writable juga memiliki batas spesifik. Karena counter secara normal tidak dapat melampaui UINT64_MAX - 1, counter yang cukup penuh dapat memberi backpressure kepada writer. Sebagian besar desain koordinasi menjaga nilai jauh dari batas tersebut, tetapi batas itu tetap menjadi bagian dari perilaku API yang dapat diamati.

Duplikasi descriptor berbagi counter yang sama

Descriptor yang dihasilkan oleh dup(), diwariskan melalui fork(), atau dengan cara lain merujuk ke open file description yang sama mengakses objek eventfd dan counter yang sama. Read melalui salah satu descriptor tersebut mengubah state yang diamati melalui descriptor lainnya.

Hal ini relevan ketika beberapa consumer menunggu pada descriptor hasil duplikasi. Dalam mode biasa, satu reader dapat mengonsumsi nilai terakumulasi dan mereset counter bersama. Dalam mode semaphore, reader yang berhasil mengonsumsi unit satu per satu. Penjadwalan di antara thread yang bersaing terpisah dari jaminan aritmetis; API tidak mengubah descriptor hasil duplikasi menjadi counter independen.

EFD_CLOEXEC meminta close-on-exec secara atomik saat pembuatan. Flag ini mengendalikan pewarisan descriptor melewati execve() dan tidak mengubah semantik counter selama descriptor tetap terbuka.

Overflow counter memiliki kasus khusus yang berasal dari kernel

Write dari userspace tidak dapat secara langsung membuat counter overflow karena penambahan yang akan melewati maksimum normal akan blocking atau gagal. Linux juga mendokumentasikan kasus overflow khusus yang terkait dengan jumlah sangat besar eventfd signal post dari kernel AIO. Dalam state tersebut, poll() melaporkan kondisi readable sekaligus error, dan read mengembalikan UINT64_MAX.

Jalur khusus tersebut berbeda dari perilaku write() userspace biasa. Memperlakukan UINT64_MAX sebagai nilai counter normal akan menghapus batas terdokumentasi antara aritmetika reguler dan state overflow yang dilaporkan kernel.

Jumlah notifikasi bukan work queue

eventfd sesuai ketika fakta bersama yang perlu dikomunikasikan berupa jumlah berbatas atau kondisi wakeup. Antarmuka ini tidak membawa payload, identitas producer, metadata urutan, atau batas per-write. Properti tersebut harus berada pada struktur bersama atau protokol lain ketika aplikasi memerlukannya.

Salah satu desain yang umum memasangkan eventfd dengan state yang dimiliki secara terpisah: producer mengubah queue atau state machine, lalu menaikkan counter eventfd agar pekerjaan terlihat oleh consumer berbasis descriptor. Correctness tetap bergantung pada kontrak sinkronisasi yang melindungi state eksternal tersebut. Counter eventfd menyediakan notifikasi dan state aritmetis; counter itu tidak menggantikan aturan memory ordering, kepemilikan queue, atau invariant aplikasi.