| | gregg Account closed
Registered: Apr 2005 Posts: 56 |
Some sort of multithreading.
About a week ago the topic multithreading came up on #c-64. So today I gave it a try. However, there's something wrong with my code and I can't really figure out what it is.
A short description: I have a fixed number of threads running and a CIA IRQ deals with context switching in a round-robin fashion. Every IRQ I save all current state data (SP, status register, PC, A, X, Y) in a structure and fetch the state data for the next thread.
In this example the first thread increments the screen background color (fast), while the second thread changes the border background color (slow). However the wait in the second thread runs too fast every other time, and I have no idea why. It's probably something wrong with the context switch stuff, maybe some of you could take a look at it?
Sources are for ACME.
!to "threading.prg",cbm
!cpu 6510
;!source "mylib.a"
!macro basic_header .a, .b, .c, .d {
*= $0801
!byte <.eol,>.eol,0,0,$9e
!text .a, .b, .c, .d
.eol: !byte 0,0,0
}
num_threads = 2
thread_num = $fd ; current thread number
;--------------------------------------------------------------------------
+basic_header "2", "0", "6", "1"
*= $080d
init: sei
; set up context switch IRQ
lda #$35
sta $01
lda #<context_switch
ldx #>context_switch
sta $fffe
stx $ffff
lda #0
sta thread_num
cli
jmp thread1
;--------------------------------------------------------------------------
context_switch:
pha
txa
pha
tya
pha
lda $dc0d
; save current thread
lda thread_num
; *8
asl
asl
asl
tay
; save A,X,Y
pla
sta thread_data+6,y
pla
sta thread_data+5,y
pla
sta thread_data+4,y
; save PSW
pla
sta thread_data+1,y
; save PC
pla
sta thread_data+2,y
pla
sta thread_data+3,y
; save SP
tsx
txa
sta thread_data,y
; next thread, wraparound
ldy thread_num
iny
cpy #num_threads
bne +
ldy #0
+ sty thread_num
; *8
tya
asl
asl
asl
tay
; restore thread data
; stack pointer first
lda thread_data,y
tax
txs
; push PC, PSW for RTI
lda thread_data+3,y
pha
lda thread_data+2,y
pha
lda thread_data+1,y
pha
; push registers
lda thread_data+6,y
pha
lda thread_data+5,y
pha
lda thread_data+4,y
pha
pla
tay
pla
tax
pla
rti
;--------------------------------------------------------------------------
thread1:
inc $d021
ldy #$02
jsr wait2
jmp thread1
thread2:
inc $d020
ldy #$80
jsr wait2
jmp thread2
wait2:
- ldx #0
dex
bne *-1
dey
bne -
rts
;--------------------------------------------------------------------------
thread_data:
!fill 8, 0
!byte $ff-$40, $22, <thread2, >thread2, 0,0,0,0
|
|
... 211 posts hidden. Click here to view all posts.... |
| | trident
Registered: May 2002 Posts: 91 |
Oswald: you just described preemptive multithreading: the IRQ is one thread that preempts the main thread. "Multithreading" is just the name for it.
Using the stack to save the regs = context switch. Context switching is not expensive on a 6502 since there is no memory protection. |
| | Oswald
Registered: Apr 2002 Posts: 5094 |
this is not multithreading nor tasking. for that the irq "task" should be handled like:
a) save and restore the irq's cpu state on exit/enter. this doesnt happen. there's only "context switch" for one "thread". there's no seperate stacks, etc.
b) there are no fixed exit and entry points of real threads like the irq in my example
|
| | trident
Registered: May 2002 Posts: 91 |
Saving state is done implicitly when registers and the CPU status word are pushed onto the stack. Multiple stacks are not necessary, since there is only one level of preemption: the IRQ thread runs on the same stack as the main thread. Switching between multiple "main" threads is easy too, since one can use different parts of the stack at $100 for different threads: ldx $stack_pointer_of_the_other_thread; txs; jmp $ea81;
But, as you say, preemtpive multithreading is often not the most efficient way to get the job done (and is obviously no silver bullet). The nice thing with timer-based preemptive multithreading is that you don't need to specify things like "modify the loader to exit after every xth byte" or "calculate x mandelbrot pixels", but you can say "load data from the drive during the next 10 raster lines" or "rotate vectors for 20 raster line", without needing to specify exactly how many bytes to load, pixels to calcluate, or vectors to rotate.
At the end of the day, it is just another tool in the toolbox. |
| | Oswald
Registered: Apr 2002 Posts: 5094 |
"Saving state is done implicitly when registers and the CPU status word are pushed onto the stack. "
once again: the interrupt "thread"'s state is not saved anywhere. threads have no fixed entry and exit points. even if it were multithreading it were not a premptive one: "Cooperative multithreading, on the other hand, relies on the threads themselves to relinquish control once they are at a stopping point"
also: "Threads do not own resources except for a stack, a copy of the registers including the program counter, and thread-local storage"
since when does an irq have an own stack, copy of registers, and program counter?
get your facts straight please. |
| | chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:
since when does an irq have an own stack, copy of registers, and program counter?
thats pretty common on many architectures actually...and in a way, you can do it on c64 aswell. that you have to adjust said things "manually" in the isr is mostly an implementation detail, not a violation of the basic principle. |
| | Oswald
Registered: Apr 2002 Posts: 5094 |
Groepaz, possibly. but in my example the irq doesnt has an own stack/pc/registers, so I beg trident not to call that approach preemptive multithreading. its neither preemptive/multithreading. |
| | chatGPZ
Registered: Dec 2001 Posts: 11386 |
infact, it is :) |
| | Oswald
Registered: Apr 2002 Posts: 5094 |
please define exactly what do you think is:
a) multithreadnig
b) a thread
c) preemptive
then show me how is my example a preemptive multithreading. thanks in advance. |
| | chatGPZ
Registered: Dec 2001 Posts: 11386 |
i am not going to write a dozen pages of text here, really. also trident is in a much better position to explain it, so i'll leave it to him. if he cares anyway =P |
| | Oswald
Registered: Apr 2002 Posts: 5094 |
maybe you shouldnt troll around as a mod, and state stupid things which are untrue. can you prove it ? no. then stop trolling. now you may modify your own post to "sorry for trolling :("
thanks in advance. |
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ... | 22 | 23 - Next | |