Time slice based task routine in C

发布时间 2023-12-12 18:24:32作者: wallywl

 

          基于时间片的轮询任务调度实例。

#include <stdint.h>
#include <stdio.h>
#include <WinSock2.h>
 

#define MAX_TASK_NUM                 10
#define MAX_HALF_WORD                0xffff

#define false    0
#define true     1

static uint16_t g_ticks;

typedef uint8_t (*p_task_func)(uint16_t ticks, uint16_t time_elapsed, uint32_t in_param);


typedef struct task_list{

    p_task_func pfunc;
    uint32_t in_param;
    uint16_t timestamp;
}TASK_ST;


TASK_ST taskList[MAX_TASK_NUM];


static uint16_t time_elapsed_get(uint16_t past, uint16_t now){
    
    if (now >= past){
        return (now-past);
    } else {
        return (MAX_HALF_WORD - past + now);
    }
}


void task_init(void){
    uint8_t i = 0;
    
    for(i = 0; i < MAX_TASK_NUM; i++){
        taskList[i].pfunc = NULL;
        taskList[i].timestamp = 0;
    }
}


uint8_t task_is_register(p_task_func pfunc, uint32_t in_param){
    uint8_t i = 0;
    
    for(i = 0; i < MAX_TASK_NUM; i++){
        if (taskList[i].pfunc == pfunc &&
           taskList[i].in_param == in_param){
            
            return true;
        }
    }
    
    return false;
}


void task_register(p_task_func pfunc, uint32_t in_param){
    uint8_t i = 0;
    uint8_t rv = 0;
    
    rv = task_is_register(pfunc, in_param);
    if (rv){
        return;
    }
    
    for(i = 0; i < MAX_TASK_NUM; i++){
        if (taskList[i].pfunc == NULL){
            taskList[i].pfunc = pfunc;
            taskList[i].in_param = in_param;
            taskList[i].timestamp = g_ticks;
            return;
        }
    }
}


void task_run(uint16_t ticks){
    uint8_t i = 0;
    uint8_t rv = 0;
    uint16_t time_elapsed = 0;
    
    g_ticks = ticks;
     
    for(i = 0; i < MAX_TASK_NUM; i++){
        if (taskList[i].pfunc){
            time_elapsed = time_elapsed_get(taskList[i].timestamp, ticks);
            rv = taskList[i].pfunc(ticks, time_elapsed, taskList[i].in_param);
            if (rv){
                taskList[i].timestamp = ticks;
            }
        }        
    }
}


void task_unregister(p_task_func pfunc, uint32_t in_param, uint8_t ignore_param){
    uint8_t i = 0;
    
    for(i = 0; i < MAX_TASK_NUM; i++){
        if (taskList[i].pfunc == pfunc ){
           if (ignore_param){
               taskList[i].pfunc = NULL;  
               continue;             
           }
           
           if (taskList[i].in_param == in_param){
              taskList[i].pfunc = NULL;
              return ;
           }
        }
    }        
}


uint8_t hello(uint16_t ticks, uint16_t time_elapsed, uint32_t in_param){
   
   if (ticks % 10 == 0){   
      printf("hi %d\n", in_param + ticks);
   }
   
   if (time_elapsed == 20){
       task_unregister(hello, 0, true);
   }
   
   return false;    
}


void main()
{ 
     struct timeval  tv = {0};
     uint16_t tick = 0;
     uint8_t rv = 0;
     
     tv.tv_sec = 1;    //second
     tv.tv_usec = 0;   //us
     
     task_init();
     
     task_register(hello, 5);
     
     WSADATA ws;
     WSAStartup(MAKEWORD(2,2), &ws);    // init windows socket dll
     SOCKET delaysock = socket(AF_INET,SOCK_STREAM, 0);    
    
     fd_set s_read; 
     
     while(1){
         //select(0, NULL, NULL, NULL, &tv);   //for linux
         
         FD_ZERO(&s_read);
         FD_SET(delaysock, &s_read);                 
         select(delaysock+1, &s_read, NULL, NULL, &tv);  //for windows
         
         printf("tick %d\n", tick);
                           
         tick++;
         task_run(tick); 
         
         rv = task_is_register(hello, 5);
         if (!rv){             
             break;
         }        
     }
     
     WSACleanup();
     
     printf("exited.\n");

}

    cudaText 中在extTools 插件中编译命令如下:

    gcc compile cmd:

  C:\Program Files\CodeBlocks\MinGW\bin\gcc.exe

   "{FileNameOnly}" -o "{FileNameNoExt}"  -lwsock32 && cmd /c  "{FileNameNoExt}"