西科人BBS_西安科技大学学生论坛

 找回密码
 立即注册
楼主: 无线狂人

给大家看一段我写的程序,呵呵,能看懂的请举手~~

[复制链接]
 楼主| 发表于 2005-3-8 13:10:39 | 显示全部楼层
死亡骑士,你是一个很上进的孩子,估计你是学计算机或者通信的吧?呵呵。

你的C语言根基不错,但你缺乏必要的实际项目经验。

我来给你讲解一下你专门提出的程序段。大家共同提高!
 楼主| 发表于 2005-3-8 13:14:24 | 显示全部楼层
首先,我们来看看这个程序来自那里,完成什么功能。

它是我独自开发的操作系统PGOS中关于线程同步方面的一些操作系统的核心代码。我把拿出来我为了让大家接触一下真正的,我们在使用程序的样子是什么。这个程序是信号量支持部分。

不知道你学过〈操作系统〉这门课程吗?上面一定会提到信号量。好,我们先来看看一些数据结果和API定义。(哈,为了给你讲解,我把所有的信号量方面的代码都open了 -_-! )

// PGOS -- Semaphores Sercice Programme

#ifndef PG_TYPE
#include "pg_type.h"
#endif


#define  PG_SEM

#define  MAXSEM  2
#define  MAXSEMWAIT 3

#define  TASK_SEM_USING  0x00
#define  TASK_SEM_SUSPEND  0xFF
#define  TASK_SEM_NOTUSE    0xF0

#define  SEM_USE  0x00
#define  SEM_NOTUSE 0x01

#define  TASK_FIRST     0x00
#define  TASK_APPEND  0xFF   

typedef  struct  _pg_sem
{
    BYTE  id ;
    BYTE  state ;
#if  PG_SEM_PRIO == 1
    BYTE   prio ;
#endif
} pgSEMTASK ;

typedef struct _pg_semtk_list
{
    pgSEMTASK*  pSem ;
    struct _pg_semtk_list*  next ;
}pgSEMTKLIST ;

typedef struct  _pg_sem_list
{
    WORD  Sem ;
    pgSEMTKLIST*  list ;
    BYTE    state ;
    BYTE    tasknum ;       
    struct  _pg_sem_list*  next ;       
}pgSEMLIST ;

// BASIC Semaphores Operations Support  
PGOS_STATUS  pgos_sem_init() ;
PGOS_STATUS  pgos_sem_cre( WORD SemNum ) ;
PGOS_STATUS  pgos_sem_wait( WORD SemNum ) ;
PGOS_STATUS  pgos_sem_post( WORD SemNum ) ;

// Functions call by PGOS Kernel
pgSEMTKLIST*      pgos_sem_initklist() ;
pgSEMLIST*          pgos_sem_inilist() ;
pgSEMTASK*         pgos_sem_initk() ;
PGOS_STATUS      pgos_sem_addtask( pgSEMTKLIST* list, BYTE id, BYTE mode ) ;
 楼主| 发表于 2005-3-8 13:16:53 | 显示全部楼层
注意上面的代码经常使用#指令,大量使用这些预编译指令可以使你的程序更加健壮,可移植性更好。在我的PGOS中,为了适应不同的CPU体系结构,我大量使用了#,同时为了使PGOS达到设想中的“可配置,可裁减”所以在一个CFG文件中,为用户开放了大量的可配置选则。为了支持这些,必须在代码中用#if..#endif来支持。
 楼主| 发表于 2005-3-8 13:18:04 | 显示全部楼层
现在来看看真正的实现部分,完全开放所有的实现程序 :

#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_tk_switch() ;
                  pgos_int_enable() ;
                  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_tk_switch() ;
         }
        pgos_int_enable() ;
        return  PGOS_SUCCESS ;
}
         
#endif // SEM_SUPPORT
 楼主| 发表于 2005-3-8 13:24:00 | 显示全部楼层
http://gro.clinux.org/projects/pgos/

需要完整的PGOS代码你可以访问。
发表于 2005-3-8 13:29:40 | 显示全部楼层
谢谢```谢谢``````容我慢慢看```
发表于 2005-3-8 21:16:15 | 显示全部楼层
师兄就是厉害,我也是自动化的,你也是,对吗?
可惜我现在连PC都看不懂,呵呵,无奈
6级也没过,还要考研,都疯掉了,快

真希望和你一样大学本科毕业能够找到一份好工作

你真的太厉害了,没办法

不过我会努力的
发表于 2005-3-20 22:54:44 | 显示全部楼层
哈```最近复习软考 看到操作系统的知识 这段功能我明白了```
涉及到P,V操作 避免冲突的等待```
真的是很很佩服你```不是一个"强"字能描述的
 楼主| 发表于 2005-3-21 15:54:55 | 显示全部楼层
恩,明白了就好 :)

仔细看看里面是算法,我个人认为比较经典。
发表于 2005-3-27 07:59:25 | 显示全部楼层
周日早上来看了1个多小时```
wait 和post 两段 (非常)^n 精彩啊```
我什么时候才能达到这个高度啊```
努力~~!!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|西科人BBS ( 粤ICP备20049523号-3 )

GMT+8, 2026-3-25 11:46 , Processed in 0.040138 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表