Semephore Problems.


MadDog

Member
Joined
Mar 4, 2006
Messages
262
Age
54
Location
UK
Website
www.maddoggames.com
I've almost got my 920 and 940 talking to each other. The 920 writes commands in a buffer, the 940 reads them. The code for the 940 to wait when there is nothing to do works fine, this also prevents it from getting ahead of the 920.

Also the code stopping the 920 writing over work (catching up with its tail) works a treat too. But the code that stops the 920 from getting more than two frames ahead of th 940 is failing. This bit of code is the only bit that needs and is using a semephone.

I have an uncached var that the 920 inc's and the 940 dec's. There is also a var thats used to lock this counter so only one of the chips can write to it. This code is tricky to get right as if the 920 thinks its too far ahead then it will block and the 940 will be starved of work and will also block. Thus leaving the app bust.

This is the code on the 940, does the lock, dec's the var, then unlocks.

asm volatile(
"stmfd sp!, {r0-r3} \n"
"mov r1,#1 \n"
"mov r2,%0 \n"
"mov r3,%1 \n"
"lock_loop: \n"
" swp r3, r1,[r2] \n"//swap 1 into the lock
" cmp r3, #1 \n"//if a 1 was already there
" beq lock_loop \n"//go back and try again
"ldr r0,[r3] \n"//Get current frame count.
"sub r0,r0,#1 \n"//Dec by one,
"str r0,[r3] \n"//Store it
"mov r1,#0 \n"//set the lock to 0
"str r1,[r2] \n"//Store zero
"ldmfd sp!, {r0-r3} \n"
:
:"r"(&reg.cmd.cmd_buf->lock),"r"(&reg.cmd.cmd_buf->frames_in_command_buffer)
);


And this is the code on the 920 that does the lock, incs the var, unlocks then spins of the var is > 2.

asm volatile(
"stmfd sp!, {r5-r8} \n"
"mov r5,#1 \n"
"mov r7,%0 \n"
"mov r8,%1 \n"
"lock_loop: \n"
" swp r6, r5,[r7] \n"//swap 1 into the lock
" cmp r6, #1 \n"//if a 1 was already there
" beq lock_loop \n"//go back and try again
"ldr r6,[r8] \n"//Get current frame count.
"add r6,r6,#1 \n"//Inc by one,
"str r6,[r8] \n"//Store it
"mov r5,#0 \n"//set the lock to 0
"str r5,[r7] \n"//Store zero
"frame_ahead_lock: \n"
" ldr r6,[r8] \n"//Get current frame count.
" cmp r6,#2 \n"//If greater than 2, wait.
" bgt frame_ahead_lock \n"//Go back, we are too far ahead.
"ldmfd sp!, {r5-r8} \n"
:
:"r"(&command_buffer->lock),"r"(&command_buffer->frames_in_command_buffer)
);

Both chips get stuck on the lock loop waiting for it to go zero. I've got to have done something daft here. :(
 
Last edited by a moderator:
MadDog posted on May 26 2006 at 09:27 AM said:
This is the code on the 940, does the lock, dec's the var, then unlocks.

asm volatile(
"stmfd sp!, {r0-r3} \n"
"mov r1,#1 \n"
"mov r2,%0 \n"
"mov r3,%1 \n"
"lock_loop: \n"
" swp r3, r1,[r2] \n"//swap 1 into the lock
" cmp r3, #1 \n"//if a 1 was already there
" beq lock_loop \n"//go back and try again
"ldr r0,[r3] \n"//Get current frame count.
"sub r0,r0,#1 \n"//Dec by one,
"str r0,[r3] \n"//Store it
"mov r1,#0 \n"//set the lock to 0
"str r1,[r2] \n"//Store zero
"ldmfd sp!, {r0-r3} \n"
:
:"r"(&reg.cmd.cmd_buf->lock),"r"(&reg.cmd.cmd_buf->frames_in_command_buffer)
);
I am not sure if this is the cause of your problem but consider this section of that code:

mov r3,%1
lock_loop:
swp r3, r1,[r2]
cmp r3, #1
beq lock_loop
ldr r0,[r3]
sub r0,r0,#1

Here you seem to be using r3 as a pointer to the counter, but it is getting overwritten by the locking code before it is used. move the "mov r3, %1" below the "beq lock_loop" line.
 
Last edited by a moderator:
Anyway, there is a semaphore code sample in the ARM architecture manual (chapter A.9.5)

The file is often named ddi0100e_arm_arm.pdf in case you need to locate it, say, on your hard drive ... :p
 
Nothing jumps out at me in the 920 code to cause a lockup.

Is it possible that the 940 code could decrement the variable past zero?
 
Thats what i'm thinking, cmn is the monkey to use I think? Don't want to start with a bias as what ever it is thats causing that will still happen, that is if i'm correct with the logic and it should never go below zero.
 
Back
Top