Shop OBEX P1 Docs P2 Docs Learn Events
Number of cogs remaining? — Parallax Forums

Number of cogs remaining?

jmspaggijmspaggi Posts: 629
edited 2010-10-06 05:54 in Propeller 1
Hi,

Is there a way to know how many cogs are remaining?

I did that:
  '' Wait 10 seconds to ensure everything is running and count the number of available cogs.
  waitcnt(cnt + clkfreq * 10)
  availableCogs := 0
  repeat while (cognew(doNothing, @doNothingStack) <> -1)
    availableCogs++

But maybe there is a better way?

I want to know that because I'm using many object from OBEX and I don't know why is using a COG, and which is not.

Thanks,

JM

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-10-05 15:11
    What you're doing is correct. You may also want to keep track of which cog numbers are returned by cognew so you can release them with cogstop once your test is complete.

    -Phil
  • jmspaggijmspaggi Posts: 629
    edited 2010-10-05 15:50
    Good idea!

    I have a cog which manage the display. I will add that into it so I will always have an eye on the status.

    Thanks for the suggestion.

    JM
  • BluhairBluhair Posts: 7
    edited 2010-10-06 03:01
    The code has me lost.

    '' Wait 10 seconds to ensure everything is running and count the number of available cogs.
    waitcnt(cnt + clkfreq * 10)
    availableCogs := 0
    repeat while (cognew(doNothing, @doNothingStack) <> -1)
    availableCogs++

    I tried the code several different ways, none of which worked.

    1. Inserting the code as an object and I get the expected an expression term error.
    2. By calling the DoNothing.spin code I receive Expected ".". error.
    This I understand because the DoNothing.spin has nothing to return and no parameters.

    I understand this may only be an "explanation code" but it sure would help if you would expain some of the hidden stuff.
    I use the forum to learn doing things in new ways and it is very valuable to me.
    But sometimes very frustrating.

    Thank You
  • Heater.Heater. Posts: 21,230
    edited 2010-10-06 03:22
    Let's assume that doNothing is a method in the same spin file as your cog test loop and you have a little stack for it looks like this:
    VAR
        long doNothingStack[10]
        long availableCogs
    
    PUB start
    '' Wait 10 seconds to ensure everything is running and count the number of available cogs.
        waitcnt(cnt + clkfreq * 10)
        availableCogs := 0
        repeat while (cognew(doNothing, @doNothingStack) <> -1)
        availableCogs++
    
    PUB doNothing
        'Do nothing repeatedly
        repeat
    

    Then your cog counting loop should work.

    I think you must have "repeat" in the doNothing otherwise it will finish execution, having done nothing, and the cog will be stopped. Then the same cog will be asked to do nothing again by your cog counting loop.
  • Heater.Heater. Posts: 21,230
    edited 2010-10-06 03:27
    Note:

    1) The above example only has one stack for starting all cogs. This is generally not a good idea but here it does not matter.

    2) At the end of the cog counting loop all the cogs are used "doing nothing" therefore there are no free cogs and the result in availableCogs is wrong:)
  • jmspaggijmspaggi Posts: 629
    edited 2010-10-06 04:18
    The example you gave is close to what I did, except that I used a way bigger stack ;)

    Now, let's try to remove the issue #2 with PhiPi's suggestion:
    VAR
      byte availableCogs
      long doNothingStack [10]
      byte availableCogsNumbers[8]
      byte cogNumber
      byte index
    
    PUB countCogs
      availableCogs := 0
      repeat while ((cogNumber := cognew(doNothing, @doNothingStack)) <> -1)
        availableCogsNumbers[availableCogs++] := cogNumber
      if (availableCogs > 0)
        repeat index from 0 to availableCogs - 1
          cogstop(availableCogsNumbers[index])
    
    PUB doNothing
        'Do nothing repeatedly
        repeat
    

    @Bluhair: doNothing is not a spin file, but a method into the current spin file. Also, on Heater's exemple, you need to indent "availableCogs++" to the right to have it on the loop. So you need to cut and past those 2 methods in your existing object to have them working. Same for the VAR section. Add them to your existing VAR section. Let us know if it's still not working for you.

    JM
  • Heater.Heater. Posts: 21,230
    edited 2010-10-06 05:05
    Turns out that:
    PUB doNothing
        repeat
    

    requires 6 LONGS of stack.
  • jmspaggijmspaggi Posts: 629
    edited 2010-10-06 05:22
    So here is the question ;)

    How did you calculat that, and what is the stack for? I always give about 32 longs just to be safe. Is the stack used to store the cog code? Which mean is need to be as big as the Spin code translated in PASM will be?

    JM
  • Heater.Heater. Posts: 21,230
    edited 2010-10-06 05:34
    jmspaggi,

    I did not calculate the stack size, I just kept reducing it until the program failed:)

    The stack does not hold the cog code.

    Consider, you can call the same method from many places in your code. Therefore it is necessary for the address at which to continue after the call has returned to be remembered somewhere. That somewhere is in the stack area.

    Of course the called method can call other methods, again those return addresses are remembered on the stack. And so on.

    Also if the called method has parameters they must be "passed" to the method some how. This is also done on the stack.

    If the called method has local variables they will also live on the stack temporarily.

    Finally the method it self may need some "scratchpad" working memory in which to evaluate complicated expressions. This scratchpad will also exist temporarily on the stack.

    So as you see calculating the required stack size is in general rather complicated.

    Normally you can make a guess and double it. Or keep reducing it until your program fails.

    If you really want to know then define a large stack, run your method, when it is finished print out the contents of the stack array. There you will see where it has been writing or not.

    P.S. Spin code is not translated to PASM. Rather it is translated to a sequence of byte code instructions which is then interpreted by a built-in PASM program running in the started COG.
  • jmspaggijmspaggi Posts: 629
    edited 2010-10-06 05:54
    Ok, I see.

    A bit to much complicated for a beginner ;) I like the idea of looking at the stack content after the call! When my project will be done, I will do that for each call to clear the un-used memory.

    Thanks!

    JM
Sign In or Register to comment.