Re: real-time process

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>>>>> "Jan" == Jan Hudec <bulb@ucw.cz> writes:

Jan> On Thu, Oct 17, 2002 at 04:54:07PM +0300, Momchil Velikov wrote:
>> >>>>> "Momchil" == Momchil Velikov <velco@fadata.bg> writes:
>> 
>> >>>>> "Nagaraj" == Nagaraj  <nagaraj@smartyantra.com> writes:
Momchil> FWIW, the problem is the classic producer-consumer problem with
Momchil> solutions described in _any_ OS textbook.

Jan> No, it probably isn't. I expect that the camera is giving frames at
Jan> constant rate and the video encoder wants to grab the latest if it's
Jan> completed, but does not care when it missed some.

Does it make any difference if the camera or the encoder misses a
frame ?  If not (and I think not) it is exactly a producer/consumer
problem, where the produces simply stop producing when there are no
buffers available, i.e. misses a frame.  Note that it is also better
for the camera to miss a frame, because the frame data does not enter
the computer at all, thus it does not spend bus bandwith, memory
bandwith, caches, whatever, etc., all or any of them.

Momchil> Thus, the right solution would be to use semaphores.  But, AFAIK,
Momchil> there are no semaphores shared between the userspace and the kernel.

Jan> This is rather oversimplified. That any OS textbook will tell you, that
Jan> all the synchronization primitives are equivalent.

Which synchronization primitives are equivalent ? Is a barrier
equivalent to a condition variable ? Or one of them is not a
synchronization mechanism ?

True, everything can be implemented with mutexes and conditions, but
anyone in the real world has to consider the quality of implementation
issues too.

For example native semaphores are never of lower performance than
mutex/cond implementantion (otherwise they would be implemented with
mutex/cond).  It is not at all accidentally that POSIX has separate
semaphore primitives.  Just think of a broadcast on a condition
variable and how all the woken up processes IN TURN lock the mutex,
polluting the mutex cache line, which begins wildly bouncing back and
forth between CPUs.  A semaphore post operation can be implemented
WITHOUT ANY WRITES to the semaphore if there are waiters.  You can't
get much more scalable.

Jan> The sigwait mechanizm should actually be correct synchronization.

Jan> Having POLLIN on the descriptor iff a complete buffer is ready would be
Jan> better.

Momchil> Probably futexes can do the work.

Jan> Why when character devices already are perfect message queues?

Character devices are for I/O. ABUSING them for concurrency control
can be justified ONLY when there are no other primitives of adequate
performance.

>> Alternatively (and better),

Jan> Don't agree with better. It adds more ioctl crap. It would be
Jan> better if it was poll instead of ad-hoc ioctl.

IOCTLs are crap, true.

Jan> But yes, mmap has advantage being no-copy.

That's what I mean by "better".  

Jan> I still don't like the ioctls for synchronization, since the pocess has
Jan> to also poll for the network to accept the data. And this would force it
Jan> to have a helper thread just because it does not integrate with poll.

Hmm, how come that the MPEG encoder has to poll the network on the
read side ?

[snip]

>> Have the driver allocate 2 buffers and mmap() them into the process.
>> Have the driver create 2 semaphores (initially zero) and let the app
>> post and wait on them with ioctls.
>> 
>> void *buf[2];
>> 
>> buf [0] = mmap (fd, ...);
>> buf [1] = buf [0] + HALF_BUFFER_SIZE; /* GCC extension :) */
>> 
>> no = 0;
>> while (!done ())
>> {
>> /* Let the driver know a buffer is available. DMA starts
>> if not started already.  */
>> ioctl (fd, POSTSEM_0);
>> /* Wait until DMA interrupts and the interrupt handler signals the
>> semaphore.  Driver continues filling the other buffer.  */
>> ioctl (fd, WAITSEM_1);
>> 
>> /* Data is in buffer, no copying needed.  */
>> do_stuff (buf [no]);
>> 
>> /* Switch buffers.  */
>> no = !no;   
>> }


Jan> You seem to have the semaphores wrong.

I DON'T THINK SO.

Can you describe a scenario where the system would deadlock ? Or you
just do not understand the above pseudocode ?

Here's the driver sequence of actions:

sem_wait (SEM_0);

fill_buffer (0);
sem_post (SEM_1);

fill_buffer (1);
sem_post (SEM_1);

no = 0;
while (!done ())
{
  sem_wait (SEM_0);
  fill_buffer (no);
  sem_post (SEM_1);
  no = !no;
}

See ?

[irrelevant textbook example snipped]

Jan> But that is proper solution for producer-consument. This is NOT
Jan> producer-consument.

See above. It is.

>> One can add buffers to compensate for jitter. On a real-time OS two
>> buffers ought to be enough.  Ok ?

Jan> That's drivers choice! Driver allocates them (event here).

The only need for more than two buffers is to compensate for
scheduling delays in the consumer.

~velco
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux