Shop OBEX P1 Docs P2 Docs Learn Events
General Question about MultiTasking — Parallax Forums

General Question about MultiTasking

Circuitbuilder9Circuitbuilder9 Posts: 85
edited 2012-04-20 21:36 in Propeller 1
Hi, all.

I was looking at some code recently, and i would like to know how to multitask in one cog, in both spin and assembly. Is there something that i should look out for? Or is it a certain way you put in the code?

If at all possible, example code would suffice, for the purpose of explanation in this thread.

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-04-16 18:05
    Without interrupts it's a bit awkward to multitask in a single COG (that's what I thought the other COGs were for) but in PASM you can use the JMPRET to pass control to another task which can then do the same back. Using self-modifying code you can rewrite the destinations of the jmpret instructions to handle more tasks. Hope I said that correctly but I'm sure someone else will chime in to help.

    Have a look at FullDuplexSerial as an example of the jmpret.
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-04-16 18:32
    If you're up to using GCC, then you can use pthreads for cooperative multi-tasking. There are examples of how to use pthreads in the demo programs. Any kind of pre-emptive multitasking is going to require an interrupt...but then with 8 COGS, well, you know.

    Mixing SPIN and PASM will be more difficult since you would need to be able to distinguish a SPIN task from a PASM task and switch out (and save) the SPIN interpreter and load in the PASM code and vice versa with each task change.

    With PIN only, you would need to save the context of the SPIN interpreter with each task switch. This introduces a lot of overhead and would require some sort of thread dispatcher. Lots of overhead unless you can really justify it.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-04-16 18:35
    I suppose the LED flashing program I wrote is an example of multitasking with one cog.

    The program will flash an LED on any or all pins of the Prop. Each LED can have a different flash rate and different number of times to flash.
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-04-16 18:43
    OK, so in the propeller assembly, jmpret is used for multitasking code. But are there any examples? What other tidbits of code to you combine with that instruction to do more than one task? I'm hoping to expand my horizons more in propeller assembly, because i am new to it.

    In the other topic of multitasking in Spin, is there a certain instruction that multitasking revolves around, such as a single command joined with others in a certain syntax, or are they accomplished by loops, mostly?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-04-16 19:03
    So cb9 are you familiar with multitasking in various forms in other CPUs? I think if you understood what multitasking is and what it isn't you might have picked up sufficient information from this forum and code already. What are you trying to do?

    @Duane: Since you only have the one timing task even though it is flexible in allowing different multiple rates it is still a single task, it's stuck in that loop.
  • Mike GreenMike Green Posts: 23,101
    edited 2012-04-16 19:17
    Strictly speaking, JMPRET is used to implement co-routines and multitasking is done as co-routines. One example of this is the FullDuplexSerial object where the receive and transmit sides of the serial port are implemented as co-routines. Any time either of the sides has to wait for something, it transfers control to the other side to do something instead. All of the waiting is done by polling. If the transmit side is idle, it's waiting for something to be put into its buffer. If the receive side is idle, it's waiting for the beginning of a start bit. The system clock is used as the timebase.

    The TV driver is a more difficult example. There's a lot of initialization that has to be done and the driver may be reinitialized at the start of any display frame. The initialization code is done as a co-routine where short segments of the initialization code are executed during part of the horizontal retrace interval during the first few lines of a new frame.
  • kwinnkwinn Posts: 8,697
    edited 2012-04-16 20:23
    You can also do "cooperative" multitasking in spin or PASM by having the individual programs execute a short section of code and then return to the scheduler.
  • tonyp12tonyp12 Posts: 1,951
    edited 2012-04-16 21:57
    You would need to create these programs part from scratch so they don't use wait or any other type of longs delays.
    Set up a master part that it just a list of jmpret to these subroutines, but you expect a quick return.

    So more like a state-machine, that you check on things 1000 times second and everything will now have this time base.
    If you want to blink an LED once a second, your sub routine will see if it's counter have reached 500 to turn it on and 1000 to turn it off.
  • pjvpjv Posts: 1,903
    edited 2012-04-16 22:27
    Circuitbuilder;

    Search the Parallax site for the contests held a few years ago. I wrote a multi-threading scheduler for those contest, and the code and descriptions are posted there.

    A year or so ago, I wanted to see how many simultaneous threads I could run in a single cog, and I believe the number was somewhere around 115 simultaneous independent (but co-operative) threads.

    Cheers,

    Peter (pjv)
  • prof_brainoprof_braino Posts: 4,313
    edited 2012-04-17 09:03
    Software multitasking can be done by each "task" surrendering control, see round-robin software multitasking.

    We can do hardware multitasking on a cog using the cnt etc to do things independent of the rest of the app on a cog. This is how the MSC handles communication between separate prop chips in propforth.

    Cliff Biffle did multitasking on his version of propellerforth, I think he got 140 tasks at once, but there wasn't any room for anything else at that point. the tasks just incremented a count.

    The real question is what do we want to do that would need multitasking, then we can figure out how to get it done.
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-04-17 11:18
    Whoa, i'm overwhelmed by answers, i'll take this slowly.

    First, for those wondering what i am trying to accomplish: it's nothing. I want to learn multi tasking techniques, which (in my opinion) is a very important aspect of programming.

    @peter: are there any articles on the internet (or anywhere else) that i can find explanations to multitasking? I am a highschooler, so unlike a lot of you guys on the forum, i don't have a major or enough experience yet. I am slowly improving my technique.

    Lastly to everyone else, what to byte/word/long modification do to make code self modify?
    I was always confused about all of the shift, rotate, shift arithmatic, and other binary modification assembly instructions. I know what they do, but do not know when it is appropriate for the code. How do you guys know how to use them to make self modifying code?
  • StefanL38StefanL38 Posts: 2,292
    edited 2012-04-17 12:40
    maybe looking at Prop RTOS http://www.parallax.com/PropRTOS/tabid/852/Default.aspx

    is interesting too.
    best regards
    Stefan
  • prof_brainoprof_braino Posts: 4,313
    edited 2012-04-17 14:17
    a highschooler

    Ah!,I see! A different answer is brewing just for you....
    Lastly to everyone else, what to byte/word/long modification do to make code self modify?

    Think before you want to do this, self modifying code tends to change and you lose control and it does other than what you want, instead consider:
    Make specific code for each behavior you want. Determine the situation, and c all the specific code thats needed. But, there are many ways to skin the cat.

    Multitasking originally meant the computer is sitting around doing nothing most of the time, waiting for you to hit the next key. Once in a great while (to the computer, you hit "enter" and the computer gets to do something interesting. Since its just sitting around waiting for the user, why not make it sit around and wait for many users? So they put 100 terminals on the mainframe, and the computer still mostly sat around waiting for somebody to hit "enter".

    But few really understand this. Nowadays, bosses ask humans to "multitask". In this context, they REALLY want one person to do multiple jobs in the same physical time. Basically they are asking one person to do the job of many with no additional pay. Avoid this. If you are really sitting around doing nothing most of the time, you should get a new job, or you are in the army, or both.
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-04-17 18:44
    @Prof_braino:

    But when you "multitask" in propeller assembly what differences does the code look like compared t assembly code that basically accomplishes one task at a time?
    I am looking for a "trend," i guess, so that i can use that example for multitasking in propeller assembly.

    @anyone: What goes on in the process control of the code (that is what's so confusing to me)?
    And, lastly, the read/write byte/word/long instructions in Prop Assembly: How are bit patterns so special to self modifying code? Any examples?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-04-17 20:21
    People multitask all the time, in fact mothers are know as masters of multitasking. But people can only do one thing at a time, they simply keep track of each task or job and slice the time up between them. The smaller the slices the faster you get around to each task but you lose time by switching to the next task and remembering where you were before. So with any computer it can multitask at a low or high level it follows this basic pattern. There are multitaskers (software that manages taks) that are cooperative such as the baby has been fed and gone to sleep and now you can feed the cat. Then there is preemptive multitasking where the bell rings and you have to drop what you are doing and switch to the next task (maybe in round robin fashion). Or the preemptive taker may also allow for priorities such as the baby cries and you have to drop everything right now and then the dog chases the cat and you drop the baby...oooops.
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-04-18 13:57
    OK, i get the idea of multitasking, but, my other question stated before:

    What goes on in the process control of the code (that is what's so confusing to me) to multitask?
    And, lastly, the read/write byte/word/long instructions in Prop Assembly: How are bit patterns so special to self modifying code? Any examples?
  • Mike GreenMike Green Posts: 23,101
    edited 2012-04-18 14:30
    It helps to have a practical case where you might want to multitask. As Peter mentioned, there are several types of multitasking depending on the circumstances where you might want to change from one task to another. In the case of the Propeller, most multitasking is cooperative where there are specific places where it makes sense to switch from one task to another as opposed to preemptive multitasking where something external happens to force the processor to stop doing one task and start doing another. On the Propeller, there's really no mechanism to force one cog to do something like that. One of the reasons for having multiple cogs is to eliminate the need to do that.

    What do the RD/WR BYTE/WORD/LONG instructions have to do with self modifying code or bit patterns? These instructions, like most of the Propeller's instructions, have no ability to have an indirect or indexed address, so self-modifying techniques have to be used for indexing through an array for example, but the same thing is true of other instructions. Are bit patterns special to self modifying code? I don't see that, but maybe you could show what made you think that way.
  • Mark_TMark_T Posts: 1,981
    edited 2012-04-18 16:44
    OK, i get the idea of multitasking, but, my other question stated before:

    What goes on in the process control of the code (that is what's so confusing to me) to multitask?
    And, lastly, the read/write byte/word/long instructions in Prop Assembly: How are bit patterns so special to self modifying code? Any examples?

    The fundamental operation in multitasking is to switch a physical processor from one "thread" to another - this means saving all the registers on the stack, finding the new thread and loading up the registers from its stack and "returning" back to that context. In PASM there isn't a stack in the traditional sense so you can really do this as subroutines aren't re-entrant. But then again you have to decide what a register is (the whole cog RAM? Just the Spin interpreter's variables?)

    With full-blown processes you have more state than just a stack, you have a memory-management context and other OS datastructures - beyond the scope of the Prop chip really.

    Not sure what you are getting at by that last question... You mention the hub RAM instructions and then talk about self-modifying code which only happens in cog RAM via MOVS/MOVD/MOVI...
  • prof_brainoprof_braino Posts: 4,313
    edited 2012-04-20 18:15
    @Prof_braino:

    But when you "multitask" in propeller assembly what differences does the code look like compared t assembly code that basically accomplishes one task at a time?
    I am looking for a "trend," i guess, so that i can use that example for multitasking in propeller assembly.

    If you do software multitasking, as in round robin multitasker in forth, each task voluntarily surrenders control back to the round robin loop slow a slow activity such as disk access is requested. That is, when a task say get data from the disk, it will have to wait for several millisecond before the disk comes back with data. this allow the other tasks in the loop maybe several hundred passes. There are lots of activities that are slower than assembly executing in the cache, so when we hit one we give up control. The result is that when you are w2aiting, everybody else gets access, and it gets really efficient, it looks like everybody how the whole house to himself.

    The code itself is just code, the algorithm you implement to do the multitasking is whats different. I'm not the guy to give any greater detail, this is where the REALLY smart people play.

    With hardware multitasking we don;t have to spend any special attention in the software when we give up control, somebody designed the hardware to to something that covers it. Some method behave differently than other. In the case of the prop, there are eight separate independent CPU's , the cogs, that just crank along doing only what they are told. The never have to wait for the other guys, until they want to read a shared resource, such as the Hub memory. To access the Hub, each cog gets a chance every 15 (?) cycles, it in the manual. The benefit is it deterministic , which means we know exactly how long it takes to do something, which is important when we are working near the limiting speed of the chip. Most of the time all this doesn't matter, but in the case where its important its a very big deal.
  • ZootZoot Posts: 2,227
    edited 2012-04-20 19:03
    Here's pseudo code that may help. In this very simple example, one task runs every "tick" of the scheduler clock/counter, another task runs every other tick (half as often) and another tick runs every fourth time around. The idea is that you are never running all the code every tick, just the minimum needed to keep all your balls in the air...
    
    Scheduler:
    
    while ( 1 == 1 ) {   // loop forever
    
        do ledFlasher    // runs every "tick"
       
        if ( tick & %01 == 0 ) {  // runs every even "tick"
             do slowLedFlasher
        }
    
        if ( tick & %11 == %11 ) {  // runs every 4th tick only
             do checkButton
        }
    
        tick += 1
    
        // now parse some states...
        if ( button == PRESSED ) {
            // do something
        }
    
    }
    
    
    function ledFlasher() {
         LED0 = ~LED0   // flash the LED
    }
    
    function slowLedFlasher() {
         LED1 = ~LED1   // flash the LED
    }
    
    function checkButton() {
         if ( BUTTON1 == lastButton ) {  // if state changes...
              if ( debounce >= 10 ) { // i.e. 40 main "ticks"
                  if ( BUTTON1 == 0 ) {
                       button = PRESSED 
                  } else {
                       button = RELEASED
                  }
              } else {
                  debounce += 1   // counts up 1 every 4 ticks
              }
          } else {
                debounce = 0 // state change on button, clear debounce
          }
          lastButton = BUTTON1
    } 
    
    

    There are lots of ways to skin this cat -- it is common to have individual registers for "ticks" for each task, so that each runs when it needs, then some light management (or custome tuning of intervals between each running of a given task) to ensure that no task hogs all the time. Or it may be that a given task runs every "tick", but that only a portion of the task is executed, to leave time for the other tasks, etc.

    For what it's worth, I consider pjv the master of RTOS (real-time operating system, i.e., multi-task scheduling and management). On both the SX and the Prop he has created insanely compact code that gets a huge amount of mileage out of a cooperative multi-tasking environment.
  • evanhevanh Posts: 16,112
    edited 2012-04-20 21:36
    Multitasking originally meant the computer is sitting around doing nothing most of the time, waiting for you to hit the next key. Once in a great while (to the computer, you hit "enter" and the computer gets to do something interesting. Since its just sitting around waiting for the user, why not make it sit around and wait for many users? So they put 100 terminals on the mainframe, and the computer still mostly sat around waiting for somebody to hit "enter".

    Multitasking has always been independent of multiuser. Just like virtual memory has always been independent of paging. The two may have grown up together but it doesn't make them one and the same.

    But few really understand this. Nowadays, bosses ask humans to "multitask". In this context, they REALLY want one person to do multiple jobs in the same physical time. Basically they are asking one person to do the job of many with no additional pay. Avoid this. If you are really sitting around doing nothing most of the time, you should get a new job, or you are in the army, or both.

    The human analogies don't really fit given it's a technical function but, hey, can't stop the PR spin now can we. I distinctly remember talkiing about multitasking, in computing terms, in the early 1990s and getting a ton of blank stares from every lay person. At some point in the early 2000s all of a sudden it was a common term that replaced "busy" or "100 things" for humans. I'm gonna guess it was a buzzword used at a product launch, probably WinXP.
Sign In or Register to comment.