diff options
author | Peter Tyser <ptyser@xes-inc.com> | 2009-07-10 11:03:19 -0500 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2009-07-21 00:13:21 +0200 |
commit | 1bc1538613d66cef3cbce680fc8d7c3561a0fbd0 (patch) | |
tree | f832202519d4077e8ca735948198691f054fe968 /examples/sched.c | |
parent | b220c64d86f7c705a183302c3b50076d7e5d876c (diff) | |
download | u-boot-imx-1bc1538613d66cef3cbce680fc8d7c3561a0fbd0.zip u-boot-imx-1bc1538613d66cef3cbce680fc8d7c3561a0fbd0.tar.gz u-boot-imx-1bc1538613d66cef3cbce680fc8d7c3561a0fbd0.tar.bz2 |
Move examples/ to examples/standalone
The current files in examples are all standalone application examples,
so put them in their own subdirectory for organizational purposes
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Diffstat (limited to 'examples/sched.c')
-rw-r--r-- | examples/sched.c | 369 |
1 files changed, 0 insertions, 369 deletions
diff --git a/examples/sched.c b/examples/sched.c deleted file mode 100644 index b32766f..0000000 --- a/examples/sched.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <exports.h> - -/* - * Author: Arun Dharankar <ADharankar@ATTBI.Com> - * - * A very simple thread/schedular model: - * - only one master thread, and no parent child relation maintained - * - parent thread cannot be stopped or deleted - * - no permissions or credentials - * - no elaborate safety checks - * - cooperative multi threading - * - Simple round-robin scheduleing with no priorities - * - no metering/statistics collection - * - * Basic idea of implementing this is to allow more than one tests to - * execute "simultaneously". - * - * This may be modified such thread_yield may be called in syscalls, and - * timer interrupts. - */ - - -#define MAX_THREADS 8 - -#define CTX_SIZE 512 -#define STK_SIZE 8*1024 - -#define STATE_EMPTY 0 -#define STATE_RUNNABLE 1 -#define STATE_STOPPED 2 -#define STATE_TERMINATED 2 - -#define MASTER_THREAD 0 - -#define RC_FAILURE (-1) -#define RC_SUCCESS (0) - -typedef vu_char *jmp_ctx; -unsigned long setctxsp (vu_char *sp); -int ppc_setjmp(jmp_ctx env); -void ppc_longjmp(jmp_ctx env, int val); -#define setjmp ppc_setjmp -#define longjmp ppc_longjmp - -struct lthread { - int state; - int retval; - char stack[STK_SIZE]; - uchar context[CTX_SIZE]; - int (*func) (void *); - void *arg; -}; -static volatile struct lthread lthreads[MAX_THREADS]; -static volatile int current_tid = MASTER_THREAD; - - -static uchar dbg = 0; - -#define PDEBUG(fmt, args...) { \ - if(dbg != 0) { \ - printf("[%s %d %s]: ",__FILE__,__LINE__,__FUNCTION__);\ - printf(fmt, ##args); \ - printf("\n"); \ - } \ -} - -static int testthread (void *); -static void sched_init (void); -static int thread_create (int (*func) (void *), void *arg); -static int thread_start (int id); -static void thread_yield (void); -static int thread_delete (int id); -static int thread_join (int *ret); - -#if 0 /* not used yet */ -static int thread_stop (int id); -#endif /* not used yet */ - -/* An example of schedular test */ - -#define NUMTHREADS 7 -int sched (int ac, char *av[]) -{ - int i, j; - int tid[NUMTHREADS]; - int names[NUMTHREADS]; - - app_startup(av); - - sched_init (); - - for (i = 0; i < NUMTHREADS; i++) { - names[i] = i; - j = thread_create (testthread, (void *) &names[i]); - if (j == RC_FAILURE) - printf ("schedtest: Failed to create thread %d\n", i); - if (j > 0) { - printf ("schedtest: Created thread with id %d, name %d\n", - j, i); - tid[i] = j; - } - } - printf ("schedtest: Threads created\n"); - - printf ("sched_test: function=0x%08x\n", (unsigned)testthread); - for (i = 0; i < NUMTHREADS; i++) { - printf ("schedtest: Setting thread %d runnable\n", tid[i]); - thread_start (tid[i]); - thread_yield (); - } - printf ("schedtest: Started %d threads\n", NUMTHREADS); - - while (1) { - printf ("schedtest: Waiting for threads to complete\n"); - if (tstc () && getc () == 0x3) { - printf ("schedtest: Aborting threads...\n"); - for (i = 0; i < NUMTHREADS; i++) { - printf ("schedtest: Deleting thread %d\n", tid[i]); - thread_delete (tid[i]); - } - return RC_SUCCESS; - } - j = -1; - i = thread_join (&j); - if (i == RC_FAILURE) { - printf ("schedtest: No threads pending, " - "exiting schedular test\n"); - return RC_SUCCESS; - } - printf ("schedtest: thread is %d returned %d\n", i, j); - thread_yield (); - } - - return RC_SUCCESS; -} - -static int testthread (void *name) -{ - int i; - - printf ("testthread: Begin executing thread, myname %d, &i=0x%08x\n", - *(int *) name, (unsigned)&i); - - printf ("Thread %02d, i=%d\n", *(int *) name, i); - - for (i = 0; i < 0xffff * (*(int *) name + 1); i++) { - if (tstc () && getc () == 0x3) { - printf ("testthread: myname %d terminating.\n", - *(int *) name); - return *(int *) name + 1; - } - - if (i % 100 == 0) - thread_yield (); - } - - printf ("testthread: returning %d, i=0x%x\n", - *(int *) name + 1, i); - - return *(int *) name + 1; -} - - -static void sched_init (void) -{ - int i; - - for (i = MASTER_THREAD + 1; i < MAX_THREADS; i++) - lthreads[i].state = STATE_EMPTY; - - current_tid = MASTER_THREAD; - lthreads[current_tid].state = STATE_RUNNABLE; - PDEBUG ("sched_init: master context = 0x%08x", - (unsigned)lthreads[current_tid].context); - return; -} - -static void thread_yield (void) -{ - static int i; - - PDEBUG ("thread_yield: current tid=%d", current_tid); - -#define SWITCH(new) \ - if(lthreads[new].state == STATE_RUNNABLE) { \ - PDEBUG("thread_yield: %d match, ctx=0x%08x", \ - new, \ - (unsigned)lthreads[current_tid].context); \ - if(setjmp(lthreads[current_tid].context) == 0) { \ - current_tid = new; \ - PDEBUG("thread_yield: tid %d returns 0", \ - new); \ - longjmp(lthreads[new].context, 1); \ - } else { \ - PDEBUG("thread_yield: tid %d returns 1", \ - new); \ - return; \ - } \ - } - - for (i = current_tid + 1; i < MAX_THREADS; i++) { - SWITCH (i); - } - - if (current_tid != 0) { - for (i = 0; i <= current_tid; i++) { - SWITCH (i); - } - } - - PDEBUG ("thread_yield: returning from thread_yield"); - return; -} - -static int thread_create (int (*func) (void *), void *arg) -{ - int i; - - for (i = MASTER_THREAD + 1; i < MAX_THREADS; i++) { - if (lthreads[i].state == STATE_EMPTY) { - lthreads[i].state = STATE_STOPPED; - lthreads[i].func = func; - lthreads[i].arg = arg; - PDEBUG ("thread_create: returns new tid %d", i); - return i; - } - } - - PDEBUG ("thread_create: returns failure"); - return RC_FAILURE; -} - -static int thread_delete (int id) -{ - if (id <= MASTER_THREAD || id > MAX_THREADS) - return RC_FAILURE; - - if (current_tid == id) - return RC_FAILURE; - - lthreads[id].state = STATE_EMPTY; - return RC_SUCCESS; -} - -static void thread_launcher (void) -{ - PDEBUG ("thread_launcher: invoking func=0x%08x", - (unsigned)lthreads[current_tid].func); - - lthreads[current_tid].retval = - lthreads[current_tid].func (lthreads[current_tid].arg); - - PDEBUG ("thread_launcher: tid %d terminated", current_tid); - - lthreads[current_tid].state = STATE_TERMINATED; - thread_yield (); - printf ("thread_launcher: should NEVER get here!\n"); - - return; -} - -static int thread_start (int id) -{ - PDEBUG ("thread_start: id=%d", id); - if (id <= MASTER_THREAD || id > MAX_THREADS) { - return RC_FAILURE; - } - - if (lthreads[id].state != STATE_STOPPED) - return RC_FAILURE; - - if (setjmp (lthreads[current_tid].context) == 0) { - lthreads[id].state = STATE_RUNNABLE; - current_tid = id; - PDEBUG ("thread_start: to be stack=0%08x", - (unsigned)lthreads[id].stack); - setctxsp ((vu_char *)<hreads[id].stack[STK_SIZE]); - thread_launcher (); - } - - PDEBUG ("thread_start: Thread id=%d started, parent returns", id); - - return RC_SUCCESS; -} - -#if 0 /* not used so far */ -static int thread_stop (int id) -{ - if (id <= MASTER_THREAD || id >= MAX_THREADS) - return RC_FAILURE; - - if (current_tid == id) - return RC_FAILURE; - - lthreads[id].state = STATE_STOPPED; - return RC_SUCCESS; -} -#endif /* not used so far */ - -static int thread_join (int *ret) -{ - int i, j = 0; - - PDEBUG ("thread_join: *ret = %d", *ret); - - if (!(*ret == -1 || *ret > MASTER_THREAD || *ret < MAX_THREADS)) { - PDEBUG ("thread_join: invalid tid %d", *ret); - return RC_FAILURE; - } - - if (*ret == -1) { - PDEBUG ("Checking for tid = -1"); - while (1) { - /* PDEBUG("thread_join: start while-loopn"); */ - j = 0; - for (i = MASTER_THREAD + 1; i < MAX_THREADS; i++) { - if (lthreads[i].state == STATE_TERMINATED) { - *ret = lthreads[i].retval; - lthreads[i].state = STATE_EMPTY; - /* PDEBUG("thread_join: returning retval %d of tid %d", - ret, i); */ - return RC_SUCCESS; - } - - if (lthreads[i].state != STATE_EMPTY) { - PDEBUG ("thread_join: %d used slots tid %d state=%d", - j, i, lthreads[i].state); - j++; - } - } - if (j == 0) { - PDEBUG ("thread_join: all slots empty!"); - return RC_FAILURE; - } - /* PDEBUG("thread_join: yielding"); */ - thread_yield (); - /* PDEBUG("thread_join: back from yield"); */ - } - } - - if (lthreads[*ret].state == STATE_TERMINATED) { - i = *ret; - *ret = lthreads[*ret].retval; - lthreads[*ret].state = STATE_EMPTY; - PDEBUG ("thread_join: returing %d for tid %d", *ret, i); - return RC_SUCCESS; - } - - PDEBUG ("thread_join: thread %d is not terminated!", *ret); - return RC_FAILURE; -} |