Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 May 1996 16:18:40 -0700 (MST)
From:      Terry Lambert <terry@lambert.org>
To:        eeg@telecom.at (Franz Hollerer)
Cc:        freebsd-questions@freebsd.org
Subject:   Re: realtime processes
Message-ID:  <199605062318.QAA22134@phaeton.artisoft.com>
In-Reply-To: <199605061850.UAA52374@pina1> from "Franz Hollerer" at May 6, 96 08:49:33 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> Please, can someone tell me if the following may work:
> 
> rtprio(.....);                    /* realtime scheduling priority */
> set_rts();                       /* set rs232c rts output */
> usleep(10000);              /* sleep between 10 and 20ms */
> outp_rs232(....);            /* output a string to rs232 and wait */
>                                       /* until the whole string is */
>                                       /* send */
> usleep(10000);              /* sleep between 10 and 20ms */
> res_rts();                       /* reset rs232c rts output */
> rtprio(.....);                    /* normal scheduling priority */
> 
> I have same questions referring to the above code fragment and I
> hobe that someone will  answer this questions.
> 
> 1) Can I trust the scheduler that my process will get the CPU
>     between 10 and 20ms?

When you call usleep(), you tell the machine to voluntarily prempt
your process pending a wakeup event.

When the wakeup occurs, your process sits at the front of the ready
to run queue because of the rtprio (behind any "higher priority" RT
processes).

When you voluntarily cede the processor, you are only guaranteed
to run the next time the ready to run queue is checked.  This will
not include any time up to 9999 uS (9.999 mS), before your process
is back on the run queue.

If the process that runs following your process ceding the processor
takes up 9.998 ms, then another process will be pulled off the ready
to run queue before your process is inserted at the queue head.

Effectively, this means that the other process can run up to its full
process qunatum (20ms) before it is involuntarily preeempted by the
timer (what used to be called LBOLT, and what *I* still call LBOLT).

Effectively, this means your wait will be:

10,000uS (min) - 29,999uS (max).

Which is whatever delay you ask for plus one process quantum.


This is because there is no concept of kernel multithreading and
therfore no concept of kernel preemption; thus when your timer
expires, the non-"RT" process running at the time is not
involuntarily context switched out in favor of your "RT" process.

Part of this is just kernel programming that hasn't been done,
and part of it is the basically bogus timer code that would allow
for an RT oneshot event to cause preemption: the system clock
uses the high resoloution interrupt timer, so it's not free for
use for a one-shot.  To fix this, HZ would need to go to 64 (or,
according to some people, the off-board RTC's can go to 128),
freeing the system clock for a reschedulable one-shot with queue
pending decrements and time-ordered insertion.


None of this helps for *real* deadlining, which needs to include
the run time and the queue adjust time (varies on number of queue
entries) for the one-shot.  Even then, scheduling would need to
subtract out the time to execute from the interval time to give
you *real* RT capability -- so you would need to predict code
path, probably by definiting a two stage scheduler for the
oneshot and then scheduling again based on the event ID do that
all events deadline to the same time.  That would actually
be a user space RT event handler issue.


Why do you think you need such fine control?


> 2) Output to RS232:
>     I'm of the know of a system call which waits for output to drain.
>     But normally this system call waits 100ms or more after the
>     last character. I would need 10ms. Is this
>     possible?

This is to allow processing in the target devices recieve buffer to
take place before a signal state change wich could cause a buffer
flush to occur.  Typically this is only for DCD/DTR processing,
though because of FIFO's, this could be done on *input* processing
on UART's as well.

Potentially, if it's an input case, you could disable FIFO'ing and
replace it with "get interrupt ... poll like hell until 10ms of
no activity".  This is sort of how some of the old BerkNet transport
level code worked in earlier SunOS versions.  I don't recommend it.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199605062318.QAA22134>