📄 pg_sem.c
字号:
///////////////////////////////////////////////////////////////
//
//
// PGOS : A Portable,Configable Embedded System Kernel
//
//
//
// This is an open source project under GPL lincence
//
// Version 0.9.0 ---- Development Snopshot
//
// File name : pg_sem.c : Semaphores service implemention
// History :
//
// 2005-07-24 First build by X.K. @ PGOS Team
//
/////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include "pgos.h"
#if PG_SEM_SUPPORT == 1
pgSEMLIST* pgos_sem_list ;
pgSEMLIST* pgos_sem_list_head ;
BYTE pgos_sem_num ;
extern BYTE task_cur_id ;
extern BYTE task_cur_prio ;
pgSEMTASK* pgos_sem_initk()
{
pgSEMTASK* Temp ;
Temp = ( pgSEMTASK * )malloc( sizeof( pgSEMTASK ) ) ;
if( !Temp )
return NULL ;
Temp->state = TASK_SEM_NOTUSE ;
return Temp ;
}
pgSEMTKLIST* pgos_sem_initklist()
{
pgSEMTKLIST* TempList ;
pgSEMTKLIST* TempHead ;
BYTE index ;
TempList = ( pgSEMTKLIST * )malloc( sizeof( pgSEMTKLIST ) ) ;
if( !TempList )
return NULL ;
TempList->pSem = pgos_sem_initk() ;
if( !TempList->pSem )
return NULL ;
TempHead = TempList ;
index = 0;
for( ; index < MAXSEMWAIT ; index ++ )
{
TempList->next = ( pgSEMTKLIST * )malloc( sizeof( pgSEMTKLIST ) ) ;
if( !TempList->next )
return NULL ;
TempList->next ->pSem = pgos_sem_initk() ;
if( !TempList->next ->pSem )
return NULL ;
TempList = TempList->next ;
}
return TempHead ;
}
pgSEMLIST* pgos_sem_inilist()
{
pgSEMLIST* TempList ;
pgSEMLIST* TempHead ;
BYTE index ;
TempList = ( pgSEMLIST * )malloc( sizeof( pgSEMLIST ) ) ;
if( !TempList )
return NULL ;
TempList->list = pgos_sem_initklist() ;
if( !TempList->list )
return NULL ;
TempList->state = SEM_NOTUSE ;
TempList->tasknum = 0x00;
TempHead = TempList ;
index = 0;
for( ; index < MAXSEM ; index ++ )
{
TempList->next = ( pgSEMLIST * )malloc( sizeof( pgSEMLIST ) ) ;
if( !TempList->next )
return NULL ;
TempList->next ->list = pgos_sem_initklist() ;
if( !TempList->next ->list )
return NULL ;
TempList->next->state = SEM_NOTUSE ;
TempList->next->tasknum = 0x00 ;
TempList = TempList->next ;
}
return TempHead ;
}
PGOS_STATUS pgos_sem_addtask( pgSEMTKLIST* list, BYTE id, BYTE mode )
{
BYTE index ;
pgSEMTKLIST* pList ;
pList = list ;
index = 1;
for( ; ; )
{
if( pList->pSem->state == TASK_SEM_NOTUSE )
{
pList->pSem->id = id ;
if( mode == TASK_FIRST )
pList->pSem->state = TASK_SEM_USING ;
else
pList->pSem->state = TASK_SEM_SUSPEND ;
#if PG_SEM_PRIO == 1
pList->pSem->prio = pgos_tk_lookup( id )->prio ;
#endif // SEM_PRIO
return PGOS_SUCCESS ;
}
index++ ;
if( index > MAXSEMWAIT )
return PGOS_FAIL_HD ;
pList = pList->next ;
}
return PGOS_FAIL_HD ;
}
PGOS_STATUS pgos_sem_init()
{
pgos_sem_list = pgos_sem_inilist() ;
if( !pgos_sem_list )
return PGOS_FAIL_MEM ;
pgos_sem_list_head = pgos_sem_list ;
pgos_sem_num = 0x00 ;
return PGOS_SUCCESS ;
}
PGOS_STATUS pgos_sem_cre( WORD SemNum )
{
pgos_int_disable() ;
if( pgos_sem_num + 1 <= MAXSEM )
{
pgos_sem_list->Sem = SemNum ;
pgos_sem_list->state = SEM_USE ;
pgos_sem_list->tasknum = 0 ;
pgos_sem_list = pgos_sem_list->next ;
pgos_sem_num++ ;
pgos_int_enable() ;
return PGOS_SUCCESS ;
}
pgos_int_enable() ;
return PGOS_FAIL_NM ;
}
PGOS_STATUS pgos_sem_wait( WORD SemNum )
{
pgSEMLIST* pList ;
pgTASK* pTask ;
pgos_int_disable() ;
pList = pgos_sem_list_head ;
for( ; pList->state != SEM_NOTUSE ; pList = pList->next )
{
if( pList->Sem == SemNum )
{
if( pList->tasknum == 0x00 )
{
if( pgos_sem_addtask( pList->list, task_cur_id, TASK_FIRST ) != PGOS_SUCCESS )
return PGOS_FAIL_NM ;
pList->tasknum++ ;
return PGOS_SUCCESS ;
}
if( pgos_sem_addtask( pList->list, task_cur_id, TASK_APPEND ) != PGOS_SUCCESS )
return PGOS_FAIL_NM ;
pList->tasknum ++ ;
pTask = pgos_tk_lookup( task_cur_id ) ;
pTask->state = PG_SUSPEND ;
pgos_int_enable() ;
pgos_tk_switch() ;
return PGOS_SUCCESS ;
}
}
pgos_int_enable() ;
return PGOS_FAIL_HD ;
}
PGOS_STATUS pgos_sem_post( WORD SemNum )
{
pgSEMLIST* pSemList ;
pgSEMTKLIST* pSEMTkList ;
pgTASK* pTask ;
#if PG_SEM_PRIO == 1
pgSEMTKLIST* pSEMTkListNxt ;
BYTE id ;
BYTE prio ;
#endif
pgos_int_disable() ;
if( pgos_sem_num == 0 )
{
pgos_int_enable() ;
return PGOS_FAIL_NM ;
}
pSemList = pgos_sem_list_head ;
for( ; pSemList->Sem != SemNum ; pSemList = pSemList->next ) ;
pSEMTkList = pSemList->list ;
if( pSemList->tasknum == 0 )
{
pgos_int_enable() ;
return PGOS_FAIL_HD ;
}
for( ; pSEMTkList->pSem->state != TASK_SEM_USING ; pSEMTkList = pSEMTkList->next ) ;
pSEMTkList->pSem->state = TASK_SEM_NOTUSE ;
pSEMTkList = pSemList->list ;
pSemList->tasknum -- ;
if( pSemList->tasknum == 0 )
return PGOS_SUCCESS ;
#if PG_SEM_FIFO == 1
for( ; pSEMTkList->pSem->state != TASK_SEM_SUSPEND ; pSEMTkList = pSEMTkList->next ) ;
pSEMTkList->pSem->state = TASK_SEM_USING ;
pTask = pgos_tk_lookup( pSEMTkList->pSem->id ) ;
#else // SEM_FIFO
#if PG_SEM_PRIO == 1
pSEMTkListNxt = pSEMTkList ;
prio = 0 ;
for( ; pSEMTkList ; pSEMTkList = pSEMTkList->next )
{
if( pSEMTkList->pSem->state == TASK_SEM_SUSPEND )
{
if( pSEMTkList->pSem->prio > prio )
{
prio = pSEMTkList->pSem->prio ;
id = pSEMTkList->pSem->id ;
pSEMTkListNxt = pSEMTkList ;
}
}
}
pSEMTkList->pSem->state = TASK_SEM_USING ;
pTask = pgos_tk_lookup( id ) ;
#endif // SEM_PRIO
#endif // SEM( FIFO&PRIO )
pTask->state = PG_READY ;
if( pTask->prio > task_cur_prio )
{
pgos_int_enable() ;
pgos_tk_switch() ;
}
pgos_int_enable() ;
return PGOS_SUCCESS ;
}
#endif // SEM_SUPPORT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -