Shop OBEX P1 Docs P2 Docs Learn Events
Wierd behavior with VAR variable placement — Parallax Forums

Wierd behavior with VAR variable placement

lardomlardom Posts: 1,659
edited 2013-01-21 21:26 in Propeller 1
I managed to get two cogs modify their variables without causing one cog to hang.
The rules for parallel processes I've learned include:
a) You can't share variables
b) Infinite loops do not return to the caller and can only by over-ridden by a cognew command
c) method calls must come from the launched cogs to preserve parallel processes
I have noticed unexplainable delays with the 'b / B' methods simply from where I position variables in the VAR block. Can anyone tell me what's going on?
CON

    _clkmode  = xtal1 + pll16x
    _xinfreq  = 5_000_000
      
 {change pin from 6 to 7
 removed variable references to A and object hung
 removed 'stackA[40], period_a, and finally index---works
 move A and B variables to separate lines-----works
 duplicate B and change to A and see if it still works
 B still works with A methods and variables added
 A works alone and changed pin from 7 to 6  }

var
   word  cogB
   word  cogA       
   long  stackB[10], period_b, indexB,  stackA[10], period_a, indexA  
 '  long  stackA[10], period_a, indexA      
      

pub start  

   stop_b
   cogB := cognew(main_b(2), @stackB) + 1
   stop_a
   cogA := cognew(main_a(2), @stackA) + 1
   
PUB stop_b

    if cogB
      cogstop(cogB~ - 1)          

PUB stop_a

    if cogA
      cogstop(cogA~ - 1) 

pub main_b(V) | idx       
     
    dira[7]~~    
    period_b := clkfreq/V      
    
    repeat   idx from 1 to 3
      outa[7]~~
      waitcnt(period_b + cnt)   
      outa[7]~
      waitcnt(period_b + cnt)
    
    New_b       

pub main_a(V) | idx       
     
    dira[6]~~    
    period_a := clkfreq/V      
    
    repeat   idx from 1 to 3
      outa[6]~~
      waitcnt(period_a + cnt)   
      outa[6]~
      waitcnt(period_a + cnt)
    
    New_a       


PUB New_b 

    indexB := indexB + 2      
    if indexB > 35
      indexB := 2

    main_b(indexB)

PUB New_a 

    indexA := indexA + 2      
    if indexA > 35
      indexA := 2

    main_a(indexA)
                  

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2013-01-21 09:40
    I think your stacks are overflowing. Increase the stack sizes from 10 to 20, and it might work better.
  • lardomlardom Posts: 1,659
    edited 2013-01-21 09:55
    @Dave Hein, I changed the stack sizes to 20 and then random sizes up to 200 and as low as 5 the leds behavior changed but they were still weird.
  • lardomlardom Posts: 1,659
    edited 2013-01-21 10:19
    Ha! I just found it... I was using a single local variable "idx" in two separate methods. I instead inserted "idxA" and "idxB" into the VAR block. I guess mixing the two types caused the conflict. I'll test some more to pinpoint the source of the conflict.
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-01-21 10:20
    OK, well I looked at your code a little closer, and the main problem is that you calling new_x from main_x, and then main_x from new_x. This is known as recursive calling, which will quickly overflow any stack size you define. Add a repeat to the beginning of your main_x routine, and remove the call to main_x from new_x. Also, increase the stack size from 10 to 20.

    EDIT: Using idx by both cogs is not a problem since this is a stack variable, and each cog has it's own stack space.
  • Mike GreenMike Green Posts: 23,101
    edited 2013-01-21 10:40
    "rules" that are not what they seem:
    a) You can't share variables
    b) Infinite loops do not return to the caller and can only by over-ridden by a cognew command
    c) method calls must come from the launched cogs to preserve parallel processes
    Reality:
    a) You can share variables, but you have to do it remembering that both cogs can change the variable at the same time and one cog can change a variable between two references to the variable in the other cog. In other words, A + A may not be the same as 2 * A.
    b) Infinite loops do not return to the caller. When did they ever return to the caller? They can't be over-ridden by a cognew. The only way a cog in an infinite loop can be affected by another cog is to do a COGSTOP on that cog to reset it or do a COGINIT on that cog to force a new program to be loaded and executed or possibly modify a hub value referenced in the infinite loop (if it's written that way) to turn the infinite loop into an exiting loop.
    c) A method call is done by a specific cog because that's the cog whose Spin interpreter is executing the call. There's nothing about preserving parallel processes. Each cog is a (mostly) separate computer that happens to be (interpretively) executing code in a memory that's shared by all the cogs. The interpretive code is read-only and can be simultaneously interpreted by more than one cog, each with its own data area (its stack). There's also a shared data area where you have to be careful about how the data is used.

    Try to keep separate the ideas of objects and parallel processing. They're really orthogonal. You can have a program consisting of a single (main) object that uses all 8 Propeller cogs to do things. 7 of the 8 cogs can all be executing the same single method with the 8th cog executing the main program which can also call the same method once things are set up. You can also have a multi-object program with multiple levels of objects, all using only a single cog. There's no direct absolute relationship between the two concepts.
  • lardomlardom Posts: 1,659
    edited 2013-01-21 21:26
    @Dave Hein, I eliminated the recursive calling. I just read about pushing and popping the stack last week but still didn't see my error. I'm a bit slow at times. Thanks for pointing it out. I also declared a second copy of the object. It just occurred to me that by making two cognew commands I was trying to put different methods of the same object into separate cogs.
    @Mike Green, I pay attention to what you say pretty closely. Lessons learned.
Sign In or Register to comment.