• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. post-execution on an interrupted SKILL routine

Stats

  • Locked Locked
  • Replies 5
  • Subscribers 143
  • Views 13841
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

post-execution on an interrupted SKILL routine

jaleco
jaleco over 5 years ago

I have a SKILL script that executes the callback of a menu item, and depends on first redefining an environment variable. 

When a user interrupts the script with ctrl-C, the script cannot finish to set the environment variable back to its default value.

How can I write the script in a way that handles a user interrupt to reset the changed environment variable after the interrupt?

  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett over 5 years ago

    What you need here is unwindProtect(). Here's a little example showing the principle - if you call runIt() and then use control-C during the run (quite easy to do because there are a trillion inner loop points, so enough time to interrupt it!), you'll see that the UNIX env var gets returned to its initial value (which you can check with getShellEnvVar("SOMEVAR") of course).

    procedure(verySlow()
      let((a)
        a=0
        for(i 1 1000000
          a=a+i
        )
        a
      )
    )
    
    procedure(extremelySlow()
      let((b)
        for(j 1 1000000
          b=mod(j 100)
          when(b==0
            printf("%d\n" j)
          )
          verySlow()
        )
      )
    )
    
    procedure(runIt()
      setShellEnvVar("SOMEVAR" "CHANGED")
      ; first function is form to be evaluated, and second is
      ; what to do as cleanup when the stack is unwound (because of
      ; error or interrupt). If you need more than one statement, 
      ; surround each with {} or a let() or something like that
      unwindProtect(
        extremelySlow()
        setShellEnvVar("SOMEVAR" "INITIAL")
      )
    )
    
    setShellEnvVar("SOMEVAR" "INITIAL")
    
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • jaleco
    jaleco over 5 years ago in reply to Andrew Beckett

    Thank you so much Andrew!

    Actually I do have more than one statement for the cleanupForm (the second function).

    Can you provide a sample of what you mean by enclosing each with { } or a let()?

    I'm not understanding the correct syntax of that part.

    Sounds like I could put the cleanupForm into a separate procedure.

    Also, it looks like the final setShellEnvVar() would need to be placed as the last line of the runIt() procedure, following the unwindProtect().

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to jaleco

    The unwindProtect functions works like this:

    unwindProtect(
        expressionToEvaluate
        expressionToAlwaysRunAtEnd
    )
    expressionThatIsNotGuaranteedToBeRun

    the second expression within the unwindProtect will always run, even if the first is interrupted, or fails with an error. The expression after the unwindProtect (that follows it) will not be evaluated if the code was interrupted or an error occurred, so you definitely do NOT what the final setShellEnvVar as the last line of the runIt procedure, following the unwindProtect().

    If  you want more than one expression to evaluate, or more than one expression to always run at the end, you need to either put those into a function you call, or simply group them:

    unwindProtect(
        {
            firstExprToEvaluate

            secondExprToEvaluate
            ...
            finalExprToEvaluate
        }
        {
            firstExprToAlwaysRunAtEnd
            ...

            finalExprToAlwaysRunAtEnd
        }
    )
    expressionThatIsNotGuaranteedToBeRun

    Note that instead of using {} you could also use other grouping functions, such as let or prog:

    unwindProtect(
        let((someLocalVar anotherLocalVar)
            firstExprToEvaluate

            secondExprToEvaluate
            ...
            finalExprToEvaluate
        )
        {
            firstExprToAlwaysRunAtEnd
            ...

            finalExprToAlwaysRunAtEnd
        }
    )
    expressionThatIsNotGuaranteedToBeRun

    Hope that's clearer?

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to jaleco

    The unwindProtect functions works like this:

    unwindProtect(
        expressionToEvaluate
        expressionToAlwaysRunAtEnd
    )
    expressionThatIsNotGuaranteedToBeRun

    the second expression within the unwindProtect will always run, even if the first is interrupted, or fails with an error. The expression after the unwindProtect (that follows it) will not be evaluated if the code was interrupted or an error occurred, so you definitely do NOT what the final setShellEnvVar as the last line of the runIt procedure, following the unwindProtect().

    If  you want more than one expression to evaluate, or more than one expression to always run at the end, you need to either put those into a function you call, or simply group them:

    unwindProtect(
        {
            firstExprToEvaluate

            secondExprToEvaluate
            ...
            finalExprToEvaluate
        }
        {
            firstExprToAlwaysRunAtEnd
            ...

            finalExprToAlwaysRunAtEnd
        }
    )
    expressionThatIsNotGuaranteedToBeRun

    Note that instead of using {} you could also use other grouping functions, such as let or prog:

    unwindProtect(
        let((someLocalVar anotherLocalVar)
            firstExprToEvaluate

            secondExprToEvaluate
            ...
            finalExprToEvaluate
        )
        {
            firstExprToAlwaysRunAtEnd
            ...

            finalExprToAlwaysRunAtEnd
        }
    )
    expressionThatIsNotGuaranteedToBeRun

    Hope that's clearer?

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
  • jaleco
    jaleco over 5 years ago in reply to Andrew Beckett

    Hi Andrew,

    Yes, that is much clearer - thank you so much again.  The description in the SKILL Language Reference is pretty spartan.

    Based on my incorrect interpretation of how unwindProtect actually works, your initial example looked something like this :

    procedure(verySlow()...); proc

    procedure(extremelySlow()...); proc

    procedure(runIt()...);proc

    setShellEnvVar()

    It didn't make sense to me that the final setShellEnvVar() was standalone.

    I had thought that the second function of unwindProtect() only executed in the case of an interrupt, and so was needed to include following unwindProtect() in the case of no interrupt.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to jaleco

    Sorry, I should have put a comment before that final top-level setShellEnvVar - it's there purely so that some initial value of the env var was set when I loaded the file.

    I'll take a look at the documentation tomorrow, and probably file a request with tech pubs to improve it (it wouldn't surprise me if it isn't terribly expansive with its explanation...)

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information