Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
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 11:44
chatGPZ

Registered: Dec 2001
Posts: 11386
you have an interisting definition of trolling, really :)
2008-04-13 11:49
gregg
Account closed

Registered: Apr 2005
Posts: 56
The effect thread interrupts the main thread without any knowledge or consent of it. And that's by definition how preemption works (see WP for example).
2008-04-13 12:00
Oswald

Registered: Apr 2002
Posts: 5094
Quote: you have an interisting definition of trolling, really :)

and you have childish arguments, and trolling techniques. :)
2008-04-13 12:04
gregg
Account closed

Registered: Apr 2005
Posts: 56
Please use 4chan for all your trolling needs! (Or heise.de for ze Germans)
2008-04-13 12:06
Oswald

Registered: Apr 2002
Posts: 5094
Quote: The effect thread interrupts the main thread without any knowledge or consent of it. And that's by definition how preemption works (see WP for example).

but it gives back control by own will which is cooperative. also threads does not preempt/return to other threads by own will. also threads has own context, stack, etc, which an interrupt clearly does not have. its just an interrupt not a thread.
2008-04-13 12:41
Laxity

Registered: Aug 2005
Posts: 459
One argument in Oswalds favor could be that the effect "thread" locks the system thread until it's done and then returns, so it's actually not preemtive multithreading. For it to be preemtive, it would have to be interrupted by the system for the main thread to run. It's not Cooperative multithreading either, because the main thread do not relinquish the system resources for the effect thread to run (unless you'd like to argument that the IRQ does that for it). It's not one nor the other. I doubt it would be considered multithreading. Dualthreading at most :)

That said, the concept of writing a multithreading kernel for the C64 is a very interesting concept. I'm not sure how useful it is (I lack the imagination for that, I guess), but it's really neat. Isn't there going to be some problems with stack in your implementation, Gregg?.. I mean, the more threads you add, the less stack there'd be free for each thread, correct?.. And copying the complete stack per thread (plus state) is going to be expensive in terms of both memory usage and CPU time spend on task switching... Hmm..

EDIT: Didn't see your previous reply, Dr. O.. So in fact we agree on this :)
2008-04-13 12:47
gregg
Account closed

Registered: Apr 2005
Posts: 56
Quote:
Isn't there going to be some problems with stack in your implementation, Gregg?.. I mean, the more threads you add, the less stack there'd be free for each thread, correct?..


Yes, I'm simply moving the stack pointer down by a fixed amount for each thread. This limits the the number of threads as well as the maximum recursion depth, but I don't think either will be a real issue on the c64... this is meant to be used for a handful of threads, not dozens and dozens of threads.

Quote:
And copying the complete stack per thread (plus state) is going to be expensive in terms of both memory usage and CPU time spend on task switching...


I'm not copying the stack, but merely changing the stack pointer. The initialization only pushes initial thread data onto the stack, to make it possible to actually start it.
2008-04-13 12:55
Laxity

Registered: Aug 2005
Posts: 459
Quote: Quote:
Isn't there going to be some problems with stack in your implementation, Gregg?.. I mean, the more threads you add, the less stack there'd be free for each thread, correct?..


Yes, I'm simply moving the stack pointer down by a fixed amount for each thread. This limits the the number of threads as well as the maximum recursion depth, but I don't think either will be a real issue on the c64... this is meant to be used for a handful of threads, not dozens and dozens of threads.

Quote:
And copying the complete stack per thread (plus state) is going to be expensive in terms of both memory usage and CPU time spend on task switching...


I'm not copying the stack, but merely changing the stack pointer. The initialization only pushes initial thread data onto the stack, to make it possible to actually start it.


Yeah, I know you aren't copying the stack (I did look at the code, you know :)= ).. I was thinking that the implications of doing so would be relatively severe (on this system). The current implementation would enforce limitations on each thread. Effectively this means that adding a thread can result in previously added threads to stop working if they rely on a serain amount of the stack frame (if the stack is divided in to equal size per thread).
2008-04-13 13:03
gregg
Account closed

Registered: Apr 2005
Posts: 56
Yeah, but I hope you're not going to seriously use recursion for algorithms on the c64, are you? :p I doubt this ever becomes a real problem. Even the tiny stack offset of $20 bytes allows a recursion depth (JSR) of 13... that's quite enough :)
2008-04-13 13:06
Krill

Registered: Apr 2002
Posts: 2980
Quote: but it gives back control by own will which is cooperative. also threads does not preempt/return to other threads by own will. also threads has own context, stack, etc, which an interrupt clearly does not have. its just an interrupt not a thread.

What are you nitpicking about anyways?

It is a fact that everything described here is some sort of multithreading. The details as to whether, e.g., who is in charge of what, or whether a thread has a complete own stack on its own or not, are not relevant.

Also pretty many embedded systems, among others, implement preemptive multithreading using timer interrupts and then switch states "manually".

Furthermore, there is any number of variations for multithreading in general, as to what is static, what is shared or private, et cetera.

That said, multithreading on C64 is neither expensive nor useless. I have used it myself here and there, and generic/elegant solutions are not bound to be expensive.
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
Andy/AEG
MWR/Visdom
rambo/Therapy/ Resou..
Icon/TRIAD
cba
Twilight/Excess/Arcade
Twoflower/ΤRIΛD
grennouille
Guests online: 134
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 The Demo Coder  (9.6)
6 Edge of Disgrace  (9.6)
7 What Is The Matrix 2  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.7)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 X-Mas Demo 2024  (9.5)
7 Dawnfall V1.1  (9.5)
8 Rainbow Connection  (9.5)
9 Onscreen 5k  (9.5)
10 Morph  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Censor Design  (9.3)
5 Triad  (9.3)
Top Fullscreen Graphicians
1 Joe  (9.7)
2 Sulevi  (9.6)
3 The Sarge  (9.6)
4 Veto  (9.6)
5 Facet  (9.6)

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