当前位置: 首页 > news >正文

珠海做公司网站百度搜索排行榜风云榜

珠海做公司网站,百度搜索排行榜风云榜,网站导航一定要一样吗,11网拍推广平台创建线程 用户在基于RTOS开发应用程序前,首先要创建线程。 用户创建一个线程时须指定用户希望采用的调度策略。 例如,用户想创建一个周期性执行的线程: acoral_period_policy_data_t* data; data acoral_malloc(sizeof(acoral_period_poli…

创建线程

用户在基于RTOS开发应用程序前,首先要创建线程。
用户创建一个线程时须指定用户希望采用的调度策略
例如,用户想创建一个周期性执行的线程:

acoral_period_policy_data_t* data;
data = acoral_malloc(sizeof(acoral_period_policy_data_t));
data->prio=5;
data->prio_type=ACORAL_HARD_PRIO;
data->time=2000;acoral_crate_thread(test,512,NULL,"test",NULL,ACORAL_SCHED_POLICY_PERIOD,data);
int create_thread(void (*route)(void *args),unsigned int sttack_size,void *args,char *name,void *stack,unsigned int sched_policy,void *data){acoral_thread_t *thread;thread=alloc_thrad();if(NULL==thread){acoral_print("Alloc thread:%s fail\n",name);acoral_print("No Mem Space or Beyond the max thread\n");return -1;}thread->name = name;stack_size = stack_size&(~3); //将stack_size变量的值取为向下取整的4的倍数thread->stack_size = stack_size;if(stack!=NULL)thread->stack_buttom = (unsigned int *)stack;elsethread->stack_buttom=NULL;thread->policy = sched_policy;return acoral_policy_thread_init(sched_policy,threadd,route,args,data);
}

分配线程空间

创建线程需要做的第一项工作就是为该线程分配内存空间,线程是通过TCB描述的,为该线程分配内存空间就是为TCB分配内存空间,其返回值是刚分配的TCB的指针。

acoral_pool_ctr_t acoral_thread_pool_ctrl;acoral_thread_t *acoral_alloc_thread(){return (acoral_thread_t *)acoral_get_res(&acoral_thread_pool_ctrl);
}
/*资源池控制块*/
typedef struct{unsigned int type;//资源类型unsigned int size; //资源大小,如线程控制块大小,用sizeof(acoral_thread_t)赋值unsigned int num_per_pool;//每个资源池对象的个数unsigned int num;   //已分配的资源池的个数unsigned int max_pools; //最多可以分配多少个资源池acoral_list_t *frree_pools; //空闲资源池链表acoral_list_t *pools,list[2];unsigned char *name;
}

资源池管理的资源内存是从第一级内存系统(伙伴系统)分配的,为了最大限度使用内存,减少内存碎片,对象的个数,最大值、可分配内存等都是通过计算后由用户指定的。
例如,伙伴算法设定基本内存块的大小为1KB,资源的大小为1KB,用户一个资源池包含20个资源,这样计算下来需要分配1x20=20KB的空间,而由于伙伴系统只能分配2i个基本内存块的大小,故会分配32KB,32KB可以包含32个资源对象,故每个资源池的对象的个数更改为32.

线程初始化

return acoral_policy_thread_init(sched_policy,thread,route,args,data);
int acoral_policy_thread_init(unsigned int policy,acoral_thread_t *thread,void (*route)(void *args),void *args,void *data){acoral_sched_policy_t *policy_ctrl;policy_ctrl = acoral_get_policy_ctrl(policy);if(policy_ctrl==NULL||polciy_ctrl->policy_thread_init==NULL){acoral_enter_critical();acoral_release_res((acoral_res_t *)thread);acoral_exit_critical();acoral_print("No thread policy support:%d\n",thread->policy);return -1;}return policy_ctrl->policy_thread_init(thread route args,data);
}
int period_policy_thread_init(acoral_thread_t *thread,void (*route)(void *args),void *args,void *data){unsigned int prio;acoral_period_policy_data_t *policy_data;period_private_data_t *private_data;if(thread->polciy==ACORAL_SCHED_POLICY_PERIOD){policy_data = (acoral_period_policy_data_t *)data;prio=policy_data->prio;if(policy_data->prio_type==ACORAL_NONHARD_PRIO){prio+=ACORAL_NONHARD_RT_PRIO_MAX;if(prio>=ACORAL_NONHARD_RT_PRIO_MIN)prio=ACORAL_NONHARD_RT_PRIO_MIN-1;}thread->prio = prio;private_data = (period_private_data_t *)acoral_malloc(sizeof(period_private_Data_t));if(private_data==NULL){acoral_print("No level2 mem space for private_data:%s\n",thread->name);acoral_enter_critical();acoral_release_res((acoral_res_t *)thread);acoral_exit_critical();return -1;}private_data->time=policy_data->time;private_data->route=route;private_data->args=args;thread->private_data=private_data;}if(acoral_thread_init(thread,route,period_thread_exit,args)!=0){acoral_print("No thread stack:%s\n",thread->name);acoral_enter_critical();acoral_release_res((acoral_res_t *)thread);acoral_exit_critical();return -1;}acoral_resume_thread(thread);acoral_enter_critical();period_thread_delay(thread,((period_private_data_t *)thread->private_data)->time);acoral_exit_critical();return thread->res.id;
}

堆栈初始化

acoral_list_t acoral_threads_queue;//全局所有线程队列unsigned int acoral_thread_init(acoral_thread_t *thread,void (route)(void *args),void (*exit)(void),void *args){unsigned int stack_size = thread->stack_size;if(thread->stack_buttom==NULL){	//判断堆栈指针是否为NULL,如果堆栈指针为NULL,说明需动态分配。if(stack_size<CFG_MIN_STACK_SIZE)stack_size=CFG_MIN_STACK_SIZE;thread->stack_buttom=(unsigned int *)acoral_malloc(stack_size);if(thread->stack_buttom==NULL)return ACORAL_ERR_THREAD_NO_STACK;thread->stack_size = stack_size;}thread->stack=(unsigned int *)((char *)thread->stack_buttom+stack_size-1);HAL_STACK_INIT(&thread->stack,route,exit,args);//模拟线程创建时的堆栈环境thread->data = NULL;thread->state = ACORAL_THREAD_STATE_SUSPEND;acoral_init_list(&thread->waiting);acoral_init_list(&thread->ready);acoral_init_list(&thread->timeout);acoral_init_list(&thread->global_list);acoral_enter_critical();acoral_list_add2_tail(&thread->global_list,&acoral_threads_queue);//将刚创建的线程挂到全局队列尾部acoral_exit_critical();return 0;
}

HAL_STACK_INIT()是与硬件相关的函数,不同处理器有不同寄存器,这些寄存器体现了当前线程的运行环境,如果当前线程被其它中断或线程所抢占,将发生上下文切换。
需要通过堆栈来保存被抢占线程的运行环境,那先保存哪个寄存器,再保存哪个寄存器?这就需要根据处理器的结构而定,HAL_STACK_INIT()就是用来规定寄存器保存顺序的。

typedef struct{unsigned int primask;unsigned int r4; ///<通用寄存器unsigned int r5; ///<通用寄存器unsigned int r6; ///<通用寄存器unsigned int r7; ///<通用寄存器unsigned int r8; ///<通用寄存器unsigned int r9; ///<通用寄存器unsigned int r10; ///<通用寄存器unsigned int r11; ///<通用寄存器unsigned int r0; ///<通用寄存器unsigned int r1; ///<通用寄存器unsigned int r2; ///<通用寄存器unsigned int r3; ///<通用寄存器unsigned int r12; ///<通用寄存器unsigned int lr;unsigned int pc;unsigned int cpsr;
}hal_ctx_t;
  • primask:用于保存中断优先级屏蔽寄存器的值
  • r0~r11:通用寄存器,用于保存临时变量、函数参数和返回值
  • r12:通用寄存器,用于保存调用者的中间值
  • lr:链接寄存器,保存跳转指令返回时的地址
  • pc:程序计数器,保存当前正在执行的指令地址
  • cpsr:程序状态寄存器,保存了当前CPU的状态,包括标志位和CPU模式等。

由于是用C语言来模拟线程创建时的堆栈环境,所以用宏转换定义hal_stack_init()来实现HAL_STACK_INIT()
HAL_STACK_INIT(&thread->stack,route,exit,args);

void hal_stack_init(acoral_u32 **stk,void (*route)(),void (*exti)(),void *args){hal_ctx_t *ctx = *stk;ctx--;ctx=(hal_ctx_t *)((unsigned int *)ctx+1);ctx->r0=(unsigned int)args;ctx->r1=0;ctx->r2=2;ctx->r3=3;ctx->r4=4;ctx->r5=5;ctx->r6=6;ctx->r7=7;ctx->r8=8;ctx->r9=9;ctx->r10=10;ctx->r11=11;ctx->r12=12;ctx->lr=(unsigned int)exit;ctx->pc=(unsigned int)route;ctx->primask=0;*stk=(unsigned int *)ctx; //将指针传给stk,而stk是用户创建堆栈指针变量地址
}

挂载线程到就绪队列

void resume_thrad(acoral_thread_t *thread){if(!(thread->state&ACORAL_THREAD_STATE_SUSPEND)) //如果当前状态不处于suspend状态,则不需要唤醒。return;acoral_enter_critical();acoral_rdyqueue_add(thread);acoral_exit_critical();acoral_sched();	
}
void acoral_rdy_thread(acoral_thread_t *thread){if(!(ACORAL_THREAD_STATE_SUSPEND&thread->state))return;acoral_rdyqueue_add(thread);
}
//acoral就绪队列
typedef struct{unsigned int num;//就绪的线程数unsigned int bitmap[PRIO_BITMAP_SIZE];acoral_list_t queue[ACORAL_MAX_PRIO_NUM];
}acoral_rdy_queue_t;acoral_rdy_queue_t acoral_ready_queues;void acoral_rdyqueue_add(acoral_thread_t *thread){acoral_rdy_queue_t *rdy_queue;rdy_queue = &acoral_ready_queues;acoral_prio_queue_add(rdy_queue,thread->prio,&thread->ready);thread->state &= ~ACORAL_THREAD_STATE_SUSPEND;thread->state |= ACORAL_THREAD_STATE_READY;aoral_set_need_sched(true);
}
void acoral_prio_queue_add(acoral_rdy_queue_t *array,unsigned char prio,acoral_list_t *list){acoral_list_t *queue;acoral_list_t *head;array->num++;queue = array->queue + prio; //根据线程优先级找到线程所在的优先级链表head = queue;acoral_list_add_tail(list,head); //将该线程挂到优先级链表上acoral_set_bit(prio,array->bitmap);
}

调用acoral_sched()

一个普通线程创建的最后一步是调用内核调度函数acoral_sched()

真正意义上的多任务操作系统,都要通过一个调度程序(Scheduler)来实现调度功能,该调度程序以函数形式存在,用来实现操作系统的调度策略,可在内核的各个部分进行调用。
调用调度程序的具体位置又被称为是一个调度点,由于调度通常是由外部事件的中断来触发的,或者由周期性的时钟信号触发,因此调度点通常出于以下位置:

  1. 中断服务程序结束的位置。例如,当用户通过按键向系统提出新的请求,系统首先以中断服务程序ISR响应用户请求。然后在中断服务程序结束时创建新的任务,并将新任务挂载到就绪队列尾部。接下来,RTOS会进入一个调度点,调用调度程序,执行相应的调度策略。又如,当I/O中断发生时,如果I/O事是一个或多个任务正在等待的事件,则在I/O中断结束时刻,也将会进入一个调度点,调用调度程序,调度程序将根据调度策略确定是否继续执行当前处于运行状态的任务,或是让高优先级任务抢占低优先级任务。
  2. 运行任务因缺乏资源而被阻塞的时刻。例如,使用串口UART传输数据,如果UART此时正在被其他任务使用,这将导致当前任务从就绪状态变为等待状态,不能继续执行,而RTOS会进入一个调度点,调用调度程序。
  3. 任务周期开始或结束时。
  4. 高优先级任务就绪的时刻,如果采用基于优先级抢占式调度策略。

普通线程创建流程

  1. 为线程分配空间
  2. 然后根据创建线程的调度策略对线程TCB进行相关的初始化
  3. 然后对线程的堆栈进行初始化
  4. 将创建的线程挂到就绪队列上
  5. 供内核调度
http://www.zhongyajixie.com/news/13328.html

相关文章:

  • 基于php网站建设设计惠州seo公司
  • 短网址生成原理关键词seo价格
  • 影响网站建设价格的因素有互联网营销是什么意思
  • 网站开发价目表移动网站优化排名
  • 上不了建设银行网站百度搜索风云榜游戏
  • 网站制作与网站建设海外短视频跨境电商平台是真的吗
  • 利用jsp做网站培训网
  • 网页设计师网站自己建网站需要钱吗
  • 网站建设和网络优化常见的网络营销工具
  • 珠海市企业网站制作平台微信营销的10种方法技巧
  • 如何免费自己做网站关键字排名优化工具
  • 专业网站建设哪家权威旅游网站网页设计
  • 新乡网站设计公司广告推广渠道有哪些
  • 单位的网站怎样设计才美观南京seo新浪
  • 怎样做写真网站小红书搜索关键词排名
  • 外贸网站建设价格惠州seo网络推广
  • 保险网站定制做百度关键词排名的公司
  • 网站备案麻烦吗制作网页的软件
  • 做视频网站需要执照吗百度的特点和优势
  • 做网站服务器空间网络推广竞价是什么
  • 个人经营性网站备案怎么学seo基础
  • 桑拿网站只做推广软文范例
  • wordpress生成海报图片插件seo网站营销推广公司
  • 旅游网站繁体asp宣传软文怎么写
  • 甘肃营销型网站建设吉安seo网站快速排名
  • 网站建设网站免费软件测试培训
  • web前端如何仿网站2022适合小学生的简短新闻
  • 内网 wordpress慢seo优化厂商
  • 今日头条新闻头条百度seo技术优化
  • 无锡seo公司网站seo诊断服务