PDA

View Full Version : [resolved][puzzle] Identify yourself!



kuroneko
12-17-2009, 04:47 PM
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

Andrey Demenev
12-17-2009, 05:40 PM
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.

VIRAND
12-17-2009, 05:41 PM
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 Demenev
12-17-2009, 05:50 PM
VIRAND: what you missed is "puzzle" the topic title :) It is just sort of brain excersise

kuroneko
12-17-2009, 06:36 PM
You guys are fast :) 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 Demenev
12-17-2009, 06:39 PM
@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

kuroneko
12-17-2009, 09:43 PM
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 Schwabe
12-18-2009, 12:36 AM
Curious... why wouldn't this work?




CON

_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000

PUB start|cog

ID := @cog
cog := cognew(@PASM, 0)

DAT org 0

PASM
mov temp, ID
rdlong temp, temp

shl temp, #16
mov outa, temp
mov dira, LEDmask

Endless_Loop
jmp #Endless_Loop

'LED mask
LEDmask long %00000000_11111111_00000000_00000000

ID long 0
temp long 0



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe (mailto:bschwabe@parallax.com)

IC Layout Engineer
Parallax, Inc.

Cluso99
12-18-2009, 07:34 AM
Beau: Nice LOL. kuroneko didn't say explicitly say cognew was failing http://forums.parallax.com/images/smilies/smile.gif

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

· Home of the MultiBladeProps: TriBlade (http://forums.parallax.com/showthread.php?p=786418),·RamBlade (http://forums.parallax.com/showthread.php?p=849265),·SixBlade (http://forums.parallax.com/showthread.php?p=780033), website (http://bluemagic.biz/cluso.htm)
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator) (http://forums.parallax.com/showthread.php?p=790917)
· Prop Tools under Development or Completed (Index) (http://forums.parallax.com/showthread.php?p=753439)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) (http://forums.parallax.com/showthread.php?p=778427) ZiCog (Z80) (http://forums.parallax.com/showthread.php?p=788511) , MoCog (6809) (http://forums.parallax.com/showthread.php?p=811043)
· Search the Propeller forums (http://search.parallax.com/search?site=parallax&client=parallax&output=xml_no_dtd&proxystylesheet=parallax&proxycustom=<HOME/>&ie=&oe=&lr=)·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz (http://www.bluemagic.biz)·· MultiBladeProp is: www.bluemagic.biz/cluso.htm (http://www.bluemagic.biz/cluso.htm)

VIRAND
12-18-2009, 07:40 AM
kuroneko said...
You guys are fast :) 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?

kuroneko
12-18-2009, 08:30 AM
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[64].

RossH
12-18-2009, 09:21 AM
@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 (http://forums.parallax.com/showthread.php?p=844004)

kuroneko
12-18-2009, 09:48 AM
@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?

RossH
12-18-2009, 10:03 AM
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 (http://forums.parallax.com/showthread.php?p=844004)

Beau Schwabe
12-18-2009, 10:52 AM
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. http://forums.parallax.com/images/smilies/smilewinkgrin.gif

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

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe (mailto:bschwabe@parallax.com)

IC Layout Engineer
Parallax, Inc.

Post Edited (Beau Schwabe (Parallax)) : 12/18/2009 3:17:41 AM GMT

Andrey Demenev
12-18-2009, 11:33 AM
Ross, it is possible to write [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.

RossH
12-18-2009, 11:40 AM
@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 (http://forums.parallax.com/showthread.php?p=844004)

kuroneko
12-18-2009, 11:42 AM
Andrey Demenev said...
... it is possible to write [very slow] code to detect which cogs are running ...

Can you elaborate?

Post Edited (kuroneko) : 12/25/2009 5:55:08 AM GMT

Andrey Demenev
12-18-2009, 12:10 PM
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 :)

RossH
12-18-2009, 12:28 PM
Andrey,

Yes, that should work. Thanks.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Catalina - a FREE C compiler for the Propeller - see Catalina (http://forums.parallax.com/showthread.php?p=844004)