1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

Re: Delta Queue Help - Paging Mr. Kirwan

Discussion in 'Embedded' started by Jon Kirwan, Sep 25, 2011.

  1. Jon Kirwan

    Jon Kirwan Guest

    On Sun, 25 Sep 2011 15:18:14 +0200, Arlet Ottens
    <> wrote:

    >On 09/25/2011 02:56 PM, eeboy wrote:
    >
    ><snip>
    >
    >> This does bring up a question though. If I am making a stack for some
    >> function. It seams it would be easy to allocate space for it as it would be
    >> some base value plus whatever space for autos... but if that function calls
    >> another sub which might call another sub which might... see where I am
    >> going with that question? How do I allocate? I know that I use some large
    >> char arrays (~128b) for sprintf. I guess those should be static huh?

    >
    >If you make those arrays static, you have to keep in mind that printf()
    >will no longer be reentrant. This could be a problem if you call that
    >printf() function in a task, do a context switch in the middle of it,
    >and have the other task use the same static buffer. An auto variable
    >doesn't have that problem, but will require a suitably large stack to
    >accommodate it. A static buffer protected by a semaphore would also be
    >an option.


    It's probably starting to get confusing. I'm not sure, even,
    what is being asked by eeboy. But your response, Arlet,
    needs some clarification I think. I'll use your comments as
    a foil, but I'm really responding to eeboy and not you.

    ....

    Often, what I may do is set up each thread in a separate c
    file. And I then don't publish (make 'extern') any static
    data I define that I don't want other threads using or
    messing with.

    This works just fine. It's just fine to use static arrays in
    each thread and it's not even risky, so long as you make sure
    that other threads don't use the same static regions.

    You mentioned sprintf(). Let's say you don't have enough
    sram laying about on your micro. So you simply *must* use
    the same buffer for sprintf(), in all threads, because you
    have no other choice in the matter. Do you have a problem?
    Maybe. Not necessarily.

    We've been discussing a non-preemptive design all along. Keep
    that in mind. Yes, if the system were preemptive and could
    literally _tear_ control away from you, it would be a problem
    and _then_ you probably would need a semaphore to help
    arbitrate access to the buffer for sprintf(). But let's say
    this is NOT preemptive. In that case, there is no problem.
    When you call sprintf(), unless you re-write it, it will do
    the work you asked and then return. But since this is a
    cooperative system and changes to other threads can only
    occur when you call the thread switch code, there is no way
    for interference from other threads. You have control over
    the cpu, so there is no problem. So long as you get a chance
    to _use_ the buffer before you switch threads, or copy the
    part of it you need somewhere else, first.

    It's not nearly as scary as some are making this sound.
    Especially not if you are staying cooperative.

    Now, if you go preemptive, then yes. All hell breaks loose.
    It's possible that there is static memory being used in some
    floating point code you don't even know you are using. So
    you have thread T1 in the middle of some expression calc and
    then the operating system 'preempts' you and forces control
    over to thread T2. But the floating point code was not
    written for a preemptive operating system and the author,
    stilly idiot as he or she may be, used some static memory
    that is entirely internal to their code for temporary storage
    during computation. But T2 now starts up a calculation, or
    perhaps comes back to one it thinks is in progress, and it's
    just BAD. Nothing works and you've no idea why your numbers
    aren't right. The only fix is to make the context switch
    code aware of all these library static areas and save them
    away. Or else block switching when a library routine is
    running. Stuff like that. It gets really bad, fast.

    Which is why I don't recommend pre-emption as your first
    attempt. :)

    Anyway, I'll answer other stuff elsewhere, shortly.

    Jon
    Jon Kirwan, Sep 25, 2011
    #1
    1. Advertising

  2. Jon Kirwan

    Arlet Ottens Guest

    On 09/25/2011 04:59 PM, Jon Kirwan wrote:
    > On Sun, 25 Sep 2011 15:18:14 +0200, Arlet Ottens
    > <> wrote:
    >
    >> On 09/25/2011 02:56 PM, eeboy wrote:
    >>
    >> <snip>
    >>
    >>> This does bring up a question though. If I am making a stack for some
    >>> function. It seams it would be easy to allocate space for it as it would be
    >>> some base value plus whatever space for autos... but if that function calls
    >>> another sub which might call another sub which might... see where I am
    >>> going with that question? How do I allocate? I know that I use some large
    >>> char arrays (~128b) for sprintf. I guess those should be static huh?

    >>
    >> If you make those arrays static, you have to keep in mind that printf()
    >> will no longer be reentrant. This could be a problem if you call that
    >> printf() function in a task, do a context switch in the middle of it,
    >> and have the other task use the same static buffer. An auto variable
    >> doesn't have that problem, but will require a suitably large stack to
    >> accommodate it. A static buffer protected by a semaphore would also be
    >> an option.

    >
    > It's probably starting to get confusing. I'm not sure, even,
    > what is being asked by eeboy. But your response, Arlet,
    > needs some clarification I think. I'll use your comments as
    > a foil, but I'm really responding to eeboy and not you.
    >
    > ....
    >
    > Often, what I may do is set up each thread in a separate c
    > file. And I then don't publish (make 'extern') any static
    > data I define that I don't want other threads using or
    > messing with.
    >
    > This works just fine. It's just fine to use static arrays in
    > each thread and it's not even risky, so long as you make sure
    > that other threads don't use the same static regions.
    >
    > You mentioned sprintf(). Let's say you don't have enough
    > sram laying about on your micro. So you simply *must* use
    > the same buffer for sprintf(), in all threads, because you
    > have no other choice in the matter. Do you have a problem?
    > Maybe. Not necessarily.
    >
    > We've been discussing a non-preemptive design all along. Keep
    > that in mind. Yes, if the system were preemptive and could
    > literally _tear_ control away from you, it would be a problem
    > and _then_ you probably would need a semaphore to help
    > arbitrate access to the buffer for sprintf(). But let's say
    > this is NOT preemptive. In that case, there is no problem.
    > When you call sprintf(), unless you re-write it, it will do
    > the work you asked and then return. But since this is a
    > cooperative system and changes to other threads can only
    > occur when you call the thread switch code, there is no way
    > for interference from other threads. You have control over
    > the cpu, so there is no problem. So long as you get a chance
    > to _use_ the buffer before you switch threads, or copy the
    > part of it you need somewhere else, first.


    A common scenenario is the following:

    sprintf( buffer, "hello world\n" );
    uart_sendstring( buffer );

    Now, if your uart_sendstring() puts stuff on an transmit FIFO for the
    UART, and the FIFO happens to be full, you'd usually want the task to
    sleep until there's some room in the FIFO.

    While the task is sleeping, another task is scheduled, that also
    performs a sprintf() overwriting the buffer that was still used.
    Arlet Ottens, Sep 25, 2011
    #2
    1. Advertising

  3. Jon Kirwan

    Jon Kirwan Guest

    On Sun, 25 Sep 2011 17:22:17 +0200, Arlet Ottens
    <> wrote:

    >On 09/25/2011 04:59 PM, Jon Kirwan wrote:
    >> On Sun, 25 Sep 2011 15:18:14 +0200, Arlet Ottens
    >> <> wrote:
    >>
    >>> On 09/25/2011 02:56 PM, eeboy wrote:
    >>>
    >>> <snip>
    >>>
    >>>> This does bring up a question though. If I am making a stack for some
    >>>> function. It seams it would be easy to allocate space for it as it would be
    >>>> some base value plus whatever space for autos... but if that function calls
    >>>> another sub which might call another sub which might... see where I am
    >>>> going with that question? How do I allocate? I know that I use some large
    >>>> char arrays (~128b) for sprintf. I guess those should be static huh?
    >>>
    >>> If you make those arrays static, you have to keep in mind that printf()
    >>> will no longer be reentrant. This could be a problem if you call that
    >>> printf() function in a task, do a context switch in the middle of it,
    >>> and have the other task use the same static buffer. An auto variable
    >>> doesn't have that problem, but will require a suitably large stack to
    >>> accommodate it. A static buffer protected by a semaphore would also be
    >>> an option.

    >>
    >> It's probably starting to get confusing. I'm not sure, even,
    >> what is being asked by eeboy. But your response, Arlet,
    >> needs some clarification I think. I'll use your comments as
    >> a foil, but I'm really responding to eeboy and not you.
    >>
    >> ....
    >>
    >> Often, what I may do is set up each thread in a separate c
    >> file. And I then don't publish (make 'extern') any static
    >> data I define that I don't want other threads using or
    >> messing with.
    >>
    >> This works just fine. It's just fine to use static arrays in
    >> each thread and it's not even risky, so long as you make sure
    >> that other threads don't use the same static regions.
    >>
    >> You mentioned sprintf(). Let's say you don't have enough
    >> sram laying about on your micro. So you simply *must* use
    >> the same buffer for sprintf(), in all threads, because you
    >> have no other choice in the matter. Do you have a problem?
    >> Maybe. Not necessarily.
    >>
    >> We've been discussing a non-preemptive design all along. Keep
    >> that in mind. Yes, if the system were preemptive and could
    >> literally _tear_ control away from you, it would be a problem
    >> and _then_ you probably would need a semaphore to help
    >> arbitrate access to the buffer for sprintf(). But let's say
    >> this is NOT preemptive. In that case, there is no problem.
    >> When you call sprintf(), unless you re-write it, it will do
    >> the work you asked and then return. But since this is a
    >> cooperative system and changes to other threads can only
    >> occur when you call the thread switch code, there is no way
    >> for interference from other threads. You have control over
    >> the cpu, so there is no problem. So long as you get a chance
    >> to _use_ the buffer before you switch threads, or copy the
    >> part of it you need somewhere else, first.

    >
    >A common scenenario is the following:
    >
    >sprintf( buffer, "hello world\n" );
    >uart_sendstring( buffer );
    >
    >Now, if your uart_sendstring() puts stuff on an transmit FIFO for the
    >UART, and the FIFO happens to be full, you'd usually want the task to
    >sleep until there's some room in the FIFO.
    >
    >While the task is sleeping, another task is scheduled, that also
    >performs a sprintf() overwriting the buffer that was still used.


    Oh, yes!!

    As I said, so long as you do what needs to be done _before_
    allowing a context switch, it is fine. Your case is common
    and would violate my cautionary point. So good to bring it
    up.

    Jon
    Jon Kirwan, Sep 25, 2011
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. eeboy
    Replies:
    13
    Views:
    1,019
    Jon Kirwan
    Sep 17, 2011
  2. Jon Kirwan

    Re: Delta Queue Help - Paging Mr. Kirwan

    Jon Kirwan, Sep 20, 2011, in forum: Embedded
    Replies:
    12
    Views:
    445
    Arlet Ottens
    Sep 21, 2011
  3. Jon Kirwan

    Re: Delta Queue Help - Paging Mr. Kirwan

    Jon Kirwan, Sep 21, 2011, in forum: Embedded
    Replies:
    1
    Views:
    229
    Jon Kirwan
    Sep 21, 2011
  4. Jon Kirwan

    Re: Delta Queue Help - Paging Mr. Kirwan

    Jon Kirwan, Sep 25, 2011, in forum: Embedded
    Replies:
    0
    Views:
    328
    Jon Kirwan
    Sep 25, 2011
  5. Jon Kirwan

    Re: Delta Queue Help - Paging Mr. Kirwan

    Jon Kirwan, Sep 25, 2011, in forum: Embedded
    Replies:
    0
    Views:
    252
    Jon Kirwan
    Sep 25, 2011
Loading...

Share This Page