Shop OBEX P1 Docs P2 Docs Learn Events
[resolved][puzzle] Identify yourself! — Parallax Forums

[resolved][puzzle] Identify yourself!

kuronekokuroneko Posts: 3,623
edited 2009-12-18 04:28 in Propeller 1
It's Friday the 13th and for some unexplained reason the cogid instruction stopped working. However, you urgently need this information, i.e. your cog's ID. All you know is:
  • At least one and at most four other cogs are running, doing stuff.
  • You are not allowed to disturb them or interfere with their operation.
  • PASM: par points to private scratch space, size 64 longs
How do you get your ID value?

Clarification: startup context
  • you wake up at location $000 in PASM district
  • Who are you?


Post Edited (kuroneko) : 12/25/2009 2:01:11 PM GMT

Comments

  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2009-12-17 09:40
    Should be pretty easy. YOU = "the cog that wants to Identify itself". Generate a program in the scratch area. Start it on a cog passing it a unique address in par. Store ID of the cog started. When started, the cog waits some time to get in sync, then performs a hubop (rdlong will do). Then it writes cnt to par, and commits suicide. Upon new cog startup, you also wait, hubop, write cnt, then waste 16 cycles. Now you know the distance on the hub wheel from yourself to the cog you have started (calculate from cnt difference), and using that distance and other cog ID, you can calculate your own ID. Note - you need just one additional cog to do this, and much less than 64 longs of scratch area.
  • VIRANDVIRAND Posts: 656
    edited 2009-12-17 09:41
    cog0 does something often, and the other cogs find out their order by waiting for it, and measuring how long they waited.
    If every cog wants its ID, they share the information on a stack in hub ram, so they can figure out which cogs had to wait
    more or less, and there will be a tendency for the stack to get reports from cogs in order. Just a guess. It involves counters
    or watching what other cogs are doing in the hub or some other global resource, relative to cog0, and cogself, methinks.
    There is timing, hub order, and global resources, and cog0, at least, to try to use to get ID, if that is how it is defined.

    edit:Hmmm. Did I break the rules of the game? I don't think so because a cog wouldn't expect a cogID failure, so it wouldn't
    be programmed to try something else. I assume someone has a broken Propeller and needs to use it anyway, and programmed
    to compensate. I would be very surprised if there is a way to handle an unanticipated failure like this one in runtime.

    Post Edited (VIRAND) : 12/17/2009 9:50:55 AM GMT
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2009-12-17 09:50
    VIRAND: what you missed is "puzzle" the topic title [noparse]:)[/noparse] It is just sort of brain excersise
  • kuronekokuroneko Posts: 3,623
    edited 2009-12-17 10:36
    You guys are fast [noparse]:)[/noparse] I'm running out of ideas!

    @Andrey: Yes, that is the basic idea. Although I'm not quite sure why you'd want to wait at all. Just do a hub op and record cnt. You always return from it at 16n+m. All you need is m. And yes, one free cog is enough and certainly less than 64 longs are required. But that would have been telling. It gets more tricky - if not impossible - when all 7 remaining cogs are in use.

    @VIRAND: This puzzle is not to be taken too seriously. Regardless, you can't make assumptions about existing cog IDs as reference. For all you know you could be cog 0. Getting the reference point was the challenge.

    Post Edited (kuroneko) : 12/17/2009 10:41:17 AM GMT
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2009-12-17 10:39
    @kuroneko: Well, you need to wait anyway, while the cog starts up, executes the code and stops. But you are right about the new cog - no wait is necessary there
  • kuronekokuroneko Posts: 3,623
    edited 2009-12-17 13:43
    For the terminally curious, a quick & dirty implementation of what was discussed.

    CON
      data = $1F5   ' outb
      addr = $1F7   ' dirb
      idnt = $1FB   ' frqb
      zero = $1FF   ' vscl
      
    DAT             org     0
    
    identify        mov     idnt, cnt               '  -4   get reference
    
                    mov     addr, par               '       transfer payload
    xfer            wrlong  payload, addr
                    add     xfer, dst1
                    add     addr, #4
                    djnz    loop, #xfer
    
                    mov     host, addr              '       prepare cognew
                    shl     host, #14
                    add     host, par
                    shl     host, #2
                    or      host, #%1000
    
                    coginit host wr                 '       invoke payload
    
                    wrlong  zero, addr
                    rdlong  data, addr wz           '       collect result
            if_z    jmp     #$-1
    
                    sub     idnt, data              '       calculate ID
                    shr     idnt, #1
                    add     idnt, host
                    and     idnt, #%0111
                    
                    mov     dira, demo              '       demo board LEDs
                    shl     idnt, #16
                    mov     outa, idnt
                    
                    waitcnt cnt, #0                 '       burn cycles
                    jmp     #$-1
    host
    loop            long    tail
    dst1            long    |< 9
    demo            long    $00FF0000
    
                    fit
                    
    payload         org     0
                    
                    or      $+4, cnt                '  -4   get reference
                    wrlong  $+3, par                '  +0 = 1st hub slot
                    cogid   cnt
                    cogstop cnt
    
                    long    %1_00000000
                    
    tail            res     1
    
                    fit
    

    Post Edited (kuroneko) : 12/17/2009 2:25:07 PM GMT
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-12-17 16:36
    Curious... why wouldn't this work?

    [b]CON[/b]
    
      [b]_CLKMODE[/b] = [b]XTAL1[/b] + [b]PLL16X[/b]
      [b]_XINFREQ[/b] = 5_000_000
    
    [b]PUB[/b] start|cog
    
    ID  := @cog
    cog :=  [b]cognew[/b](@PASM, 0) 
    
    [b]DAT[/b]     [b]org[/b]     0
    
    PASM
            [b]mov[/b]             temp,   ID
            [b]rdlong[/b]          temp,   temp
    
            [b]shl[/b]             temp,   #16
            [b]mov[/b]             [b]outa[/b],   temp
            [b]mov[/b]             [b]dira[/b],   LEDmask
                                     
    Endless_Loop                
            [b]jmp[/b]             #Endless_Loop
         
    'LED mask     
    LEDmask  [b]long[/b]     %00000000_11111111_00000000_00000000
    
    ID       [b]long[/b]           0
    temp     [b]long[/b]           0
    
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Cluso99Cluso99 Posts: 18,069
    edited 2009-12-17 23:34
    Beau: Nice LOL. kuroneko didn't say explicitly say cognew was failing smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
    · Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
  • VIRANDVIRAND Posts: 656
    edited 2009-12-17 23:40
    kuroneko said...
    You guys are fast [noparse]:)[/noparse] I'm running out of ideas!

    @Andrey: Yes, that is the basic idea. Although I'm not quite sure why you'd want to wait at all. Just do a hub op and record cnt. You always return from it at 16n+m. All you need is m. And yes, one free cog is enough and certainly less than 64 longs are required. But that would have been telling. It gets more tricky - if not impossible - when all 7 remaining cogs are in use.

    @VIRAND: This puzzle is not to be taken too seriously. Regardless, you can't make assumptions about existing cog IDs as reference. For all you know you could be cog 0. Getting the reference point was the challenge.

    I'm not an expert on the Propeller YET. I assumed that the Propeller always boots an initial instance of Spin in Cog0. No?
  • kuronekokuroneko Posts: 3,623
    edited 2009-12-18 00:30
    Beau Schwabe (Parallax) said...
    Curious... why wouldn't this work?
    I guess I was a bit vague about startup conditions, especially that you don't get told about yourself. Context should have been:
    • you wake up at location $000 in PASM district
    • Who are you?
    VIRAND said...
    I'm not an expert on the Propeller YET. I assumed that the Propeller always boots an initial instance of Spin in Cog0. No?
    It doesn't matter. The whole thing is a thought experiment. You don't get to chose startup conditions. All you know is that your code is invoked with par pointing at long storage[noparse][[/noparse]64].
  • RossHRossH Posts: 5,519
    edited 2009-12-18 01:21
    @all,

    Probably dumb questions, and I'm sure the answer is in the manual somewhere, but I'm at work at the moment, so here goes ...

    What is a cog that has not been explicitly started actually doing, and is there any way to tell (from another cog) that it is in this state?

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • kuronekokuroneko Posts: 3,623
    edited 2009-12-18 01:48
    @Ross:
    The Propeller Manual said...
    The COGSTOP instruction stops a cog whose ID is in the register CogID, placing that cog into a dormant state. In the dormant state, the cog ceases to receive System Clock pulses so that power consumption is greatly reduced.
    So I guess that means as far as other cogs are concerned, it doesn't exist. Even with a particular cog running, unless it wants to talk to you you have no way of telling unless you know that it's doing something specific at a certain time ... and even that might be hard to observe.

    What are you after?
  • RossHRossH Posts: 5,519
    edited 2009-12-18 02:03
    Hi Kuroneko,

    Thanks for that. I'd really like an instruction (or small piece of code) that could tell me the state of a cog - it would make dynamic allocation of cogs a bit easier - i.e. when a cog has finished it simply stops itself, and then the system can detect that and re-use the cog for something else. At the moment, I think I'd have to be able to poll the cog, or or have the cog set a flag when it's finished.

    Just starting to think about a possible new Catalina-compatible Prop OS (codename "Catalyst").

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-12-18 02:52
    kuroneko,

    " * you wake up at location $000 in PASM district
    * Who are you?"


    lol - sounds like a bad night... or a good one depending on your particular preference. smilewinkgrin.gif

    You did say that it was Friday the 13th though.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 12/18/2009 3:17:41 AM GMT
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2009-12-18 03:33
    Ross, it is possible to write [noparse][[/noparse]very slow] code to detect which cogs are running - but this information can become outdated next clock cycle - any cog can issue COGINIT, and you would not know.

    In OS environment, the best would be to assume that tasks/programs do not use COGINIT/COGSTOP, but call OS services for such things.
  • RossHRossH Posts: 5,519
    edited 2009-12-18 03:40
    @Hi Andrey,

    I'd be interested in seeing any such code you know of. The problem with imposing a 'procedural' solution is that sometimes users will want to run existing SPIN programs that don't abide by the procedures.

    Of course, I understand that any information you get will only be aproximate - but it would still be handy to be able find out (aproximately) how many cogs an 'unknown' program (i.e. one for which you have only a binary file) actually uses.

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • kuronekokuroneko Posts: 3,623
    edited 2009-12-18 03:42
    Andrey Demenev said...
    ... it is possible to write [noparse][[/noparse]very slow] code to detect which cogs are running ...
    Can you elaborate?

    Post Edited (kuroneko) : 12/25/2009 5:55:08 AM GMT
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2009-12-18 04:10
    I could write the code later, now I am busy with work. For now, I just express the idea. Issue COGINIT to start a free cog. If cog has not been started - you know all cogs are busy. Otherwise, you know first free cog ID. The started cog performs the same operation, passing the cog ID it starts (or "no free" flag) to "parent" cog. Repeat this recursively up to 7 times - and you are done. Use a location in HUB memory through which cogs would signal they are done. Each new started cog stops itself after its "child" has stopped (or no free cogs available). Sort of recursive approach [noparse]:)[/noparse]
  • RossHRossH Posts: 5,519
    edited 2009-12-18 04:28
    Andrey,

    Yes, that should work. Thanks.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
Sign In or Register to comment.