MaxCoderz

for your 1 bit pleasure!

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: [TI ASM] atomics
PostPosted: Sat 30 Apr, 2011 3:37 pm 
Offline
Calc King

Joined: Sat 05 Aug, 2006 7:22 am
Posts: 1513
I've been working on threading on the z80 a bit, and I don't really like hacking around with di/ei all the time. It's especially annoying when you don't know whether interrupts are disabled already or not and you want to nice and leave them disabled.
So I needed some atomic stuff to implement locks and the like (which are also hugely useful by themselves in a multithreaded context)

I have this one:
Code:
testandset:
   ld hl,tas_thingy
   scf
   jp (hl)
tas_thingy:
   res 1,(hl) ; changes itself to ret (res = 11001011)
   or a
   ret

I suppose I use "ld (hl),$C9" instead but whatever.

It's nice for locks, but locks have "the lock problem" and otherwise TaS is a pretty weak routine with a consensus number of just 2.

Are more powerful atomic constructs possible on the z80?

In the mean time, here are some more "Test and Set"-like things.
Code:
rlc (hl)
ret
ret
; changes itself into
sub a
ld b,$C9
ret

"useful" because the result is in both the Z and C flags. Bad because it kills b.
Code:
rrc (hl)
ret
ret
; changes itself into
push hl
ld c,$C9
ret

Potentially useful because the push hl/ret automatically sends it into a loop when it fails. Bad because it kills c.

Code:
sla (hl)
ret
; changes itself into
sub (hl)
ld h,(hl)
ret

Potentially useful because it's the shortest TaS-like instruction sequence I've found (if called with A = 10010110, the result is in the Z flag. call with A >= 10010110 for result in C flag) - kills A though, obviously (and sometimes h, but that's less of an issue)


Last edited by King Harold on Sun 01 May, 2011 4:25 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: [TI ASM] atomics
PostPosted: Sat 30 Apr, 2011 7:49 pm 
Offline
New Member

Joined: Sun 06 Feb, 2011 7:08 am
Posts: 42
Sorry, I have no clue what any of this means :/ I just figured I would post so that you know somebody is reading this XD

I haven't tested this (I just threw it together), but this should give an idea for detecting if interrupts are enabled or not:
Code:
;============================
;This will store the interrupt status in the P/V flag
;============================
     push bc         ;C5
     ld b,a          ;47
     ld a,i          ;ED57             ;This stores the interrupt status in the p/v flag. I think set= interrupts active
     ld a,b          ;78
     pop bc          ;C1
;============================
     push af         ;F5      ;This is to save the P/V flag
     di              ;F3
;More code
     pop af          ;F1
     ret po          ;E0               ;If this doesn't work, try pe XD
     ei              ;FB
     ret             ;C9


Top
 Profile  
Reply with quote  
 Post subject: Re: [TI ASM] atomics
PostPosted: Sun 01 May, 2011 4:33 am 
Offline
Calc King

Joined: Sat 05 Aug, 2006 7:22 am
Posts: 1513
Yea I know that one, but as you can see it's a bit of a bother and it's only an option when the code in between is "fast enough" - and you can't transparently wrap any code in this, because you need "special code" to return something in A

There is no "fetch-and-de/increment", but inc and dec are atomic and give just enough information in the flags for a simple (ie breaking on too many releases) unfair semaphore (it's biased by 1, so 1 means "none" and it only goes up to 126):
Code:
Wait:
   dec (hl)
-:
   jp m,{+}
   ret nz
+: ; val is <= 0
   ; yield
   xor a
   or (hl)
   jr {-}

Release:
   inc (hl)
   ret

And here is a version of Release that blocks until it wouldn't overflow (only for "single writer" where the one doing the release is seen as the writer):
Code:
Release:
-: inc (hl)
   ret po
   dec (hl)
   ; yield
   jr {-}

It would temporarily leave the semaphore counter in overflowed state and that would block any Wait operations in the meantime - but that's not actually harmful, just a bit "less than optimal"
You can use a pair of these single-writer multiple-reader semaphores to create a multiple-reader multiple-writer semaphore.

Even simpler (only for single-reader, single-writer):
Code:
wait:
   dec (hl)
   ret po
   inc (hl)
   ; yield
   jr wait

release:
   inc (hl)
   ret po
   dec (hl)
   ; yield
   jr release

It's biased by $80 so it has $80 = zero. And it goes up to 255 (which is represented by $7F).
Again, it can leave the semaphore counter in overflowed state, but that's OK, it just temporarily blocks the other thread as well (very shortly and only with lots of bad luck).
I love the symmetry and the fact that it doesn't destroy any regs. You can't turn it into a multiple-anything though.


Top
 Profile  
Reply with quote  
 Post subject: Re: [TI ASM] atomics
PostPosted: Sun 01 May, 2011 7:39 am 
Offline
Calc King

Joined: Sat 05 Aug, 2006 7:22 am
Posts: 1513
Autocopy adds some more fun:
Code:
rlc b,(ix+%001xx000)
; becomes
sub a
jr xx,0

You can change the xx bits to whatever, the jump has an offset of zero anyway so it's irrelevant.
The result is in both Z and C flags.
Downsides: kills A and B, and is pretty big (5 bytes if a ret is included)

But that pattern can be still be useful. You know the condition is going to be Z+NC at that jump, and you can use any offset up to and including 7 (with 6 being a special nice case in that it isn't an autocopy and so doesn't destroy regs and 7 autocopying to A which is killed anyway - though in a different way)
You can use this to skip whatever is done after the rlc (up to 7 bytes anyway) and do whatever you want (such as, for example, marking the thread as Waiting)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB ® Forum Software © phpBB Group | DVGFX2 by: Matt