URL
https://opencores.org/ocsvn/thor/thor/trunk
Subversion Repositories thor
[/] [thor/] [trunk/] [software/] [FMTK/] [source/] [kernel/] [TCB.c] - Rev 23
Compare with Previous | Blame | View Log
// ============================================================================ // __ // \\__/ o\ (C) 2012-2015 Robert Finch, Stratford // \ __ / All rights reserved. // \/_// robfinch<remove>@finitron.ca // || // // TCB.c // Task Control Block related functions. // // This source file is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This source file 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, see <http://www.gnu.org/licenses/>. // // ============================================================================ // #include "config.h" #include "const.h" #include "types.h" #include "proto.h" extern char hasUltraHighPriorityTasks; extern pascal prtdbl(double); TCB tcbs[NR_TCB]; hTCB freeTCB; hTCB TimeoutList; hTCB readyQ[8]; pascal int chkTCB(TCB *p) { asm { lw r1,32[bp] //chk r1,r1,b48 } } naked TCB *GetRunningTCBPtr() { asm { mov r1,tr rts } } naked hTCB GetRunningTCB() { asm { subui r1,tr,#tcbs_ shrui r1,r1,#12 rts } } pascal void SetRunningTCB(hTCB ht) { asm { lw tr,32[bp] shli tr,tr,#12 addui tr,tr,#tcbs_ } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- pascal int InsertIntoReadyList(hTCB ht) { hTCB hq; TCB *p, *q; asm { ldi r1,#70 sc r1,hs:LEDS } if (ht < 0 || ht >= NR_TCB) throw E_BadHandle; p = &tcbs[ht]; if (p->priority > 077 || p->priority < 000) throw E_BadPriority; asm { ldi r1,#71 sc r1,hs:LEDS } if (p->priority < 003) hasUltraHighPriorityTasks |= (1 << p->priority); p->status = TS_READY; hq = readyQ[p->priority>>3]; asm { ldi r1,#72 sc r1,hs:LEDS } // Ready list empty ? if (hq<0) { p->next = ht; p->prev = ht; readyQ[p->priority>>3] = ht; return E_Ok; } asm { ldi r1,#75 sc r1,hs:LEDS } // Insert at tail of list q = &tcbs[hq]; p->next = hq; p->prev = q->prev; tcbs[q->prev].next = ht; q->prev = ht; asm { ldi r1,#77 sc r1,hs:LEDS } return E_Ok; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- pascal int RemoveFromReadyList(hTCB ht) { TCB *t; if (ht < 0 || ht >= NR_TCB) throw E_BadHandle; t = &tcbs[ht]; if (t->priority > 077 || t->priority < 000) throw E_BadPriority; if (ht==readyQ[t->priority>>3]) readyQ[t->priority>>3] = t->next; if (ht==readyQ[t->priority>>3]) readyQ[t->priority>>3] = -1; tcbs[t->next].prev = t->prev; tcbs[t->prev].next = t->next; t->next = -1; t->prev = -1; t->status = TS_NONE; return E_Ok; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- pascal int InsertIntoTimeoutList(hTCB ht, int to) { TCB *p, *q, *t; if (ht < 0 || ht >= NR_TCB) throw E_BadHandle; t = &tcbs[ht]; if (TimeoutList<0) { t->timeout = to; TimeoutList = ht; t->next = -1; t->prev = -1; return E_Ok; } q = null; p = &tcbs[TimeoutList]; while (to > p->timeout) { to -= p->timeout; q = p; p = &tcbs[p->next]; } t->next = p - tcbs; t->prev = q - tcbs; if (p) { p->timeout -= to; p->prev = ht; } if (q) q->next = ht; else TimeoutList = ht; t->status |= TS_TIMEOUT; return E_Ok; }; // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- pascal int RemoveFromTimeoutList(hTCB ht) { TCB *t; if (ht < 0 || ht >= NR_TCB) throw E_BadHandle; t = &tcbs[ht]; if (t->next) { tcbs[t->next].prev = t->prev; tcbs[t->next].timeout += t->timeout; } if (t->prev >= 0) tcbs[t->prev].next = t->next; t->status = TS_NONE; t->next = -1; t->prev = -1; } // ---------------------------------------------------------------------------- // Pop the top entry from the timeout list. // ---------------------------------------------------------------------------- hTCB PopTimeoutList() { TCB *p; hTCB h; h = TimeoutList; if (TimeoutList >= 0 && TimeoutList < NR_TCB) { TimeoutList = tcbs[TimeoutList].next; if (TimeoutList >= 0 && TimeoutList < NR_TCB) tcbs[TimeoutList].prev = -1; } return h; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- void DumpTaskList() { TCB *p, *q; int n; int kk; hTCB h, j; // printf("pi is "); // prtdbl(3.141592653589793238,10,6,'E'); printf("CPU Pri Stat Task Prev Next Timeout\r\n"); for (n = 0; n < 8; n++) { h = readyQ[n]; if (h >= 0 && h < NR_TCB) { q = &tcbs[h]; p = q; kk = 0; do { // if (!chkTCB(p)) { // printf("Bad TCB (%X)\r\n", p); // break; // } j = p - tcbs; printf("%3d %3d %02X %04X %04X %04X %08X %08X\r\n", p->affinity, p->priority, p->status, (int)j, p->prev, p->next, p->timeout, p->ticks); if (p->next < 0 || p->next >= NR_TCB) break; p = &tcbs[p->next]; if (getcharNoWait()==3) goto j1; kk = kk + 1; } while (p != q && kk < 10); } } printf("Waiting tasks\r\n"); h = TimeoutList; while (h >= 0 && h < NR_TCB) { p = &tcbs[h]; printf("%3d %3d %02X %04X %04X %04X %08X %08X\r\n", p->affinity, p->priority, p->status, (int)j, p->prev, p->next, p->timeout, p->ticks); h = p->next; if (getcharNoWait()==3) goto j1; } j1: ; }