Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.arch.embedded > #28994 > unrolled thread

Task priorities in non strictly real-time systems

Started bypozz <pozzugno@gmail.com>
First post2020-01-03 14:41 +0100
Last post2020-01-03 21:46 -0500
Articles 20 on this page of 74 — 15 participants

Back to article view | Back to comp.arch.embedded


Contents

  Task priorities in non strictly real-time systems pozz <pozzugno@gmail.com> - 2020-01-03 14:41 +0100
    Re: Task priorities in non strictly real-time systems David Brown <david.brown@hesbynett.no> - 2020-01-03 15:19 +0100
      Re: Task priorities in non strictly real-time systems pozz <pozzugno@gmail.com> - 2020-01-05 01:25 +0100
        Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-05 13:32 -0600
          Re: Task priorities in non strictly real-time systems Richard Damon <Richard@Damon-Family.org> - 2020-01-05 16:49 -0500
            Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-05 21:05 -0600
          Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-05 17:08 -0700
            Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-05 21:26 -0600
              Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-05 22:10 -0700
                Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-06 07:37 -0600
                  Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-06 17:21 -0700
                    Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-07 19:23 -0600
                Re: Task priorities in non strictly real-time systems Richard Damon <Richard@Damon-Family.org> - 2020-01-06 20:36 -0500
                  Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-07 01:38 -0600
                    Re: Task priorities in non strictly real-time systems Richard Damon <Richard@Damon-Family.org> - 2020-01-07 06:53 -0500
              Re: Task priorities in non strictly real-time systems George Neuner <gneuner2@comcast.net> - 2020-01-06 07:13 -0500
              Re: Task priorities in non strictly real-time systems David Brown <david.brown@hesbynett.no> - 2020-01-07 10:11 +0100
                Re: Task priorities in non strictly real-time systems Richard Damon <Richard@Damon-Family.org> - 2020-01-07 07:05 -0500
                Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-07 19:34 -0600
            Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-06 10:44 +0200
              Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-06 02:51 -0700
                Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-06 15:39 +0200
                  Re: Task priorities in non strictly real-time systems George Neuner <gneuner2@comcast.net> - 2020-01-06 13:29 -0500
                    Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-06 14:38 -0700
                    Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-07 07:05 +0200
                      Re: Task priorities in non strictly real-time systems George Neuner <gneuner2@comcast.net> - 2020-01-07 13:09 -0500
                        Re: Task priorities in non strictly real-time systems Dimiter_Popoff <dp@tgi-sci.com> - 2020-01-07 20:53 +0200
                          Re: Task priorities in non strictly real-time systems Clifford Heath <no.spam@please.net> - 2020-01-08 08:43 +1100
                            Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-08 00:33 +0200
                            Re: Task priorities in non strictly real-time systems Dimiter_Popoff <dp@tgi-sci.com> - 2020-01-08 15:26 +0200
                        Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-08 00:08 +0200
                    Re: Task priorities in non strictly real-time systems David Brown <david.brown@hesbynett.no> - 2020-01-07 10:37 +0100
                  Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-06 16:10 -0700
                    Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-07 07:37 +0200
                      Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-07 01:49 -0600
                      Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-07 06:43 -0700
                    Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-07 10:21 +0200
                      Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-07 06:42 -0700
                        Re: Task priorities in non strictly real-time systems Richard Damon <Richard@Damon-Family.org> - 2020-01-07 22:23 -0500
                          Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-09 22:07 +0200
                    Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-07 10:54 +0200
                      Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-07 06:43 -0700
            Re: Task priorities in non strictly real-time systems Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2020-01-06 18:01 +0100
              Re: Task priorities in non strictly real-time systems Niklas Holsti <niklas.holsti@tidorum.invalid> - 2020-01-06 19:47 +0200
      Re: Task priorities in non strictly real-time systems pozz <pozzugno@gmail.com> - 2020-01-05 01:58 +0100
        Re: Task priorities in non strictly real-time systems Clifford Heath <no.spam@please.net> - 2020-01-05 14:26 +1100
          Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-05 11:21 +0200
            Re: Task priorities in non strictly real-time systems David Brown <david.brown@hesbynett.no> - 2020-01-05 14:07 +0100
              Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-05 17:46 +0200
                Re: Task priorities in non strictly real-time systems David Brown <david.brown@hesbynett.no> - 2020-01-05 19:08 +0100
          Re: Task priorities in non strictly real-time systems David Brown <david.brown@hesbynett.no> - 2020-01-05 13:56 +0100
          Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-05 13:39 -0600
            Re: Task priorities in non strictly real-time systems Clifford Heath <no.spam@please.net> - 2020-01-06 07:44 +1100
              Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-05 21:00 -0600
                Re: Task priorities in non strictly real-time systems Clifford Heath <no.spam@please.net> - 2020-01-06 14:50 +1100
                  Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-06 07:12 -0600
        Re: Task priorities in non strictly real-time systems Paul Rubin <no.email@nospam.invalid> - 2020-01-04 22:34 -0800
          Re: Task priorities in non strictly real-time systems David Brown <david.brown@hesbynett.no> - 2020-01-05 14:12 +0100
            Re: Task priorities in non strictly real-time systems Niklas Holsti <niklas.holsti@tidorum.invalid> - 2020-01-05 18:00 +0200
          Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-05 13:44 -0600
        Re: Task priorities in non strictly real-time systems George Neuner <gneuner2@comcast.net> - 2020-01-06 14:52 -0500
        Re: Task priorities in non strictly real-time systems George Neuner <gneuner2@comcast.net> - 2020-01-06 15:05 -0500
          Re: Task priorities in non strictly real-time systems gtwrek@sonic.net (gtwrek) - 2020-01-06 22:41 +0000
          Re: Task priorities in non strictly real-time systems Don Y <blockedofcourse@foo.invalid> - 2020-01-06 19:50 -0700
            Re: Task priorities in non strictly real-time systems George Neuner <gneuner2@comcast.net> - 2020-01-07 13:26 -0500
    Re: Task priorities in non strictly real-time systems Niklas Holsti <niklas.holsti@tidorum.invalid> - 2020-01-03 16:28 +0200
      Re: Task priorities in non strictly real-time systems pozz <pozzugno@gmail.com> - 2020-01-05 01:37 +0100
        Re: Task priorities in non strictly real-time systems Les Cargill <lcargill99@comcast.com> - 2020-01-05 13:46 -0600
          Re: Task priorities in non strictly real-time systems Niklas Holsti <niklas.holsti@tidorum.invalid> - 2020-01-05 22:44 +0200
    Re: Task priorities in non strictly real-time systems Rick C <gnuarm.deletethisbit@gmail.com> - 2020-01-03 11:49 -0800
    Re: Task priorities in non strictly real-time systems upsidedown@downunder.com - 2020-01-03 22:51 +0200
      Re: Task priorities in non strictly real-time systems pozz <pozzugno@gmail.com> - 2020-01-05 01:48 +0100
    Re: Task priorities in non strictly real-time systems Joe Chisolm <jchisolm6@earthlink.net> - 2020-01-03 15:34 -0600
    Re: Task priorities in non strictly real-time systems Richard Damon <Richard@Damon-Family.org> - 2020-01-03 21:46 -0500

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#29056

Fromupsidedown@downunder.com
Date2020-01-07 10:54 +0200
Message-ID<85g81flnmgprie5meragkpopm61m62qr8n@4ax.com>
In reply to#29043
On Mon, 6 Jan 2020 16:10:03 -0700, Don Y <blockedofcourse@foo.invalid>
wrote:

<description of simple RT kernel for 6809 with typically 6 to 12 tasks
skipped>

>>>> The scheduler checked the task state byte of each created task
>>>> (requiring just 3 instructions/task). If no new higher priority task
>>>> had become runnable, the scheduler performed a simple return from
>>>> interrupt restoring the registers from the local stack and the
>>>> suspended task was resumed.
>>>
>>> Deciding and picking can often be far more complicated actions.
>>> And, the criteria used to make that selection are often not simple
>>> (static?) priorities.


Assuming a task can be in a WAITING state (not READY), runnable
(READY) and actually RUNNING. The scheduler simply scans the priority
list in priority order and when it detects the first task in READY
state (or already RUNNING) execute that task. The scan omits all tasks
in WAITING state. 

Only if a very large number (dozens) of tasks are expected to be in
WAITING state before detecting the first task in READY state it might
make sense to have a separate queue for READY or RUNNING tasks only 


>> Why complicate things with dynamically changing priorities ? For
>> avoiding priority inversion or improve user responsiveness ? But as I
>
>I find the whole notion of "priorities" to be abhorrent.  It suggests
>that you KNOW what the priorities SHOULD be -- as part of the DESIGN
>of the system.  

Of course I know :-).

>In practice, they tend to be twiddled after-the-fact
>when things don't quite work as you'd HOPED (i.e., you screwed up
>the design and are now using a rejiggering of priorities to try to
>coax it into behaving the way you'd HOPED)

I may sometimes have to split a task that consumes more than expected
CPU time for its priority level  into two task, moving the high time
requirement to a separate task and run it at a lower priority.

>When you assign arbitrary numeric values to impose an ordering on
>tasks ("relative importance"), do you prepare a formal justification
>for those choices?  A *rationale* that defends your choices?

Of course I check the deadline requirement of each task before
assigning priorities. Those tasks without formal deadline requirement
can often be execute in the null task with lowest priority. This of
course requires that the average CPU load is well below 100 % so that
the null task is sometimes executed.

[toc] | [prev] | [next] | [standalone]


#29065

FromDon Y <blockedofcourse@foo.invalid>
Date2020-01-07 06:43 -0700
Message-ID<qv21tl$14e$2@dont-email.me>
In reply to#29056
On 1/7/2020 1:54 AM, upsidedown@downunder.com wrote:
> On Mon, 6 Jan 2020 16:10:03 -0700, Don Y <blockedofcourse@foo.invalid>
> wrote:
> 
> <description of simple RT kernel for 6809 with typically 6 to 12 tasks
> skipped>
> 
>>>>> The scheduler checked the task state byte of each created task
>>>>> (requiring just 3 instructions/task). If no new higher priority task
>>>>> had become runnable, the scheduler performed a simple return from
>>>>> interrupt restoring the registers from the local stack and the
>>>>> suspended task was resumed.
>>>>
>>>> Deciding and picking can often be far more complicated actions.
>>>> And, the criteria used to make that selection are often not simple
>>>> (static?) priorities.
> 
> Assuming a task can be in a WAITING state (not READY), runnable
> (READY) and actually RUNNING. The scheduler simply scans the priority
> list in priority order and when it detects the first task in READY
> state (or already RUNNING) execute that task. The scan omits all tasks
> in WAITING state.

Something PUT those tasks into those states.  Sort them into the
correct queues, by "priority", when *that* happens.  In that way,
the decision time is made constant when you need to do a context switch.

> Only if a very large number (dozens) of tasks are expected to be in
> WAITING state before detecting the first task in READY state it might
> make sense to have a separate queue for READY or RUNNING tasks only

Do you *force* the developer NOT to have more than a certain number of
tasks?  It's the use of these "simple" algorithms that don't scale well
that I consider as differentiating an RTOS from an MTOS.

>> In practice, they tend to be twiddled after-the-fact
>> when things don't quite work as you'd HOPED (i.e., you screwed up
>> the design and are now using a rejiggering of priorities to try to
>> coax it into behaving the way you'd HOPED)
> 
> I may sometimes have to split a task that consumes more than expected
> CPU time for its priority level  into two task, moving the high time
> requirement to a separate task and run it at a lower priority.
> 
>> When you assign arbitrary numeric values to impose an ordering on
>> tasks ("relative importance"), do you prepare a formal justification
>> for those choices?  A *rationale* that defends your choices?
> 
> Of course I check the deadline requirement of each task before
> assigning priorities. Those tasks without formal deadline requirement
> can often be execute in the null task with lowest priority. This of
> course requires that the average CPU load is well below 100 % so that
> the null task is sometimes executed.

But deadlines vary, over time.  This is why priorities are a bad fit
as a scheduling criteria.  As a deadline approaches, do you tweek the
priority to ensure the task gets a chance to run?

"Lets make EVERYTHING louder than EVERYTHING else"
     -- Deep Purple (?)

ACTUAL deadlines are relatively easy to grok.  And, express numerically.
So, folks/developers can relate to the scheduler opting to run X instead
of Y at a particular time.

But, explaining why X should run at "3" while Y runs at "7" gets into a
lot of hand-waving ("What's running at 2?  And 5?  What about 8?")

I'm out.  I only "dropped in" to verify that I had set up Thunderbird
correctly on this rebuilt machine.  I have a fixed budget of time for
"correspondence" (my plate is *WAY* too full) and USENET burns up too
much for the benefit that it provides (me!  :> )

As of this moment, it appears that I've not left any conversations in
which I was a participant "dangling".

Happy New Year!

[toc] | [prev] | [next] | [standalone]


#29036

FromHans-Bernhard Bröker <HBBroeker@t-online.de>
Date2020-01-06 18:01 +0100
Message-ID<h7h7fdFr0f8U1@mid.dfncis.de>
In reply to#29021
Am 06.01.2020 um 01:08 schrieb Don Y:

> Preemptive frameworks can be implemented in a variety of ways.
> It need NOT mean that the processor can be pulled out from under
> your feet at any "random" time.

I think I have to disagree with that.

Let's start with linguistics.  To "preempt" means: to get in ahead of
someone (or something) else.

In the RT world, that something is a running task, and preemption
happens when some other task gets to use the CPU before that task is
done with it.  I.e. a preemptive framework, pretty much by definition of
the words, does pull the CPU out from under you, and that _will_ happen
at, essentially, random times.

If the running task can routinely (as opposed to exceptionally) avoid
that happening to itself, that means it's essentially the other type of
framework: a cooperative one.

In other words: for the distinction of preemptive vs. cooperative
multitasking to make any sense at all, it has to be about who routinely
gets to decide whether task switching is allowed at any given time.  If
the decision normally is with individual tasks, that's cooperative.  If
it's centralized in the OS, that's preemptive.

Now we in c.a.embedded don't usually get to make that distinction quite
so cleanly of course, because for us, ISRs are a fact of life, and those
are always preemptive.  So purely cooperative multitasking is out.  We
only get to decide between largely cooperative systems with some
preemptive task disturbing the "clean" picture, and almose purely
preemptive system setups, with all the extra cost in terms of data
exchange synchronization between tasks that entails.


> So, barring "events" signalled by an ISR, you can conceivably
> execute code inside a single task for DAYS and never lose control of
> the processor.

And still, when eventually you do lose it, the time when that happens
is, for all practical intents and purposes, random.  Because otherwise
you wouldn't "lose" control, you'ld be "giving it up".   In other words,
in such a case the used RTOS framework may be preemptive, but you're not
using it that way.

[toc] | [prev] | [next] | [standalone]


#29037

FromNiklas Holsti <niklas.holsti@tidorum.invalid>
Date2020-01-06 19:47 +0200
Message-ID<h7ha4pFrjcnU1@mid.individual.net>
In reply to#29036
On 2020-01-06 19:01, Hans-Bernhard Bröker wrote:
> Am 06.01.2020 um 01:08 schrieb Don Y:
> 
>> Preemptive frameworks can be implemented in a variety of ways.
>> It need NOT mean that the processor can be pulled out from under
>> your feet at any "random" time.
> 
> I think I have to disagree with that.
> 
> Let's start with linguistics.  To "preempt" means: to get in ahead of
> someone (or something) else.
> 
> In the RT world, that something is a running task, and preemption
> happens when some other task gets to use the CPU before that task is
> done with it.  I.e. a preemptive framework, pretty much by definition of
> the words, does pull the CPU out from under you, and that _will_ happen
> at, essentially, random times.
> 
> If the running task can routinely (as opposed to exceptionally) avoid
> that happening to itself, that means it's essentially the other type of
> framework: a cooperative one.

There are lots of intermediate ideas, "limited preemption" systems. See 
"Limited Preemptive Scheduling for Real-Time Systems: a Survey", at
https://algo.ing.unimo.it/people/marko/papers/TII13.pdf

> Now we in c.a.embedded don't usually get to make that distinction quite
> so cleanly of course, because for us, ISRs are a fact of life, and those
> are always preemptive.

Except, of course, when the task that would be interrupted disables or 
masks the interrupt(s) for a while, thus delaying the 
interruption/preemption until later.

Some embedded programs run with all interrupts always disabled, and 
instead poll for inputs and events.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

[toc] | [prev] | [next] | [standalone]


#29004

Frompozz <pozzugno@gmail.com>
Date2020-01-05 01:58 +0100
Message-ID<qurcak$puc$1@dont-email.me>
In reply to#28995
Il 03/01/2020 15:19, David Brown ha scritto:
> With pre-emptive scheduling, you will have to go
> through your existing code and make very sure that you have locks or
> synchronisation in place for any shared resources or data.

As I already wrote many times, I don't have experience with RTOS and 
task sync mechanism such as semaphores, locks, mutexes, message queues 
and so on.
So I'm not able to understand when a sync is really needed.

Could you point on a good simple material to study (online or book)?

For example, many times I have a serial channel where soma data are 
received. A frame parser decodes the "wire data" in variables, accessed 
by other tasks.

while(1) {
   serial_task();  // frame receiver/parser
   main_task();    // uses variables touched by frame parser
}

Supposing all the variables are of type int (i.e., they are changed 
atomically in serial_task()), should I need to protect them with locks, 
because they are used by main_task() too?

I think lock isn't needed, except main_task() needs to have a coerent 
data values for all the variables (all variables with new values or old 
values).

[toc] | [prev] | [next] | [standalone]


#29005

FromClifford Heath <no.spam@please.net>
Date2020-01-05 14:26 +1100
Message-ID<qHcQF.22112$MS2.17419@fx19.iad>
In reply to#29004
On 5/1/20 11:58 am, pozz wrote:
> Il 03/01/2020 15:19, David Brown ha scritto:
>> With pre-emptive scheduling, you will have to go
>> through your existing code and make very sure that you have locks or
>> synchronisation in place for any shared resources or data.
> 
> As I already wrote many times, I don't have experience with RTOS and 
> task sync mechanism such as semaphores, locks, mutexes, message queues 
> and so on.
> So I'm not able to understand when a sync is really needed.
> Could you point on a good simple material to study (online or book)?

I wish I could, but it is actually a frightfully difficult subject.
Basically it's the same as thread-safe programming.
Only about 1% of programmers think they can do it.
Of those, only about 1% actually can.

It's the 0.99% that you have to worry about. At least some of them for 
Toyota. Don't be one of them!

However, this difficulty is precisely why Rust was created. Although I 
haven't yet done a project in Rust, I've done enough multi-threaded work 
in C++ to know that the ideas in Rust are a massive leap forwards, and 
anyone doing this kind of work (especially professionally) owes it to 
their users to learn it.

> Supposing all the variables are of type int (i.e., they are changed 
> atomically in serial_task()), should I need to protect them with locks, 
> because they are used by main_task() too?

If "int" is your CPUs word size, you are using word alignment, and you 
don't have multiple CPUs with separate caches accessing the same RAM, 
you're probably ok for individual variables. However you will come 
unstuck if you expect assignments and reads to be performed in the same 
order you wrote them. A modern compiler will freely re-order things in 
extremely ambitious and unexpected ways, in order to keep the pipeline 
flowing.

I cannot emphasise this enough. The compiler will do what it can to make 
your program do what it thinks you have asked for - which will NOT be 
the same as what you think you have asked for.

You need to understand about basic mutex operations, preferably also 
semaphores, and beyond that to read and write barriers (if you want to 
write lock-free code). It's a big subject.

Clifford Heath.

[toc] | [prev] | [next] | [standalone]


#29007

Fromupsidedown@downunder.com
Date2020-01-05 11:21 +0200
Message-ID<7t531fpde9jlae0u0tos4o933mqpu3uluq@4ax.com>
In reply to#29005
On Sun, 5 Jan 2020 14:26:12 +1100, Clifford Heath <no.spam@please.net>
wrote:

>On 5/1/20 11:58 am, pozz wrote:
>> Il 03/01/2020 15:19, David Brown ha scritto:
>>> With pre-emptive scheduling, you will have to go
>>> through your existing code and make very sure that you have locks or
>>> synchronisation in place for any shared resources or data.
>> 
>> As I already wrote many times, I don't have experience with RTOS and 
>> task sync mechanism such as semaphores, locks, mutexes, message queues 
>> and so on.
>> So I'm not able to understand when a sync is really needed.
>> Could you point on a good simple material to study (online or book)?
>
>I wish I could, but it is actually a frightfully difficult subject.
>Basically it's the same as thread-safe programming.
>Only about 1% of programmers think they can do it.
>Of those, only about 1% actually can.
>
>It's the 0.99% that you have to worry about. At least some of them for 
>Toyota. Don't be one of them!
>
>However, this difficulty is precisely why Rust was created. Although I 
>haven't yet done a project in Rust, I've done enough multi-threaded work 
>in C++ to know that the ideas in Rust are a massive leap forwards, and 
>anyone doing this kind of work (especially professionally) owes it to 
>their users to learn it.
>
>> Supposing all the variables are of type int (i.e., they are changed 
>> atomically in serial_task()), should I need to protect them with locks, 
>> because they are used by main_task() too?

You may need some double buffering in one form or another.

Assuming you have a receiver byte buffer that can take a full serial
message and a structure of integers that will receive the values
decoded from the message.

When the serial task notices the end of a message. it immediately
decodes the values into the integers in the struct. After this, the
serial byte buffer is ready to start receiving the next message.The
serial task can then inform the main task that new data is in the
integer structure and main task can copy it to local variables. 

Alternatively, if a serial byte buffer is not used but the received
bytes are decoded into the integer fields in the fly, then a copy of
the struct may be provided, e.g. after the last integer has been
decoded, put the complete struct into a mailbox, if the RTOS provides
mailbox support.

In both cases the main task has a full message transfer time to
process a message, before it has to process the next serial message.
If the main task is incapable of processing the messages in time, then
the program is faulty at least in the hard real time sense.
 
>
>If "int" is your CPUs word size, you are using word alignment, and you 
>don't have multiple CPUs with separate caches accessing the same RAM, 
>you're probably ok for individual variables. However you will come 
>unstuck if you expect assignments and reads to be performed in the same 
>order you wrote them. A modern compiler will freely re-order things in 
>extremely ambitious and unexpected ways, in order to keep the pipeline 
>flowing.

Using volatile declaration and turn of optimization will help. Better
yet, use small assembler routines to have full control of actual
memory access.

>
>I cannot emphasise this enough. The compiler will do what it can to make 
>your program do what it thinks you have asked for - which will NOT be 
>the same as what you think you have asked for.
>
>You need to understand about basic mutex operations, preferably also 
>semaphores, and beyond that to read and write barriers (if you want to 
>write lock-free code). It's a big subject.

t least with a small micro controller, simply disable interrupts for a
critical section. Of course the critical section must behave like a
real interrupt, limit the number of instructions and do not call any
library routines.

[toc] | [prev] | [next] | [standalone]


#29009

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-05 14:07 +0100
Message-ID<qusn2q$m5i$1@dont-email.me>
In reply to#29007
On 05/01/2020 10:21, upsidedown@downunder.com wrote:
> On Sun, 5 Jan 2020 14:26:12 +1100, Clifford Heath <no.spam@please.net>

>>
>> If "int" is your CPUs word size, you are using word alignment, and you
>> don't have multiple CPUs with separate caches accessing the same RAM,
>> you're probably ok for individual variables. However you will come
>> unstuck if you expect assignments and reads to be performed in the same
>> order you wrote them. A modern compiler will freely re-order things in
>> extremely ambitious and unexpected ways, in order to keep the pipeline
>> flowing.
> 
> Using volatile declaration and turn of optimization will help. Better
> yet, use small assembler routines to have full control of actual
> memory access.

Turning off optimisation is /never/ the answer!  (Baring bugging 
compilers, of course.)

If your code "works with optimisation disabled", your code is /wrong/. 
In over 25 years in this business, I have never seen an exception.

Remember, there is no such thing as "disabling optimisations" - 
compilers can re-arrange code and apply whatever transformations they 
like, according to the C standards, with a total disregard for your 
choice of optimisation settings.  These settings are guidelines, not 
part of the semantics of the language - the language and the freedoms 
the compiler has do not change (unless your compiler specifically 
documents the changes).

And even if you think it is a "workaround" that is good enough for now, 
you are creating a maintainability nightmare.  Or worse - you are 
creating something that works fine during your testing and fails when 
deployed.

"Volatile", when used correctly, can be helpful.

Assembly routines for memory accesses are usually a bad idea - 
inefficient, inflexible and error-prone.


If you want a simple and relatively fool-proof system, all you really 
need are two functions (preferably inline) :

interrupt_status_t disableGlobalInterrupts(void);
void restoreGlobalInterrupts(interrupt_status_t old_status);

These must both act as full memory fences.

Then you can put whatever code needs atomic behaviour within a critical 
section bracketed by these functions.


You need more work if you have other memory masters (DMA, second 
processor, etc.).

> 
>>
>> I cannot emphasise this enough. The compiler will do what it can to make
>> your program do what it thinks you have asked for - which will NOT be
>> the same as what you think you have asked for.
>>
>> You need to understand about basic mutex operations, preferably also
>> semaphores, and beyond that to read and write barriers (if you want to
>> write lock-free code). It's a big subject.
> 
> t least with a small micro controller, simply disable interrupts for a
> critical section. Of course the critical section must behave like a
> real interrupt, limit the number of instructions and do not call any
> library routines.
> 

[toc] | [prev] | [next] | [standalone]


#29011

Fromupsidedown@downunder.com
Date2020-01-05 17:46 +0200
Message-ID<74041f9c9p82eeac586mn9bo8c73jeqfcj@4ax.com>
In reply to#29009
On Sun, 5 Jan 2020 14:07:37 +0100, David Brown
<david.brown@hesbynett.no> wrote:

>On 05/01/2020 10:21, upsidedown@downunder.com wrote:
>> On Sun, 5 Jan 2020 14:26:12 +1100, Clifford Heath <no.spam@please.net>
>
>>>
>>> If "int" is your CPUs word size, you are using word alignment, and you
>>> don't have multiple CPUs with separate caches accessing the same RAM,
>>> you're probably ok for individual variables. However you will come
>>> unstuck if you expect assignments and reads to be performed in the same
>>> order you wrote them. A modern compiler will freely re-order things in
>>> extremely ambitious and unexpected ways, in order to keep the pipeline
>>> flowing.
>> 
>> Using volatile declaration and turn of optimization will help. Better
>> yet, use small assembler routines to have full control of actual
>> memory access.
>
>Turning off optimisation is /never/ the answer!  (Baring bugging 
>compilers, of course.)
>
>If your code "works with optimisation disabled", your code is /wrong/. 
>In over 25 years in this business, I have never seen an exception.
>
>Remember, there is no such thing as "disabling optimisations" - 
>compilers can re-arrange code and apply whatever transformations they 
>like, according to the C standards, with a total disregard for your 
>choice of optimisation settings.  These settings are guidelines, not 
>part of the semantics of the language - the language and the freedoms 
>the compiler has do not change (unless your compiler specifically 
>documents the changes).

The problem is the C standard or actually the language lawyers (in
most languages) who do not have understanding for multithreading or
multiprocessors.

>And even if you think it is a "workaround" that is good enough for now, 
>you are creating a maintainability nightmare.  Or worse - you are 
>creating something that works fine during your testing and fails when 
>deployed.
>
>"Volatile", when used correctly, can be helpful.
>
>Assembly routines for memory accesses are usually a bad idea - 
>inefficient, inflexible and error-prone.

In any hardware platforms with at least memory location increment or
decrement operation as on a single instruction performing
read/modify/write memory access cycle is often quite hardly.

Even if you can't get an atomic R/M/W cycle, there are often similar
tricks e.g. such as using the lock prefix in x86
 

>If you want a simple and relatively fool-proof system, all you really 
>need are two functions (preferably inline) :
>
>interrupt_status_t disableGlobalInterrupts(void);
>void restoreGlobalInterrupts(interrupt_status_t old_status);
>
>These must both act as full memory fences.
>
>Then you can put whatever code needs atomic behaviour within a critical 
>section bracketed by these functions.

Is this standard C in some recent standard variant ?


>You need more work if you have other memory masters (DMA, second 
>processor, etc.).

This has a lot to do with cache coherence.

[toc] | [prev] | [next] | [standalone]


#29013

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-05 19:08 +0100
Message-ID<qut8m6$uq3$1@dont-email.me>
In reply to#29011
On 05/01/2020 16:46, upsidedown@downunder.com wrote:
> On Sun, 5 Jan 2020 14:07:37 +0100, David Brown
> <david.brown@hesbynett.no> wrote:
> 
>> On 05/01/2020 10:21, upsidedown@downunder.com wrote:
>>> On Sun, 5 Jan 2020 14:26:12 +1100, Clifford Heath <no.spam@please.net>
>>
>>>>
>>>> If "int" is your CPUs word size, you are using word alignment, and you
>>>> don't have multiple CPUs with separate caches accessing the same RAM,
>>>> you're probably ok for individual variables. However you will come
>>>> unstuck if you expect assignments and reads to be performed in the same
>>>> order you wrote them. A modern compiler will freely re-order things in
>>>> extremely ambitious and unexpected ways, in order to keep the pipeline
>>>> flowing.
>>>
>>> Using volatile declaration and turn of optimization will help. Better
>>> yet, use small assembler routines to have full control of actual
>>> memory access.
>>
>> Turning off optimisation is /never/ the answer!  (Baring bugging
>> compilers, of course.)
>>
>> If your code "works with optimisation disabled", your code is /wrong/.
>> In over 25 years in this business, I have never seen an exception.
>>
>> Remember, there is no such thing as "disabling optimisations" -
>> compilers can re-arrange code and apply whatever transformations they
>> like, according to the C standards, with a total disregard for your
>> choice of optimisation settings.  These settings are guidelines, not
>> part of the semantics of the language - the language and the freedoms
>> the compiler has do not change (unless your compiler specifically
>> documents the changes).
> 
> The problem is the C standard or actually the language lawyers (in
> most languages) who do not have understanding for multithreading or
> multiprocessors.

The main point of C11 is support for multi-threading and multi-processor 
systems.  The standards, and the language lawyers, /do/ understand it.

The more advanced and progressive compilers support C11.  Many embedded 
ones do not, but that is the fault of the compiler vendors, and perhaps 
of developers who don't realise that they should be insisting on it.

The big missing feature, however, is that you need an implementation of 
some of the functions in the C11 threading libraries, and the 
implementation must fit the OS in use.  That's not too hard for Linux or 
Windows, but a different world in embedded systems.  Still, it should be 
possible to make C11 library support for FreeRTOS, mbed, and any other 
RTOS you like.

Key points like atomics, fences, and language semantics for 
multi-threading are in place.

(And C++ is more helpful in providing higher level multi-threading 
features.)

So we are far from having nice multi-threading integration in C 
toolchains, but nearly as far as you suggest.

> 
>> And even if you think it is a "workaround" that is good enough for now,
>> you are creating a maintainability nightmare.  Or worse - you are
>> creating something that works fine during your testing and fails when
>> deployed.
>>
>> "Volatile", when used correctly, can be helpful.
>>
>> Assembly routines for memory accesses are usually a bad idea -
>> inefficient, inflexible and error-prone.
> 
> In any hardware platforms with at least memory location increment or
> decrement operation as on a single instruction performing
> read/modify/write memory access cycle is often quite hardly.
> 

/Some/ hardware platforms that let you do "x++" as a single instruction 
on memory, do so atomically.  Many others do not.  Typically, they are 
atomic on small 8-bit CISC microcontrollers.  On larger processors, you 
rarely get such instructions at all (they don't exist on any kind of 
RISC cpu).  And even when you /do/ get them, they may be implemented by 
multiple separate actions.  Perhaps they are atomic with respect to 
other code on the same core (such as interrupts), but not with respect 
to DMA or other cores.

So this kind of thing can sometimes be acceptable on target-specific 
code for small microcontrollers, but not otherwise.

> Even if you can't get an atomic R/M/W cycle, there are often similar
> tricks e.g. such as using the lock prefix in x86
>   

You do that using intrinsics or C11/C++11 atomics.  You certainly don't 
do it with "volatile".

> 
>> If you want a simple and relatively fool-proof system, all you really
>> need are two functions (preferably inline) :
>>
>> interrupt_status_t disableGlobalInterrupts(void);
>> void restoreGlobalInterrupts(interrupt_status_t old_status);
>>
>> These must both act as full memory fences.
>>
>> Then you can put whatever code needs atomic behaviour within a critical
>> section bracketed by these functions.
> 
> Is this standard C in some recent standard variant ?

No C standard covers interrupts, or ways to disable and enable them - 
that is highly target-specific.

For example, on the ARM Cortex-M, you might use:

#include "core_cmFunc.h"

typedef interrupt_status_t uint32_t;
static inline interrupt_status_t disableGlobalInterrupts(void) {
	interrupt_status_t old = __get_PRIMASK();
	__disable_irq();
	return old;
}

static inline void restoreGlobalInterrupts(interrupt_status_t old) {
	__set_PRIMASK(old);
}

If you don't want to use the ARM core functions, you can use inline 
assembly - but that is compiler specific.  For gcc, that would be:

typedef interrupt_status_t uint32_t;
static inline interrupt_status_t disableGlobalInterrupts(void) {
	interrupt_status_t old;
	asm volatile ("mrs %0, primask" : "=r" (old));
	asm volatile ("cpsid i" : : : "memory");
	return old;
}

static inline void restoreGlobalInterrupts(interrupt_status_t old) {
	asm volatile ("msr primask, %0" : : "r" (old) : "memory");
}


C11 provides standard support for a memory barrier, but since you need 
compiler-specific code for the implementation anyway, you might as well 
use the compiler-specific memory barrier.


> 
> 
>> You need more work if you have other memory masters (DMA, second
>> processor, etc.).
> 
> This has a lot to do with cache coherence.
> 

That is one aspect, yes.  But it is not the only one.  For example, 
bigger processors can have write buffers with re-ordering.

[toc] | [prev] | [next] | [standalone]


#29008

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-05 13:56 +0100
Message-ID<qusmdc$idf$1@dont-email.me>
In reply to#29005
On 05/01/2020 04:26, Clifford Heath wrote:
> On 5/1/20 11:58 am, pozz wrote:
>> Il 03/01/2020 15:19, David Brown ha scritto:
>>> With pre-emptive scheduling, you will have to go
>>> through your existing code and make very sure that you have locks or
>>> synchronisation in place for any shared resources or data.
>>
>> As I already wrote many times, I don't have experience with RTOS and 
>> task sync mechanism such as semaphores, locks, mutexes, message queues 
>> and so on.
>> So I'm not able to understand when a sync is really needed.
>> Could you point on a good simple material to study (online or book)?
> 
> I wish I could, but it is actually a frightfully difficult subject.
> Basically it's the same as thread-safe programming.
> Only about 1% of programmers think they can do it.
> Of those, only about 1% actually can.
> 
> It's the 0.99% that you have to worry about. At least some of them for 
> Toyota. Don't be one of them!

All good points.

> 
> However, this difficulty is precisely why Rust was created. Although I 
> haven't yet done a project in Rust, I've done enough multi-threaded work 
> in C++ to know that the ideas in Rust are a massive leap forwards, and 
> anyone doing this kind of work (especially professionally) owes it to 
> their users to learn it.

"Safe" languages like Rust can help for simple issues, but won't give 
any benefits of the more challenging cases.  If you understand the 
basics of multi-threading, and have a good, careful development 
methodology, you won't have the kind of problems that Rust would help 
you with.  Maybe Rust will help for some cases, but don't believe that 
it is a game-changer.

> 
>> Supposing all the variables are of type int (i.e., they are changed 
>> atomically in serial_task()), should I need to protect them with 
>> locks, because they are used by main_task() too?
> 
> If "int" is your CPUs word size, you are using word alignment, and you 
> don't have multiple CPUs with separate caches accessing the same RAM, 
> you're probably ok for individual variables. However you will come 
> unstuck if you expect assignments and reads to be performed in the same 
> order you wrote them. A modern compiler will freely re-order things in 
> extremely ambitious and unexpected ways, in order to keep the pipeline 
> flowing.

Yes.  Simple reads and writes of aligned data that is no bigger than the 
cpu's word size will be atomic without any more effort.  But complex 
accesses (like "x++;") are not atomic on most processors.  And you don't 
have any ordering unless you use "volatile", or memory fences of some kind.

A key mistake many people make is to think that non-volatile accesses 
are also ordered by volatile accesses - this is, of course, untrue.

> 
> I cannot emphasise this enough. The compiler will do what it can to make 
> your program do what it thinks you have asked for - which will NOT be 
> the same as what you think you have asked for.

Well, it /will/ be the same as you think you asked for when you know 
what you are doing!

> 
> You need to understand about basic mutex operations, preferably also 
> semaphores, and beyond that to read and write barriers (if you want to 
> write lock-free code). It's a big subject.
> 

Yes.

Or he can use cooperative multitasking, and avoid many of these issues!

> Clifford Heath.

[toc] | [prev] | [next] | [standalone]


#29015

FromLes Cargill <lcargill99@comcast.com>
Date2020-01-05 13:39 -0600
Message-ID<qutdje$tko$1@dont-email.me>
In reply to#29005
Clifford Heath wrote:
> On 5/1/20 11:58 am, pozz wrote:
<snip>
> 
> I wish I could, but it is actually a frightfully difficult subject.
> Basically it's the same as thread-safe programming.
> Only about 1% of programmers think they can do it.
> Of those, only about 1% actually can.
> 

I could show anyone how in an afternoon. So I take your statement as 
being "only 1% of 1% have been forced to take that afternoon to learn it."

I should qualify that - I could show anyone working on a classic 
architecture how. With multilevel caches and certain sorts of MMUs,
there may be more to it.

I'm thinking the WindRiver drivers course was about one week, which 
should about  cover everything conceptually.

> It's the 0.99% that you have to worry about. At least some of them for 
> Toyota. Don't be one of them!
> 
> However, this difficulty is precisely why Rust was created. Although I 
> haven't yet done a project in Rust, I've done enough multi-threaded work 
> in C++ to know that the ideas in Rust are a massive leap forwards, and 
> anyone doing this kind of work (especially professionally) owes it to 
> their users to learn it.
> 

I seriously doubt Rust represents some quantum leap here.

<snip>
> 
> You need to understand about basic mutex operations, preferably also 
> semaphores, and beyond that to read and write barriers (if you want to 
> write lock-free code). It's a big subject.
> 

And that's about an afternoon, really. Not so much the barriers and
bothering with lock-free. That may take a little more.

> Clifford Heath.

-- 
Les Cargill

[toc] | [prev] | [next] | [standalone]


#29018

FromClifford Heath <no.spam@please.net>
Date2020-01-06 07:44 +1100
Message-ID<uUrQF.242435$%d1.180908@fx45.iad>
In reply to#29015
On 6/1/20 6:39 am, Les Cargill wrote:
> Clifford Heath wrote:
>> On 5/1/20 11:58 am, pozz wrote:
> <snip>
>>
>> I wish I could, but it is actually a frightfully difficult subject.
>> Basically it's the same as thread-safe programming.
>> Only about 1% of programmers think they can do it.
>> Of those, only about 1% actually can.
>>
> 
> I could show anyone how in an afternoon. So I take your statement as 
> being "only 1% of 1% have been forced to take that afternoon to learn it."
> 
> I should qualify that - I could show anyone working on a classic 
> architecture how. With multilevel caches and certain sorts of MMUs,
> there may be more to it.
> 
> I'm thinking the WindRiver drivers course was about one week, which 
> should about  cover everything conceptually.
> 
>> It's the 0.99% that you have to worry about. At least some of them for 
>> Toyota. Don't be one of them!
>>
>> However, this difficulty is precisely why Rust was created. Although I 
>> haven't yet done a project in Rust, I've done enough multi-threaded 
>> work in C++ to know that the ideas in Rust are a massive leap 
>> forwards, and anyone doing this kind of work (especially 
>> professionally) owes it to their users to learn it.
>>
> 
> I seriously doubt Rust represents some quantum leap here.
> 
> <snip>
>>
>> You need to understand about basic mutex operations, preferably also 
>> semaphores, and beyond that to read and write barriers (if you want to 
>> write lock-free code). It's a big subject.
>>
> 
> And that's about an afternoon, really. Not so much the barriers and
> bothering with lock-free. That may take a little more.

Behold a 0.99%-er!

:)

[toc] | [prev] | [next] | [standalone]


#29022

FromLes Cargill <lcargill99@comcast.com>
Date2020-01-05 21:00 -0600
Message-ID<quu7ei$btv$1@dont-email.me>
In reply to#29018
Clifford Heath wrote:
> On 6/1/20 6:39 am, Les Cargill wrote:
>> Clifford Heath wrote:
>>> On 5/1/20 11:58 am, pozz wrote:
>> <snip>
>>>
>>> I wish I could, but it is actually a frightfully difficult subject.
>>> Basically it's the same as thread-safe programming.
>>> Only about 1% of programmers think they can do it.
>>> Of those, only about 1% actually can.
>>>
>>
>> I could show anyone how in an afternoon. So I take your statement as 
>> being "only 1% of 1% have been forced to take that afternoon to learn 
>> it."
>>
>> I should qualify that - I could show anyone working on a classic 
>> architecture how. With multilevel caches and certain sorts of MMUs,
>> there may be more to it.
>>
>> I'm thinking the WindRiver drivers course was about one week, which 
>> should about  cover everything conceptually.
>>
>>> It's the 0.99% that you have to worry about. At least some of them 
>>> for Toyota. Don't be one of them!
>>>
>>> However, this difficulty is precisely why Rust was created. Although 
>>> I haven't yet done a project in Rust, I've done enough multi-threaded 
>>> work in C++ to know that the ideas in Rust are a massive leap 
>>> forwards, and anyone doing this kind of work (especially 
>>> professionally) owes it to their users to learn it.
>>>
>>
>> I seriously doubt Rust represents some quantum leap here.
>>
>> <snip>
>>>
>>> You need to understand about basic mutex operations, preferably also 
>>> semaphores, and beyond that to read and write barriers (if you want 
>>> to write lock-free code). It's a big subject.
>>>
>>
>> And that's about an afternoon, really. Not so much the barriers and
>> bothering with lock-free. That may take a little more.
> 
> Behold a 0.99%-er!
> 
> :)


We can larf, but I think there's less to serialization than is made of it.

-- 
Les Cargill

[toc] | [prev] | [next] | [standalone]


#29025

FromClifford Heath <no.spam@please.net>
Date2020-01-06 14:50 +1100
Message-ID<m8yQF.61419$sS2.24799@fx15.iad>
In reply to#29022
On 6/1/20 2:00 pm, Les Cargill wrote:
> Clifford Heath wrote:
>> On 6/1/20 6:39 am, Les Cargill wrote:
>>> Clifford Heath wrote:
>>>> You need to understand about basic mutex operations, preferably also 
>>>> semaphores, and beyond that to read and write barriers (if you want 
>>>> to write lock-free code). It's a big subject.
>>> And that's about an afternoon, really. Not so much the barriers and
>>> bothering with lock-free. That may take a little more.
> We can larf, but I think there's less to serialization than is made of it.

Serialization using one giant lock isn't too hard - that's how people 
write code using interrupts. But it's a very simplified case, and the 
problem is to use such simple locking to construct correct algorithms at 
a higher level.

Many apparently straightforward algorithms have dire pathologies when 
the atomic operations can get interspersed at will. In many cases the 
bugs will not ever show up during testing. And *that* is the real 
problem. Such code must be *correct by construction*, but people 
generally don't work that way.

Clifford Heath.

[toc] | [prev] | [next] | [standalone]


#29032

FromLes Cargill <lcargill99@comcast.com>
Date2020-01-06 07:12 -0600
Message-ID<quvb9p$rms$1@dont-email.me>
In reply to#29025
Clifford Heath wrote:
> On 6/1/20 2:00 pm, Les Cargill wrote:
>> Clifford Heath wrote:
>>> On 6/1/20 6:39 am, Les Cargill wrote:
>>>> Clifford Heath wrote:
>>>>> You need to understand about basic mutex operations, preferably 
>>>>> also semaphores, and beyond that to read and write barriers (if you 
>>>>> want to write lock-free code). It's a big subject.
>>>> And that's about an afternoon, really. Not so much the barriers and
>>>> bothering with lock-free. That may take a little more.
>> We can larf, but I think there's less to serialization than is made of 
>> it.
> 

Well said, Clifford, by the way.

> Serialization using one giant lock isn't too hard - that's how people 
> write code using interrupts. But it's a very simplified case, and the 
> problem is to use such simple locking to construct correct algorithms at 
> a higher level.
> 

I really feel it's just a matter of people stretching metaphors beyond
the breaking point. Most of the example cases I have seen to illustrate
these pathologies are rather contrived.

Most of these are due to ... reversing dependencies within a logic 
structure, not abuse of constructs. And yes, I have trouble reading
that sentence too.

I also don't want to appear to be too blase about things like cache 
lines, memory fences and all that. I just mean basic semaphores.

> Many apparently straightforward algorithms have dire pathologies when 
> the atomic operations can get interspersed at will. 

Because it can't very well be "at will". Aren't semaphores like the 
escapement mechanism in a regulator clock more than anything else?

They say "Not now."

> In many cases the 
> bugs will not ever show up during testing. And *that* is the real 
> problem. Such code must be *correct by construction*, but people 
> generally don't work that way.
> 

I will not disagree; it doesn't mean I have to like that state of 
affairs. To an extent the very word "correct" seems to inspire
helplessness.

> Clifford Heath.

-- 
Les Cargill

[toc] | [prev] | [next] | [standalone]


#29006

FromPaul Rubin <no.email@nospam.invalid>
Date2020-01-04 22:34 -0800
Message-ID<87blrio1hk.fsf@nightsong.com>
In reply to#29004
pozz <pozzugno@gmail.com> writes:
> As I already wrote many times, I don't have experience with RTOS and
> task sync mechanism such as semaphores, locks, mutexes, message queues
> and so on.
> So I'm not able to understand when a sync is really needed.
>
> Could you point on a good simple material to study (online or book)?

I have found it simplest to have tasks communicate by message passing,
the so-called "CSP model" (communicating sequential processes), rather
than fooling around with explicit locks.  With locks you have to worry
about lock inversion and all kinds of other madness, and your main hope
of getting it right is formal methods, like Lamport used for the Paxos
algorithm.  Message passing incurs some cpu overhead because of the
interprocess communication and context switches, but it gets rid of a
lot of ways things go wrong.

If your RTOS supports message passing (look for "mailboxes" in the RTOS
docs) then I'd say use them.

The language most associated with CSP style is Erlang, which doesn't
really fit on small embedded devices, but Erlang materials might still
be a good place to learn about the style.  Erlang inventor Joe
Armstrong's book might be a good place to start:

   http://erlang.org/download/erlang-book-part1.pdf

At the much lower end, you could check out Brad Rodriguez's articles
about Forth multitaskers:

https://www.bradrodriguez.com/papers/mtasking.html

and related ones at https://www.bradrodriguez.com/papers/ .

[toc] | [prev] | [next] | [standalone]


#29010

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-05 14:12 +0100
Message-ID<qusnb2$nod$1@dont-email.me>
In reply to#29006
On 05/01/2020 07:34, Paul Rubin wrote:
> pozz <pozzugno@gmail.com> writes:
>> As I already wrote many times, I don't have experience with RTOS and
>> task sync mechanism such as semaphores, locks, mutexes, message queues
>> and so on.
>> So I'm not able to understand when a sync is really needed.
>>
>> Could you point on a good simple material to study (online or book)?
> 
> I have found it simplest to have tasks communicate by message passing,
> the so-called "CSP model" (communicating sequential processes), rather
> than fooling around with explicit locks.  With locks you have to worry
> about lock inversion and all kinds of other madness, and your main hope
> of getting it right is formal methods, like Lamport used for the Paxos
> algorithm.  Message passing incurs some cpu overhead because of the
> interprocess communication and context switches, but it gets rid of a
> lot of ways things go wrong.
> 
> If your RTOS supports message passing (look for "mailboxes" in the RTOS
> docs) then I'd say use them.
> 

Yes - message passing (whether asynchronous with queues, or synchronous 
with CSP style) is often a lot easier to get right than complicated 
locking mechanisms.

> The language most associated with CSP style is Erlang, which doesn't
> really fit on small embedded devices, but Erlang materials might still
> be a good place to learn about the style.  Erlang inventor Joe
> Armstrong's book might be a good place to start:
> 
>     http://erlang.org/download/erlang-book-part1.pdf
> 

I've worked indirectly with Erlang (I made the microcontroller half of 
the system, in C, while someone else wrote the Linux half in Erlang).  I 
was not impressed - he spend a lot of time figuring out things that 
should have been very simple.  It is just one sample point, of course, 
and not enough to condemn a whole language - but it does mean Erlang is 
not high on my "languages to learn when I have time" list.

Far and away the most popular "CSP language" is Go, as I understand it. 
Another option is XC for XMOS devices, but that is hardware-specific.

> At the much lower end, you could check out Brad Rodriguez's articles
> about Forth multitaskers:
> 
> https://www.bradrodriguez.com/papers/mtasking.html
> 
> and related ones at https://www.bradrodriguez.com/papers/ .
> 

[toc] | [prev] | [next] | [standalone]


#29012

FromNiklas Holsti <niklas.holsti@tidorum.invalid>
Date2020-01-05 18:00 +0200
Message-ID<h7efgbF9e1nU1@mid.individual.net>
In reply to#29010
On 2020-01-05 15:12, David Brown wrote:
> On 05/01/2020 07:34, Paul Rubin wrote:
>> pozz <pozzugno@gmail.com> writes:
>>> As I already wrote many times, I don't have experience with RTOS and
>>> task sync mechanism such as semaphores, locks, mutexes, message queues
>>> and so on.
>>> So I'm not able to understand when a sync is really needed.
>>>
>>> Could you point on a good simple material to study (online or book)?
>>
>> I have found it simplest to have tasks communicate by message passing,
>> the so-called "CSP model" (communicating sequential processes), rather
>> than fooling around with explicit locks.

    [snip]

> Yes - message passing (whether asynchronous with queues, or synchronous 
> with CSP style) is often a lot easier to get right than complicated 
> locking mechanisms.
> 
>> The language most associated with CSP style is Erlang, which doesn't
>> really fit on small embedded devices, but Erlang materials might still
>> be a good place to learn about the style.  Erlang inventor Joe
>> Armstrong's book might be a good place to start:
>>
>>     http://erlang.org/download/erlang-book-part1.pdf

    [snip]

> Far and away the most popular "CSP language" is Go, as I understand it. 
> Another option is XC for XMOS devices, but that is hardware-specific.

Another language with CSP-style primitives is Ada (the "rendez-vous" 
feature), although AIUI most embedded Ada programs currently being 
implemented use the alternative "monitor"-like primitives (the 
"protected object" feature), which can be used to implement critical 
regions, or CSP-like message passing, or buffered (queued) message 
passing, or for many other styles.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

[toc] | [prev] | [next] | [standalone]


#29016

FromLes Cargill <lcargill99@comcast.com>
Date2020-01-05 13:44 -0600
Message-ID<qutdta$vk4$1@dont-email.me>
In reply to#29006
Paul Rubin wrote:
> pozz <pozzugno@gmail.com> writes:
>> As I already wrote many times, I don't have experience with RTOS and
>> task sync mechanism such as semaphores, locks, mutexes, message queues
>> and so on.
>> So I'm not able to understand when a sync is really needed.
>>
>> Could you point on a good simple material to study (online or book)?
> 
> I have found it simplest to have tasks communicate by message passing,
> the so-called "CSP model" (communicating sequential processes), rather
> than fooling around with explicit locks.  With locks you have to worry
> about lock inversion and all kinds of other madness, and your main hope
> of getting it right is formal methods, like Lamport used for the Paxos
> algorithm.  Message passing incurs some cpu overhead because of the
> interprocess communication and context switches, but it gets rid of a
> lot of ways things go wrong.
> 
> If your RTOS supports message passing (look for "mailboxes" in the RTOS
> docs) then I'd say use them.
> 

Mailboxes are just semaphores with extra steps :) When I've written 
mailboxes for use in user space, they usually use a semaphore.

In kernel space, you're already under a "semaphore" ( but still subject 
to asynchronous interrupts ). This of course varies by O/S....

> The language most associated with CSP style is Erlang, which doesn't
> really fit on small embedded devices, but Erlang materials might still
> be a good place to learn about the style.  Erlang inventor Joe
> Armstrong's book might be a good place to start:
> 

Erlang is a fine system,. The ( arguably ) best thing it provides is the
"actor pattern", which applies independent of language choice.

<snip>

-- 
Les Cargill

[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | comp.arch.embedded


csiph-web