이제는 스케줄링을 담당하는 소스를 살펴 보겠다.[[BR]] 우선 내가 만든 프로그램에서 스케줄링을 담당하는 큐는 대략 WAIT 와 SUSPEND 그리고 FREE 큐로 나누어 질 수 있다. WAIT은 실행 가능하지만 멈춰 진 태스크를 위한 큐 SUSPEND는 인터럽트를 대기하던가? 아님 뭔가를 기다리기 위해 실행이 중지된 상태? 자원이겠찌? 그리고 FREE 큐는 메모리상에 존재하지만 죽은 태스크를 담아 놓은 큐.....쯔쯔쯔 불쌍도 해라.[[BR]] 음..이렇게 나누어지고 WAIT큐의 0번째 태스크가 지금 실행 중인 태스크를 지칭한다.[[BR]] 음..여하튼 이렇게 말했으니 그럼 소스를 설명해 볼까? {{{~cpp #if !defined(LIB_SCHE_CPP) #define LIB_SCHE_CPP /* Init The Scheduler List */ }}} 이 함수는 스케쥴링을 위한 준비 과정 TCB들을 다 초기화 해 준다.. 겁이 많아서 그냥 다 초기화 해줬다.[[BR]] 그리고 나서 지금의 가장 높은 태스크를 스타트 TCB로 지칭해 준다.초기화 끝[[BR]] {{{~cpp void LIB_Init_Schedu(){ for (int count = 0;count LIB_MAX_PRIORITY ) return; <--------- 우선순위가 지랄 같으면 그냥 끝낸다. // Insert Prio Queue; pReady_heap[ready_tcb_ptr] = LIB_free_TCB(); // Init the TCB by argument <----- 함수에서 얻은 변수들로... 초기화...ok??? pReady_heap[ready_tcb_ptr]->Task_Name = task_name; pReady_heap[ready_tcb_ptr]->delay = 0; pReady_heap[ready_tcb_ptr]->priority = priority; pReady_heap[ready_tcb_ptr]->StackSeg = (INT16U)FP_SEG(Stack); pReady_heap[ready_tcb_ptr]->StackOff = INT16U(Stack) - 28; pReady_heap[ready_tcb_ptr]->Stack = Stack; /// 여기서 부터는 우선순위 큐를 쓴다.... 열라 간단했는 데... <----- 사실상 우선순위 큐가 몇백번 돈 뒤에도 그 큐의 상태를 유지하는 것이 좀 어려웠다.. 쉽게 말해 손으로 태스팅 할 때 큐에 태스크를 넣었다 빼면 되는 거 같지만 컴퓨터가 컨텍스트 스위칭을 위해 몇백번 큐에 넣었다 뺐따 할때는 크크 갑자기 뻗는 상황이 재현.... -------> int temp_count = ready_tcb_ptr; LIB_TCB *Temp_TCB; ready_tcb_ptr++; while (1) { if ( pReady_heap[temp_count]->priority > pReady_heap[tree_parent(temp_count)]->priority ){ Temp_TCB = pReady_heap[temp_count]; pReady_heap[temp_count] = pReady_heap[tree_parent(temp_count)]; pReady_heap[tree_parent(temp_count)] = Temp_TCB; temp_count = tree_parent(temp_count); } else { break; } } } }}} SUSPEND 된 TASK 들을 다시 살려주는 고마운 펑션 {{{~cpp /* Resume task */ void LIB_resume_task(INT16U priority ){ if ( priority == 0 ) return; LIB_ENTER_CRITICAL(); int temp; for ( int i = 0; i<= suspend_tcb_ptr ; i++ ) { if ( pSuspend_heap[i]->priority == priority ) { pReady_heap[ready_tcb_ptr] = pSuspend_heap[i]; pSuspend_heap[i] = pSuspend_heap[suspend_tcb_ptr]; pSuspend_heap[suspend_tcb_ptr] = NULL; suspend_tcb_ptr--; temp = ready_tcb_ptr; goto EX_LOOP1; } } LIB_VRAM_STRING(0,15,"CAUTION !!!",0x07); return; EX_LOOP1: LIB_TCB *temp_tcb; while (1) { if ( pReady_heap[temp]->priority > pReady_heap[tree_parent(temp)]->priority ) { temp_tcb = pReady_heap[tree_parent(temp)]; pReady_heap[tree_parent(temp)] = pReady_heap[temp]; pReady_heap[temp] = temp_tcb; temp = tree_parent(temp); } else break; } ready_tcb_ptr++; LIB_EXIT_CRITICAL(); LIB_context_sw(); } }}} /// 태스크 서스팬드 하기......넌 이제 좀 쉬어라... SUSPEND 큐에 넣어주고 WAIT 큐에서 빼준다...... 쯔쯔쯔 {{{~cpp /* Wait task */ void LIB_suspend_task(INT16U priority){ LIB_ENTER_CRITICAL(); int temp; for(int i = 0 ; i <= ready_tcb_ptr ; i++ ) { if ( pReady_heap[i]->priority == priority ){ // ready -> suspend pSuspend_heap[++suspend_tcb_ptr] = pReady_heap[i]; // ready queue sort pReady_heap[i] = pReady_heap[ready_tcb_ptr-1]; pReady_heap[ready_tcb_ptr-1] = NULL; temp = i; ready_tcb_ptr--; goto EX_LOOP; } } LIB_VRAM_STRING(0,15,"CAUTION !!!",0x07); return; EX_LOOP: LIB_TCB *temp_tcb; while (1) { if ( pReady_heap[tree_left(temp)]->priority > pReady_heap[temp]->priority ) { temp_tcb = pReady_heap[tree_left(temp)]; pReady_heap[tree_left(temp)] = pReady_heap[temp]; pReady_heap[temp] = temp_tcb; temp = tree_left(temp); } else if ( pReady_heap[tree_right(temp)]->priority > pReady_heap[temp]->priority ) { temp_tcb = pReady_heap[tree_right(temp)]; pReady_heap[tree_right(temp)] = pReady_heap[temp]; pReady_heap[temp] = temp_tcb; temp = tree_right(temp); } else break; } LIB_EXIT_CRITICAL(); LIB_context_sw(); } }}} 죽은 태스크들은 FREE큐로 가거라...왜냐 죽었잖아... 실행을 중지시키기 위해서는 FREE큐에 태스크를 넣어준다..... {{{~cpp /* Delete the Task */ int LIB_del_task(LIB_TCB *task){ int temp_count; LIB_TCB *Temp_TCB; for ( int i = 0; i < LIB_MAX_HEAP ; i++ ){ if ( pReady_heap[i] == task ) { free_tcb_ptr++; pFreeTCB[free_tcb_ptr] = pReady_heap[i]; pReady_heap[i] = pReady_heap[ready_tcb_ptr]; pReady_heap[ready_tcb_ptr] = NULL; temp_count = i; ready_tcb_ptr--; while (1) { if ( pReady_heap[tree_left(temp_count)] != NULL) { if ( pReady_heap[tree_left(temp_count)]->priority > pReady_heap[temp_count]->priority ){ Temp_TCB = pReady_heap[temp_count]; pReady_heap[temp_count] = pReady_heap[tree_left(temp_count)]; pReady_heap[tree_left(temp_count)] = Temp_TCB; temp_count = tree_left(temp_count); } else break; } else break; } } if ( pSuspend_heap[i] == task) { free_tcb_ptr++; pFreeTCB[free_tcb_ptr] = pSuspend_heap[i]; pSuspend_heap[i] = pSuspend_heap[suspend_tcb_ptr]; pSuspend_heap[suspend_tcb_ptr] = NULL; suspend_tcb_ptr--; return success; } } LIB_Schedul(); return fail; } /* Resume task */ void LIB_resume_list(INT16U priority ){ int temp; for ( int i = 0; i<= suspend_tcb_ptr ; i++ ) { if ( pSuspend_heap[i]->priority == priority ) { pReady_heap[ready_tcb_ptr] = pSuspend_heap[i]; pSuspend_heap[i] = pSuspend_heap[suspend_tcb_ptr]; pSuspend_heap[suspend_tcb_ptr] = NULL; suspend_tcb_ptr--; temp = ready_tcb_ptr; goto EX_LOOP1; } } return; EX_LOOP1: LIB_TCB *temp_tcb; while (1) { if ( pReady_heap[temp]->priority > pReady_heap[tree_parent(temp)]->priority ) { temp_tcb = pReady_heap[tree_parent(temp)]; pReady_heap[tree_parent(temp)] = pReady_heap[temp]; pReady_heap[temp] = temp_tcb; } else break; } ready_tcb_ptr++; } }}} 가장 우선순위가 높은 걸 찾아준다... {{{~cpp /* Find Ready Task & Run the Task */ void LIB_Schedul() { High_Task = pReady_heap[0]; } #endif LIB_SCHE_CPP }}} 음..내가 교수도 아니고 스케쥴링이 오에스에서 가장 중요할 것이다.. 그럼에도 불구하고 허접하다.[[BR]] 사실 내가 만든 것과 U_C_OS 와의 실행 속도 차이는 무지하게 크다. 이유는 소스를 보면 알 것이다..[[BR]] 여하튼..하지만..그래도 내 소스가 더 보기 쉽지 않나?? ㅋㅋㅋㅋㅋ [[BR]] 실행속도가 차이는 나지만 그래도 나름대로의 방식으로 만들려고 노력했다..그래서[[BR]] 이모양 이꼴인 오에스가 되었지만............[[BR]] ---- ["REAL_LIBOS"]