semtake() in ISR - VxWorks

This is a discussion on semtake() in ISR - VxWorks ; Is there anyone to analyze the detail and possible result if calling blocking functions like semtake() in ISR? Anybody else has done such testing? -- nikeboysj posted via http://sysdminforum.com...

+ Reply to Thread
Results 1 to 16 of 16

Thread: semtake() in ISR

  1. semtake() in ISR


    Is there anyone to analyze the detail and possible result if calling
    blocking functions like semtake() in ISR?
    Anybody else has done such testing?


    --
    nikeboysj
    posted via http://sysdminforum.com


  2. Re: semtake() in ISR

    You CANNOT use semTake() in your ISR. An ISR doesn't run in a regular
    task context and has no taks control block. Actually, all ISRs share a
    single stack which depends on your BSP. Refer to vxWorks's guide for
    the restrictions and unfortunately semTake() is in the list. semGive()
    can be safely used in an ISR.
    nikeboysj wrote:
    > Is there anyone to analyze the detail and possible result if calling
    > blocking functions like semtake() in ISR?
    > Anybody else has done such testing?
    >
    >
    > --
    > nikeboysj
    > posted via http://sysdminforum.com



  3. Re: semtake() in ISR

    Well semTake can block - and you do not want that to happen for an ISR.
    However even though the documentation says in general semTake cannot be
    called from an ISR - I would think it would be safe to call semTake
    with a timeout of NO_WAIT which will return immediately (in which case
    if you do not get the semaphore you do not access the resource you are
    protecting with the semaphore).


  4. Re: semtake() in ISR

    Are you suggesting nikeboysj to build a unpredictable & indeterministic
    system?! Wish you were not intending to mislead people!


  5. Re: semtake() in ISR

    Frank wrote:
    > Are you suggesting nikeboysj to build a unpredictable & indeterministic
    > system?! Wish you were not intending to mislead people!


    IMO, although locking a sempahore from within an ISR (even with a
    NO_WAIT option) does'nt reflect a good design, i see no problem with
    Abhijit's post.

    And please quote context while replying.

    --
    Prafulla Harpanhalli


  6. Re: semtake() in ISR


    Frank wrote:
    > Are you suggesting nikeboysj to build a unpredictable & indeterministic
    > system?! Wish you were not intending to mislead people!


    Hi frank,
    While its bad to use semaphores inside ISRs,I have seen in PSOS which
    allows you to use ISRs which can take semaphores with NO_WAIT
    option.But as other othe author Martin has said,its not a good
    practice.
    Regards,
    s.subbarayan


  7. Re: semtake() in ISR


    Thanks for all of you.
    But I want to know what the "unexpredictable" result will be?
    Besides data protection lost and possible data corruption,
    any other results??
    In which conditions,exception reboot will appear as Martin Raabe just
    said.


    --
    nikeboysj
    posted via http://sysdminforum.com


  8. Re: semtake() in ISR

    I'd like to suggest a mechanizm recomended by WindRiver for interrupt
    handling...
    Make a task of rather high priority, it will consist of a FOREVER LOOP
    that waits for a semaphore. The contents of the task will contain the
    work you want done when servicing an interrupt. Now create an ISR that
    will contain one line "semGive();"
    Now when your interrupt fires, the ISR gives the semaphore and unblocks
    the task, and then the task will do all the work of the interrupt
    handler, then wait again for the semaphore. Now you can call anything
    you want withing the task.
    Good Luck!


  9. Re: semtake() in ISR

    Hello nikebo,
    nikeboysj ysj schrieb:
    > Thanks for all of you.
    > But I want to know what the "unexpredictable" result will be?
    > Besides data protection lost and possible data corruption,
    > any other results??
    > In which conditions,exception reboot will appear as Martin Raabe just
    > said.


    The question sounds like a question of a car driver:
    What will happen, when I drive along a street and jump out during the
    drive? Will the car survive, or will the car crash or will people get
    wounded?

    Yes, you can ask the question, but who is the right person to answer?
    Maybe the manufactorer of the vxWorks kernel or the HW guy or the power
    supply guy or ...?

    It is simply unpredictable!

    At least for us "simple" users and experts.

    Take care!

    --
    BaSystem Martin Raabe
    E: Martin.RaabeB-a-S-y-s-t-e-mde

  10. Re: semtake() in ISR

    Hello george,

    george.camann@gmail.com schrieb:
    > I'd like to suggest a mechanizm recomended by WindRiver for interrupt
    > handling...
    > Make a task of rather high priority, it will consist of a FOREVER LOOP
    > that waits for a semaphore. The contents of the task will contain the
    > work you want done when servicing an interrupt. Now create an ISR that
    > will contain one line "semGive();"
    > Now when your interrupt fires, the ISR gives the semaphore and unblocks
    > the task, and then the task will do all the work of the interrupt
    > handler, then wait again for the semaphore. Now you can call anything
    > you want withing the task.
    > Good Luck!


    This might be an approach, but I am afraid, that the original poster
    (OP) did not as for semGive() but for blocking calls LIKE semTake().
    So.

    BTW, if you take the hogh prior task and put it into a driver, then this
    is also a strategy Wind River recommends. ;-)

    --
    BaSystem Martin Raabe
    E: Martin.RaabeB-a-S-y-s-t-e-mde

  11. Re: semtake() in ISR

    Hi Martin & others,

    I hope everyone has understood what you have well explained.

    Now let me try some examples to demonstrate the badness of using
    semTake() in an ISR.

    Example-1:

    semaphore s1
    ISR A: semTake(s1)
    Task B: semGive(s1)
    As everyone can tell, since one can not predict when an interrupt
    arrives and if the s1 is available when the interrupt does arrive,
    there is no gurantee that the section protected in ISR A will be
    executed. The result is UNPREDICTABLE as explained already (even with
    NO_WAIT option).

    Example-2:

    ISR A: semTake(s2)
    ISR B: semGive(s2)
    Task C: semGive(s2)
    Task D: semTake(s2)

    Can someone tell me which is going to give s2 and which is going to
    take s2? The result will be messy.

    Example-3

    Now imagine one is building a system with nested interrupts with
    semTake() included in some ISRs. I think I don't elaborate for this
    case. The person who tries to build such a system should either quit or
    kill himself. :-)

    Thanks


  12. Re: semtake() in ISR

    Hello Frank,
    Frank schrieb:
    > Example-1:
    >
    > semaphore s1
    > ISR A: semTake(s1)
    > Task B: semGive(s1)
    > As everyone can tell, since one can not predict when an interrupt
    > arrives and if the s1 is available when the interrupt does arrive,
    > there is no gurantee that the section protected in ISR A will be
    > executed. The result is UNPREDICTABLE as explained already (even with
    > NO_WAIT option).
    >
    > Example-2:
    >
    > ISR A: semTake(s2)
    > ISR B: semGive(s2)
    > Task C: semGive(s2)
    > Task D: semTake(s2)
    >
    > Can someone tell me which is going to give s2 and which is going to
    > take s2? The result will be messy.
    >
    > Example-3
    >
    > Now imagine one is building a system with nested interrupts with
    > semTake() included in some ISRs. I think I don't elaborate for this
    > case.


    !!!Well said!!!


    > The person who tries to build such a system should either quit or
    > kill himself. :-)


    The second alternative is not necessary!

    --
    BaSystem Martin Raabe
    E: Martin.RaabeB-a-S-y-s-t-e-mde

  13. Re: semtake() in ISR

    Frank/Martin,

    I really don't understand what you guys are so worked up about. When
    you call semTake with NO_WAIT - it should be technically the same as
    calling the POSIX semaphore routine sem_trywait(). This means that when
    you call sem_trywait if the semaphore is available the caller will get
    the semaphore - otherwise sem_trywait will just return an error saying
    it is not available. There will be no blocking - no context switch -
    which means technically you should be able to call it from an ISR -
    assuming that the call to sem_trywait does not take a lot of time
    (should be same amount of time as semGive which can be called from ISR)
    and critical interrupts are lost as the interrupts are disabled when
    calling an ISR.

    Most of the times calling sem_trywait from an ISR will be a bad design
    - not only bad design it will not be feasible if the section protected
    by the semaphore MUST be executed. However if the "critical" section
    (accessing some shared data structures) protected by that semaphore is
    something that is not really mission critical but which can be only
    executed in that ISR - and can be executed at a later time then you can
    possibly use it:

    if (sem_trywait(my_sema) == OK)
    {
    Execute that non-mission critical stuff
    }
    else
    {
    Do nothing - may be update some failure stats
    }

    I do not really think of any particular case/example where I would need
    to do this - what I am saying is this type of thing can be
    theoretically done - especially if you are willing to accept the
    possibility that the that non-mission-critical code may never get
    executed if it never gets that semaphore.

    My point is that I believe the VxWorks documentation is missing this
    point (that it should be safe to call from an ISR) - if you really
    wanted to use this function call and have a strong case of using it you
    should have the facility to do it (and you should follow it up with
    WindRiver and find out from them if it can be done safely).

    For knowledge sake I am just attaching below the semaphore source code
    (along with the copyright notices that it can be distributed) of a
    simple educational operating system called Pintos (used at Stanford for
    their OS course - based on another educational OS called Nachos). In
    particular check sema_try_down which should be similar to
    semTake(NO_WAIT) or sem_trywait.

    This code can be also obtained from:
    http://www.stanford.edu/class/cs140/.../pintos.tar.gz

    By the way none of us has really answered nikeboysj's original
    question.

    Thanks,
    Abhijit

    /* This file is derived from source code for the Nachos
    instructional operating system. The Nachos copyright notice
    is reproduced in full below. */

    /* Copyright (c) 1992-1996 The Regents of the University of California.
    All rights reserved.

    Permission to use, copy, modify, and distribute this software
    and its documentation for any purpose, without fee, and
    without written agreement is hereby granted, provided that the
    above copyright notice and the following two paragraphs appear
    in all copies of this software.

    IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO
    ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
    CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE
    AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA
    HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
    BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
    PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
    MODIFICATIONS.
    */

    #include "threads/synch.h"
    #include
    #include
    #include "threads/interrupt.h"
    #include "threads/thread.h"

    /* Initializes semaphore SEMA to VALUE. A semaphore is a
    nonnegative integer along with two atomic operators for
    manipulating it:

    - down or "P": wait for the value to become positive, then
    decrement it.

    - up or "V": increment the value (and wake up one waiting
    thread, if any). */
    void
    sema_init (struct semaphore *sema, unsigned value)
    {
    ASSERT (sema != NULL);

    sema->value = value;
    list_init (&sema->waiters);
    }

    /* Down or "P" operation on a semaphore. Waits for SEMA's value
    to become positive and then atomically decrements it.

    This function may sleep, so it must not be called within an
    interrupt handler. This function may be called with
    interrupts disabled, but interrupts will be turned back on if
    we need to sleep. */
    void
    sema_down (struct semaphore *sema)
    {
    enum intr_level old_level;

    ASSERT (sema != NULL);
    ASSERT (!intr_context ());

    old_level = intr_disable ();
    while (sema->value == 0)
    {
    list_push_back (&sema->waiters, &thread_current ()->elem);
    thread_block ();
    }
    sema->value--;
    intr_set_level (old_level);
    }

    /* Down or "P" operation on a semaphore, but only if the
    semaphore is not already 0. Returns true if the semaphore is
    decremented, false otherwise.

    This function may be called from an interrupt handler. */
    sema_try_down (struct semaphore *sema)
    {
    enum intr_level old_level;
    bool success;

    ASSERT (sema != NULL);

    old_level = intr_disable ();
    if (sema->value > 0)
    {
    sema->value--;
    success = true;
    }
    else
    success = false;
    intr_set_level (old_level);

    return success;
    }

    /* Up or "V" operation on a semaphore. Increments SEMA's value
    and wakes up one thread of those waiting for SEMA, if any.

    This function may be called from an interrupt handler. */
    void
    sema_up (struct semaphore *sema)
    {
    enum intr_level old_level;

    ASSERT (sema != NULL);

    old_level = intr_disable ();
    if (!list_empty (&sema->waiters))
    thread_unblock (list_entry (list_pop_front (&sema->waiters),
    struct thread, elem));
    sema->value++;
    intr_set_level (old_level);
    }


  14. Re: semtake() in ISR


    Why we want to know the "possible result"?
    because when these "possible result" appear,we can easily link it to
    calling blocking functions in ISR. At least it will let us consider
    suspecting that.
    I think detail understanding will be beneficial to ananyze the real
    reason from various result atmosphere.


    --
    nikeboysj
    posted via http://sysdminforum.com


  15. Re: semtake() in ISR

    >Why we want to know the "possible result"?
    >because when these "possible result" appear,we can easily link it to
    >calling blocking functions in ISR. At least it will let us consider
    >suspecting that.
    >I think detail understanding will be beneficial to ananyze the real
    >reason from various result atmosphere.


    This is reasonable logic, but some things are 'undefined' -- trying to
    understand such things is a waste of time.
    However, in the context of vxWorks, a semTake() in an ISR will return
    ERROR without having touched the semaphore.
    You could check the return value of semTake() and, if it's ERROR,
    somehow check if you're in an ISR and, if you are, do something
    sensible....
    But, if you can remember to do all that, you can probably remember not
    to call semTake() from ISR code.
    ;-)


  16. Re: semtake() in ISR

    In vxWorks, you might not get the blocking scenario as you expect if
    you really "insist" on
    calling semTake() in an ISR.

    Let's put aside if a semaphore can be acquired by the ISR or not.
    Assuming some task relinquishes the semaphore and the following ISR is
    expected to acquire it.

    ISR()
    {
    . . .
    if (semTake(semaphore, timeout) == OK)
    {
    ... /* whatever section you expect to execute */
    }
    }

    This call of semTake() might simply return ERROR in all cases with
    errno=S_intLib_NOT_ISR_CALLABLE. Clearly, vxWorks has taken your case
    into consideration (This is only my guess based on what I understand
    from the documentation). I think this result is reasonable since an ISR
    does not run in a task context. The "blocking" we are talking about
    related to semaphore is related to tasks which are scheduled by the OS
    kernel. A task blocked by a semaphore is in "pended" state will be
    scheduled to the "ready" to run when the semaphore is acquired by it.
    An ISR does not have a TCB and no such state exists. Therefore the
    "blocking" scenario we have been talking about might never happen. No
    matter whether you assign the timeout value to NO_WAIT, WAIT_FOREVER or
    some number of ticks, the call of semTake() simply returns ERROR (no
    execution of the protected section whatsoever). If the semTake() in
    vxWorks is really implemented in this way, your ISR might not be doing
    what you expect but the whole system might still be in a health state.

    Well, what would happend if the call of semTake() in an ISR (in
    vxWorks' implementation) really blocks? The result might be catastropic
    in some cases.
    (1). In the case of NO_WAIT, the protected section might be simply
    skipped. The damage depends on the subsequence of the protected section
    missing being executed.
    (2). In the case of WAIT_FOREVER, the ISR blocks when the semaphore is
    NOT available when an interrupt invokes the ISR. Assuming you have an
    alarming mechanism (which every working system usually has, e.g.,
    watchdogs, etc), the result might be catastropic (such as system
    reboot).
    (3). In the case of that the timeout is of some number of clock ticks,
    it result depends on how long the timeout is and the chance of the
    availability of the semaphore when an interrupt arrives. Both
    scenarios (1) and (2) are possible. Generally, the system is
    unpredictable.

    I haven't done such tests myself. All my "wild" guesses are based on my
    limited understanding. I wonder if someone who has looked into the
    similar core code as vxWorks (e.g., Linux) might be able to give an
    much better insight analyses.

    Thanks

    nikeboysj wrote:
    > Why we want to know the "possible result"?
    > because when these "possible result" appear,we can easily link it to
    > calling blocking functions in ISR. At least it will let us consider
    > suspecting that.
    > I think detail understanding will be beneficial to ananyze the real
    > reason from various result atmosphere.
    >
    >
    > --
    > nikeboysj
    > posted via http://sysdminforum.com



+ Reply to Thread