Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
 Welcome to our latest new user eightbitswide ! (Registered 2024-12-24) 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 18:21
Oswald

Registered: Apr 2002
Posts: 5094
trident,

I haven't said that post#1 is not multithreading. but I think it does not :)) it is multitasking at best. multithreading means sub tasks within a task so to speak.

I'm arguing mainly that irqs are not multithreading, which you said they are, in a response to my example on how to load while an fx runs.

all of you are mixing the terms multitasking & multithreading heavily.

once again: multithreading means running cooperating processes within one task. threads were invented to make context switching faster by having them running in the same context of their parent task. this is the key.

this leads us back to that: you cannot seriously talk about threads outside the operating system context box. threads are on a sub task level and tasks is on the sub OS term level.

2008-04-13 18:31
Oswald

Registered: Apr 2002
Posts: 5094
Quote: Re the "threading with an OS" thing.

An OS can be really big or really small. If there is multi-threading, which this example shows, then the bit of code which does the context switches can be thought of as a really tiny OS.

Of course the code that runs multi-threading can also be thought of a just a tiny bit of code which does the job.


So yes, it is possible to have multi-threading without an OS per se.


in the c64's HW context thread is a meaningless term. as threads were invented to be able to run several cooperative subtasks within a task in an OS. we have no os, no task, how can we define threads them? they are part of tasks which we dont have at the first place.
2008-04-13 18:44
trident

Registered: May 2002
Posts: 91
Oswald: multithreading, multitasking, and related concepts are tricky concepts and most of them are not very well defined. Neither require an operating system, however. (But then the concept of an operating system is not particularly well defined in computer science either... :/)

Threads are, however, a quite well defined concept and threads are completely orthogonal to the concept of an operating system. Many programming languages provide a thread abstraction, for example.

One of the key points you raise is interesting: are interrupt handlers really threads if they do not have a stack? The answer is yes, because the thread has both processor state (registers, status word, program counter) and a stack (physically located on top of the main program's stack). If the interrupt handler is preempted, the state is stored on its stack. So it is a thread.

But what if there is no memory where the state of the suspended thread can be stored? Suppose there is no stack where the interrupt handler can store its state - what is the interrupt handler then? This is where the concept of protothreads is useful: a protothread is a thread without a stack. When suspended, a protothread only remembers the program counter, but not the processor status. Protothreads therefore cannot be preempted, but must yield voluntarily at specific points.
2008-04-13 18:47
trident

Registered: May 2002
Posts: 91
Quote: in the c64's HW context thread is a meaningless term. as threads were invented to be able to run several cooperative subtasks within a task in an OS. we have no os, no task, how can we define threads them? they are part of tasks which we dont have at the first place.

A thread simply is an execution context. When the C64 boots, it starts executing the main thread. The entry point of this thread is defined by the pointer at $fffa. Interrupt handlers (high-priority threads) can preempt this thread.

Threads are just an abstraction that is designed to make it possible to reason about systems. There is nothing magical about them. It is just a concept - an abstraction.

Concepts like "an interrupt handler" are in fact more complex concepts than threads. The reason we think that an interrupt handler is such an easy concept to grasp is because we've been brought up on them.
2008-04-13 19:03
Oswald

Registered: Apr 2002
Posts: 5094
trident,

substract 15 from 1 without the concept of negative numbers. managed? now set up a task without reserving memory, giving it I/O drivers, having a task scheduler, etc? understand me now? there's no task without OS. a task is an entity defined by the resources allocated, process ID, etc within the context of an OS.

*sigh* as a c64 coder yourself you should know that interrupts store only the "main" program's state. but themselves 'own' no pc/register/stack whatsoever. they store 0 state info of themselves. also the irq handler is NEVER preempted . you should know that the irq handler decides itself wether it goes back to "main" program or not. (remember HW turns on SEI automagically?) irqs are not threads. the sky is blue. etc.
2008-04-13 19:12
Oswald

Registered: Apr 2002
Posts: 5094
Quote: A thread simply is an execution context. When the C64 boots, it starts executing the main thread. The entry point of this thread is defined by the pointer at $fffa. Interrupt handlers (high-priority threads) can preempt this thread.

Threads are just an abstraction that is designed to make it possible to reason about systems. There is nothing magical about them. It is just a concept - an abstraction.

Concepts like "an interrupt handler" are in fact more complex concepts than threads. The reason we think that an interrupt handler is such an easy concept to grasp is because we've been brought up on them.


the term thread was invented to give a name to the varios >threads< that are running within a task. the term process/task was invented to name the various program entitys that are running within an OS. it builds up like a tree. you take away the tree's roots the tree falls down, so does the concept thread without the concept of a task and the task without the OS.
2008-04-13 19:13
trident

Registered: May 2002
Posts: 91
The state of the interrupt handler is stored in the CPU (registers, status word, program counter) and on the stack (if the interrupt handler calls other functions, for instance). The CPU state is stored on the stack only if the interrupt handler is preempted (e.g. by an NMI - yes, interrupt handlers do get preempted sometimes).

As I previously said, the concept of a task is difficult, so it is better if we stick to the concept of threads.
2008-04-13 19:17
trident

Registered: May 2002
Posts: 91
Quote: the term thread was invented to give a name to the varios >threads< that are running within a task. the term process/task was invented to name the various program entitys that are running within an OS. it builds up like a tree. you take away the tree's roots the tree falls down, so does the concept thread without the concept of a task and the task without the OS.

The concept of a thread is independent of the concept of a process. A process typically contains one or more threads, but a thread does not require the concept of a process.
2008-04-13 19:23
Oswald

Registered: Apr 2002
Posts: 5094
Quote: The state of the interrupt handler is stored in the CPU (registers, status word, program counter) and on the stack (if the interrupt handler calls other functions, for instance). The CPU state is stored on the stack only if the interrupt handler is preempted (e.g. by an NMI - yes, interrupt handlers do get preempted sometimes).

As I previously said, the concept of a task is difficult, so it is better if we stick to the concept of threads.


an interrupt handler's state is not stored when it exits, while a thread's state IS stored when its preempted. an interrupt handler is always entered and exited on the same points while this is untrue for a thread. see any difference now ?

for the concept of a task/process look up wikipedia. its crystal clear.
2008-04-13 19:30
Oswald

Registered: Apr 2002
Posts: 5094
Quote: The concept of a thread is independent of the concept of a process. A process typically contains one or more threads, but a thread does not require the concept of a process.

threads are running within the process' context cooperatively. do wheels fullfill their purpose without axles ? what can threads do without the process' context?
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ... | 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
MWR/Visdom
CreaMD/React
Courage
CA$H/TRiAD
iceout/Avatar/HF
Guests online: 92
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 Layers  (9.6)
2 Cubic Dream  (9.6)
3 Party Elk 2  (9.6)
4 Copper Booze  (9.6)
5 X-Mas Demo 2024  (9.5)
6 Dawnfall V1.1  (9.5)
7 Rainbow Connection  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (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 Swappers
1 Derbyshire Ram  (10)
2 Jerry  (9.8)
3 Violator  (9.7)
4 Acidchild  (9.7)
5 Cash  (9.6)

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