Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
 Welcome to our latest new user Coinoperator ! (Registered 2024-06-17) You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Some sort of multithreading.
2008-04-08 22:51
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....
 
2008-04-13 09:30
trident

Registered: May 2002
Posts: 81
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.
2008-04-13 09:45
Oswald

Registered: Apr 2002
Posts: 5032
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
2008-04-13 10:07
trident

Registered: May 2002
Posts: 81
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.
2008-04-13 10:22
Oswald

Registered: Apr 2002
Posts: 5032
"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.
2008-04-13 10:25
chatGPZ

Registered: Dec 2001
Posts: 11154
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.
2008-04-13 10:44
Oswald

Registered: Apr 2002
Posts: 5032
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.
2008-04-13 10:55
chatGPZ

Registered: Dec 2001
Posts: 11154
infact, it is :)
2008-04-13 11:02
Oswald

Registered: Apr 2002
Posts: 5032
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.
2008-04-13 11:33
chatGPZ

Registered: Dec 2001
Posts: 11154
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
2008-04-13 11:41
Oswald

Registered: Apr 2002
Posts: 5032
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
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Guests online: 106
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.7)
5 Edge of Disgrace  (9.7)
6 Uncensored  (9.6)
7 Comaland 100%  (9.6)
8 Wonderland XIV  (9.6)
9 No Bounds  (9.6)
10 Aliens in Wonderland  (9.6)
Top onefile Demos
1 Layers  (9.6)
2 Cubic Dream  (9.6)
3 Party Elk 2  (9.6)
4 Copper Booze  (9.6)
5 Rainbow Connection  (9.5)
6 It's More Fun to Com..  (9.5)
7 Dawnfall V1.1  (9.5)
8 Daah, Those Acid Pil..  (9.5)
9 Birth of a Flower  (9.5)
10 Quadrants  (9.5)
Top Groups
1 Nostalgia  (9.4)
2 Oxyron  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 SHAPE  (9.3)
Top Organizers
1 Burglar  (9.9)
2 Sixx  (9.8)
3 hedning  (9.7)
4 Irata  (9.7)
5 Tim  (9.7)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.056 sec.