Apa motivasi dari kondisi ini void serial8250_tx_chars(struct uart_8250_port *up)
?
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
Sudah ada sejak Linux 1.1.13 (Mei 1994) dan berulang di sebagian besar driver UART.
Latar Belakang: Linux 3.4.91 yang dikustomisasi, sistem tertanam pada ARMv7, port UART 0 dikonfigurasi untuk 38400 baud, FIFO 16 byte untuk i / o. Semua ini tidak dapat diubah di pengaturan kami.
Ketika printf-ing sangat berat pada konsol melalui UART, internal 4KB-buffer ( UART_XMIT_SIZE
) mengisi dan kemudian warung proses user-space sampai buffer dikosongkan (yang membutuhkan waktu satu detik di 38.400 baud!). Kemudian perilaku ini berulang. Ini karena fungsi n_tty_write()
tidur ketika buffer penuh, dan tidak terbangun untuk waktu yang lama karena kondisi yang dipertanyakan di atas.
Saya akan merasa lebih alami dan efisien jika pemeriksaan ini dihapus begitu saja. Kemudian printfs akan mengisi buffer secepat yang mereka bisa, dan kemudian melanjutkan dengan kecepatan di mana buffer sedang dikosongkan , daripada pemrosesan meledak yang saya amati.
Ini berfungsi dengan baik di lingkungan saya, tetapi tentu saja saya kehilangan atau salah paham akan sesuatu. Pasti ada alasan untuk implementasi saat ini. Apakah ada efek samping jika saya menghilangkan kondisi itu?
Sebagai pertanyaan sampingan: apakah ada opsi konfigurasi untuk menyesuaikan perilaku ini, mis. Agar printf selalu kembali segera dan membuang output jika buffer penuh?
Jawaban:
Ini ukuran efisiensi. CPU berjalan jauh lebih cepat daripada port serial sehingga jika kernel membiarkan proses userspace berjalan setiap kali ada sedikit ruang di buffer, akhirnya akan melakukan perjalanan ke userspace dan kembali untuk setiap byte data tunggal. Itu sangat membuang waktu CPU:
Tes di atas bahkan tidak membaca dan menulis perangkat nyata: perbedaan waktu adalah seberapa sering sistem memantul antara ruang pengguna dan ruang kernel.
Jika userspace tidak ingin ditahan, ia dapat menggunakan I / O yang tidak menghalangi, atau dapat memeriksa menggunakan
select()
panggilan untuk melihat apakah ada ruang untuk menulis ke perangkat ... dan jika tidak, ia dapat membuang sisanya menjadi buffer sendiri dan melanjutkan pemrosesan. Memang, itu memang menyulitkan, karena sekarang Anda memiliki buffer yang harus Anda siram ... tetapi jika Anda menggunakan stdio, itu umumnya benar.sumber