www.pudn.com > MessageQueue.zip > MAIN.C


/* 
Copyright (C) 2004  Liu Ge 
 
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 "thread.h" 
#include "memmgr.h" 
#include "taskmsg.h" 
#include "event.h" 
#include "TextOut.h" 
 
//Note: all string functions in the standard library can be called safely 
#include  
 
typedef void (_interrupt * INT_VECTOR)(void); 
#define CLOCK_INTERRUPT_NUM 8 
 
const char * IntToStr(int value, char * sz); 
 
void OutStr( int x, int y, const char * szText ) 
{ 
    TextDev_Out( x, y, szText, strlen(szText) ); 
} 
 
static P_Event s_pEvent; 
static int s_iCountThread = -1; 
 
void OutCount(void) 
{ 
    static int s_nCount; 
     
    char szBuff[10]; 
     
    s_nCount ++; 
    IntToStr( s_nCount, szBuff ); 
     
    OutStr( 58, 24, "Clock count:" ); 
    OutStr( 72, 24, szBuff ); 
     
    if( s_nCount % 18 == 0 ) 
    { 
        if( s_iCountThread != -1 ) 
        { 
            MsgThread_Send( s_iCountThread, &s_nCount, sizeof(int) ); 
        } 
    } 
} 
 
void interrupt ClockIsr(void) 
{ 
    OutCount(); 
 
    //  Issue a EOI (End Of Interrupt ) command to the interrupt 
    //  controller for enabling the interrupt controller 
    _asm mov al, 0x20 
    _asm out 0x20, al 
 
    __TaskSwitch(); 
} 
 
void SubTask(void) 
{ 
    char szBuff[10]; 
    unsigned int i; 
 
    OutStr( 0, 1, "SubTask begins..." ); 
    OutStr( 0, 4, "SubTask's count:" ); 
 
    for(i = 10000;;) 
    { 
        int k; 
         
        i --; 
 
        for( k = 0; k < 10000; k ++ ) 
        { 
            IntToStr( i, szBuff ); 
        } 
 
        OutStr( 20, 4, szBuff ); 
    } 
} 
 
void CountThread(void) 
{ 
    static int s_nCount; 
    char szBuff[10]; 
    int i; 
    int nCount; 
 
    OutStr( 0, 6, "Enter Thread" ); 
    IntToStr( s_nCount, szBuff ); 
    OutStr( 20, 6, szBuff ); 
 
    for(i = 0; i < 5; i ++) 
    { 
        if( MsgThread_Receive( &nCount, sizeof(nCount) ) 
            == sizeof(nCount) ) 
        { 
            OutStr( 0, 7, "Received messages:" ); 
            IntToStr( i+1, szBuff ); 
            OutStr( 20, 7, szBuff ); 
        } 
    } 
     
    OutStr( 0, 8, "Leaving Thread" ); 
    IntToStr( s_nCount, szBuff ); 
    OutStr( 20, 8, szBuff ); 
 
    MsgThread_Receive( &nCount, sizeof(nCount) ); 
    Event_Signal( s_pEvent ); 
    s_nCount ++; 
} 
 
void MainTask(void) 
{ 
    char szBuff[10]; 
    unsigned int iThread; 
 
    MsgThread_Init(); 
    TextDev_ClearScreen(); 
     
    OutStr( 0, 0, "MainTask begin..." ); 
     
    for(iThread = 0;; iThread ++) 
    { 
        s_pEvent = Event_Create(); 
         
        OutStr( 0, 4, "Create Thread " ); 
        IntToStr( iThread, szBuff ); 
        OutStr( 20, 4, szBuff ); 
        s_iCountThread = MsgThread_Create(CountThread, FALSE); 
         
        Event_Wait( s_pEvent ); 
         
        OutStr( 0, 10, "Exit Thread " ); 
        IntToStr( iThread, szBuff ); 
        OutStr( 20, 10, szBuff ); 
         
        Event_Destroy( s_pEvent ); 
    } 
} 
 
static unsigned char s_MemHeap[8192]; 
 
void main(void) 
{ 
    INT_VECTOR _far * pIntVectorTable = (INT_VECTOR _far *)0; 
    pIntVectorTable[CLOCK_INTERRUPT_NUM] = ClockIsr; 
 
    MemHeap_Init( s_MemHeap, 8192 ); 
    Thread_Init(MainTask, 4); 
}