//----创建线程----------------------------------------------------------------- //功能:为事件类型创建线程,初始化上下文环境,安装执行函数,构成完整线程 //参数:evtt_id,待创建的线程所服务的事件类型id //返回:新创建的线程指针 //注: 移植敏感函数 //----------------------------------------------------------------------------- struct tagThreadVm *__CreateThread(struct tagEventType *evtt,u32 *stack_size) { struct tagThreadVm *result; ptu32_t len; //计算线程栈:线程+最大单个api需求的栈 len = evtt->stack_size+CN_KERNEL_STACK+sizeof(struct tagThreadVm); //栈顶需要对齐,malloc函数能保证栈底是对齐的,对齐长度可以使栈顶对齐 len = align_up_sys(len); result=(struct tagThreadVm *)__MallocStack(len); *stack_size = len; if(result==NULL) { Djy_SaveLastError(EN_MEM_TRIED); //内存不足,返回错误 return result; } #if CN_CFG_STACK_FILL != 0 len = M_CheckSize(result); memset(result,CN_CFG_STACK_FILL,len); #endif //看实际分配了多少内存,djyos内存分配使用块相联策略,如果分配的内存量大于 //申请量,可以保证其实际尺寸是对齐的。之所以注释掉,是因为当len大于申请量时, //对齐只是实际结果,而不是内存管理的规定动作,如果不注释掉,就要求内存管理 //模块必须提供对齐的结果,对模块独立性是不利的。 // len = M_CheckSize(result); result->stack_top = (u32*)((ptu32_t)result+len); //栈顶地址,移植敏感 result->next = NULL; result->stack_size = len - sizeof(struct tagThreadVm); //保存栈深度 result->host_vm = NULL; //复位线程并重置线程 __asm_reset_thread(evtt->thread_routine,result); return result; }
//----静态创建线程------------------------------------------------------------- //功能:为事件类型创建线程,初始化上下文环境,安装执行函数,构成完整线程 //参数:evtt_id,待创建的线程所服务的事件类型id //返回:新创建的线程指针 //注: 移植敏感函数 //----------------------------------------------------------------------------- struct tagThreadVm *__CreateStaticThread(struct tagEventType *evtt,void *Stack, u32 StackSize) { struct tagThreadVm *result; ptu32_t len; result = (struct tagThreadVm *)align_up_sys(Stack); #if CN_CFG_STACK_FILL != 0 memset(Stack,CN_CFG_STACK_FILL,StackSize); #endif //看实际分配了多少内存,djyos内存分配使用块相联策略,如果分配的内存量大于 //申请量,可以保证其实际尺寸是对齐的。之所以注释掉,是因为当len大于申请量时, //对齐只是实际结果,而不是内存管理的规定动作,如果不注释掉,就要求内存管理 //模块必须提供对齐的结果,对模块独立性是不利的。 // len = M_CheckSize(result); result->stack_top = CreateThread( NULL, 0, win_engine, evtt->thread_routine, CREATE_SUSPENDED, NULL ); result->stack = 0; result->next = NULL; result->stack_size = 0; //保存栈深度 result->host_vm = NULL; //复位线程并重置线程 __asm_reset_thread(evtt->thread_routine,result); return result; }
// ============================================================================= // 函数功能:__CreateThread // 创建线程 // 输入参数:evtt,线程关联的evtt // 输出参数:stack_size,创建的VM的stack的大小 // 返回值 : // 说明 :将evtt中的内容恢复到创建的VM当中 // ============================================================================= struct tagThreadVm *__CreateThread(struct tagEventType *evtt,u32 *stack_size) { struct tagThreadVm *result; ptu32_t len; //计算虚拟机栈:线程+最大单个api需求的栈 len = evtt->stack_size+CN_KERNEL_STACK+sizeof(struct tagThreadVm); //栈顶需要对齐,malloc函数能保证栈底是对齐的,对齐长度可以使栈顶对齐 len = align_up_sys(len); result=(struct tagThreadVm *)(__MallocStack(len)); *stack_size = len; if(result==NULL) { Djy_SaveLastError(EN_MEM_TRIED); //内存不足,返回错误 return result; } #if CN_CFG_STACK_FILL != 0 memset(result,CN_CFG_STACK_FILL,len); #endif result->stack_top = (u32*)((ptu32_t)result+len); //栈顶地址,移植敏感 result->next = NULL; result->stack_size = len - sizeof(struct tagThreadVm); //保存栈深度 result->host_vm = NULL; //复位虚拟机并重置线程 __asm_reset_thread(evtt->thread_routine,result); return result; }
//----静态创建线程------------------------------------------------------------- //功能:为事件类型创建线程,初始化上下文环境,安装执行函数,构成完整线程 //参数:evtt_id,待创建的线程所服务的事件类型id //返回:新创建的线程指针 //注: 移植敏感函数 //----------------------------------------------------------------------------- struct tagThreadVm *__CreateStaticThread(struct tagEventType *evtt,void *Stack, u32 StackSize) { struct tagThreadVm *result; result = (struct tagThreadVm *)align_up_sys(Stack); #if CN_CFG_STACK_FILL != 0 memset(Stack,CN_CFG_STACK_FILL,StackSize); #endif //看实际分配了多少内存,djyos内存分配使用块相联策略,如果分配的内存量大于 //申请量,可以保证其实际尺寸是对齐的。之所以注释掉,是因为当len大于申请量时, //对齐只是实际结果,而不是内存管理的规定动作,如果不注释掉,就要求内存管理 //模块必须提供对齐的结果,对模块独立性是不利的。 // len = M_CheckSize(result); result->stack_top = (u32 *)(align_down_sys((ptu32_t)Stack+StackSize)); //栈顶地址,移植敏感 result->next = NULL; result->stack_size = (ptu32_t)(result->stack_top) - (ptu32_t)result - sizeof(struct tagThreadVm); //保存栈深度 result->host_vm = NULL; //复位线程并重置线程 __asm_reset_thread(evtt->thread_routine,result); return result; }
ptu32_t __M_StaticFormatSize(ptu32_t size) { return align_up_sys(size); //准静态分配,对齐即可 }
void __memHeapScan(void) { struct tagHeapCB *HeapTemp; struct tagHeapCession *Cession; u32 CessionNum,Ctrlsize,NameLen,n; u8 *Offset; u32 *u32Offset; u32 HeapNo=0; u32 AlignSize; Offset = (u8*)&pHeapList; CessionNum = *(u32*)Offset; while(CessionNum != 0) //本循环取得所需堆控制块数量 { u32Offset = (u32*)Offset + 1; AlignSize = *u32Offset++; //以下计算公式,参看lds文件格式 Offset += sizeof(u32)*3*CessionNum + 2*sizeof(u32); NameLen = __memStrLen((char*)Offset); //计算heap控制块和session控制块所需要的内存尺寸。 Ctrlsize = NameLen + 1 + sizeof( struct tagHeapCB ) + CessionNum * sizeof(struct tagHeapCession); Ctrlsize = align_up_sys(Ctrlsize); Cession = NULL; //下面for循环功能: //1、扫描所有session,找到第一个满足Ctrlsize需求的session。 //2、在该session顶部分配用于控制结构的内存。 //3、丢弃size小于Ctrlsize的session。 //4、按准静态分配的要求初始化heap控制块和session控制块。 //5、把所有的session连接成链表 for(n = 0; n < CessionNum; n++) { if(Cession != NULL) { Cession->static_bottom = (void*)(*u32Offset); Cession->heap_bottom = (void*)(*u32Offset); Cession->heap_top = (void*)(*(u32Offset+1)); #if ((CN_CFG_DYNAMIC_MEM == 1)) Cession->PageSize = *(u32Offset+2); #endif if(n == CessionNum -1) Cession->Next = NULL; else Cession->Next = Cession+1; Cession++; } //找到了第一个符合要求的session if((Cession == NULL) && ((*(u32Offset+1) - *u32Offset) >=Ctrlsize)) { HeapTemp = (struct tagHeapCB *)(*(u32Offset+1) - Ctrlsize); HeapTemp = (struct tagHeapCB *)align_down_sys(HeapTemp); if(tg_pHeapList == NULL) { tg_pHeapList = HeapTemp; tg_pHeapList->NextHeap = HeapTemp; tg_pHeapList->PreHeap = HeapTemp; //第一个堆可做系统堆。 if(HeapNo == 0) tg_pSysHeap = tg_pHeapList; } else { HeapTemp->NextHeap = tg_pHeapList; HeapTemp->PreHeap = tg_pHeapList->PreHeap; tg_pHeapList->PreHeap->NextHeap = HeapTemp; tg_pHeapList->PreHeap = HeapTemp; } Cession = (struct tagHeapCession*)(HeapTemp + 1); HeapTemp->Cession = Cession; HeapTemp->CessionNum = CessionNum - n; if(AlignSize == 0) HeapTemp->AlignSize = CN_ALIGN_SIZE; else HeapTemp->AlignSize = AlignSize; HeapTemp->HeapName = (char *)Offset; #if ((CN_CFG_DYNAMIC_MEM == 1)) HeapTemp->mem_sync = NULL; #endif Cession->static_bottom = (void*)(*u32Offset); Cession->heap_bottom = (void*)(*u32Offset); Cession->heap_top = (void*)HeapTemp; #if ((CN_CFG_DYNAMIC_MEM == 1)) Cession->PageSize = *(u32Offset+2); #endif if(n == CessionNum -1) Cession->Next = NULL; else Cession->Next = Cession+1; Cession++; } Ctrlsize -= sizeof(struct tagHeapCession); u32Offset += 3; } Offset += NameLen + 1; //+1跨过串结束符 Offset = (u8*)align_up(sizeof(u32),Offset); CessionNum = *(u32*)Offset; HeapNo++; } }