>>>>> "Nagaraj" == Nagaraj <nagaraj@smartyantra.com> writes: >> Why the "blocking call" variant performed so poorly ? Nagaraj> i told it in prev mails..( READ THEM WELL ! ) Nagaraj> look at the sequence: suppose u do a blocking write, Nagaraj> probably the driver does interruptible_sleep_on() Nagaraj> and waits for irq_handler() wake it up. Nagaraj> When data xfer is complete, irq_handler wakes it up. Nagaraj> NOTE: Now the xfer is stopped. then blocking write returns to application Nagaraj> THEN application starts filling in the data into the buffer ( Time reqd to Nagaraj> fill in Nagaraj> the buffer ). Then again driver calls write. Nagaraj> This fill time of application is goin to screw up ur display. Nagaraj> as xfer is in terms of Mbits even small delay means large data. Nagaraj> So idea is if u can make use of multiple buffers, Nagaraj> make write non blocking. when device xfers from Nagaraj> first buffer...( DMA does it, so CPU neednt worry ) Nagaraj> fill in next buffers simulteneously. When xfer is complete Nagaraj> DMA gives control to irq_handler, which sets up the next Nagaraj> DMA and also kill_fasync() the application. So the delay between Nagaraj> two DMA xfers is just the interrupt latency. ( which would be around 100us Nagaraj> max ) Ok, I understand the task and I must say there is a problem with the described solution. Nagaraj> for( buff_index = i = 0; i < xfer_count; i++, buff_index = Nagaraj> (buff_index+1)%MAX_BUFFERS ) { Nagaraj> sleep(1000); Nagaraj> read( buff_fd, (mbuff +buff_index*BUFF_SIZE), BUFF_SIZE ); Nagaraj> } First, the above code has a race condition, which can add up to 1000 sec (!) latency per frame! Second, there's no need for multiple buffers in the application as it copies only one buffer at a time. Multiple buffers are needed inside the driver, so it can fill some buffers, which the application empties other buffers by copying them to the application's own buffer. Sleeping with ``sleep'' (or ``usleep'' or ``nanosleep'' for that matter) is not an adequate solution. The right way would be to block with ``sigwait. int signo; sigset_t set; sigprocmask (SIG_SETMASK, 0, &set); sigaddset (&set, SIGIO); /* or SIGwhatever */ sigprocmask (SIG_SETMASK, &set, 0); sigfillset (&set); sigdelset (&set, SIGIO); configure_number_of_driver_buffers_and_kick_it_to_start_xfer (); for (i = 0; i < xfer_count; i++) { sigwait (&set, &sig); /* Read the buffer. After the driver finishes copying into the user buffer, it knows the driver's buffer is available. */ read (buff_fd, mbuff, BUFF_SIZE); do_something (mbuff); } Isn't that code better ? Or I have misunderstood the problem ? Or I have understood the problem, but produced a crap myself ? :) ~velco -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/