James Grady (jlgrady1 AT gmail.com) Last Update: Dec 3, 2007 Part1 uth_create() int uth_create(uth_tcd_t *Tid, int Pri, func0_t *Thr, void * Arg); int uth_create(threadID ,priority,func pointer, struct); ex: uth_create (&tid, LO_PRI, (func0_t*) &thr_xxx, &thr_arg); - Functionality -returns context -allocate stack space from heap -place thread in the RUN queue -block/unblock clockinterrupt uth_yield() Give up CPU to the next runnable thread -Functionality -Save current context -Load newcontext (next runnablethread) * SwapContext (&from, &to); -may need to block/unblock clock interrupt Man Pages: (getcontext, makecontext) -> function together like NewContext (swapcontext) -> functions like SwapContext ucontext-basic.c main _ get_context(&child); | child.---= --- } NewContext makecontext (&child, &childfiber, 0); _| swapcontext(&parent, &child); swapcontext(&parent, &child); childFiber .... //swaps context with parent swapcontext(&parent, &child); .... swapcontext(&parent, &child); RR scheduling and preemption -cause a signal to be delivered to your code at T msec into future (Virtual Time) -Signal Handler: uth_cswitch(-) Possible Approach - create context - 1 thread - push taskID onto RUN queue ================================================================================ << Nov 13, 2007 >> Simulating Clock Interrupt -Internal timer setitimer(ITIMER_VIRTUAL, &val, NULL); -ITIMER_VIRTUAL -> signals running in virtual time -val -> clock interrup time -SIGVTALRM -fired when the itimer expires -gives control to the signal handler -should return to where signal was fired from when the signal is handled -Comments -etime -> elapsed time (gettimeofday) -utime -> user time (i.e. how much time spent in usertime, kernel) -stime -> system time ================================================================================ << Nov 27, 2007 >> In mileC.pr source listing: >>> represents beginning on a function <<<===== denotes a uth_ call Functions: fibFiber - creates 2 instances, CPU bound usage_mon - sleep (100 ms), collects data, repeats main - initializes, calls uth_join 3 times (once per thread) Placing printf calls in your code may distort you timing measurements. Also, it is possible that your code may not work when printf's are removed. Program Counters: main fibFiber0 fibFiber1 usage_mon uth_init uth_create uth_create uth_create for{ for{ uth_sleep(100) for{ for{ uth_usage <-- x2 B---> ... C---> ... D--> uth_sleep(100) } } uth_usage <-- x2 } } etc. uth_exit uth_exit A--->uth_join uth_join uth_join Counters will most likely be at A, B, C, and D in the program. Queues: Hi Queue: runQ[0]--> Lo Queue: runQ[1]--> fibFiber0 -> fibFiber1 Lowest Queue: runQ[2]--> idle joinQ --> main sleepQ --> usage_mon Voluntary loss of CPU threads: main, usage_mon uth_join: -block interrupt signal -"register itself" - it is waiting for a thread to terminate i.e. added to the joinQ -context switch to highest priority runnable thread (only context switch once you are finished) *interrupt needs to be unblocked Involuntary loss of CPU threads: fibFiber0, fibFiber1 Hardware Stack ("Interrupt") -Signal Handler