/*=========================================================================== _ B O S S _ S C H E D _ L I S T _ R E M O V E ---------------------------------------------------------------------------*/ static void _Boss_sched_list_remove(boss_tcb_t *p_tcb) { BOSS_ASSERT( (_BOSS_IRQ_() != 0) && (p_tcb->next != _BOSS_NULL) && (p_tcb->state == _TCB_LISTING) ); if(_sched_tcb_list == p_tcb) { _sched_tcb_list = p_tcb->next; BOSS_ASSERT(_sched_tcb_list != _BOSS_NULL); } else { boss_tcb_t *p_find = _sched_tcb_list; while(p_find->next != p_tcb) { p_find = p_find->next; BOSS_ASSERT(p_find != _BOSS_NULL); } p_find->next = p_tcb->next; } p_tcb->state = _TCB_WAITING; /* 스케줄러 리스트에서 제거됨 */ p_tcb->next = _BOSS_NULL; }
/*=========================================================================== _ B O S S _ S C H E D _ L I S T _ I N S E R T ---------------------------------------------------------------------------*/ static void _Boss_sched_list_insert(boss_tcb_t *p_tcb) { BOSS_ASSERT( (_BOSS_IRQ_() != 0) && (_sched_tcb_list != _BOSS_NULL) && (p_tcb->next == _BOSS_NULL) && (p_tcb->state == _TCB_WAITING) ); if(p_tcb->prio < _sched_tcb_list->prio) { p_tcb->next = _sched_tcb_list; _sched_tcb_list = p_tcb; } else { boss_tcb_t *p_prev = _sched_tcb_list; boss_tcb_t *p_next = p_prev->next; BOSS_ASSERT(p_next != _BOSS_NULL); while(p_next->prio <= p_tcb->prio) { p_prev = p_next; p_next = p_next->next; BOSS_ASSERT(p_next != _BOSS_NULL); } p_prev->next = p_tcb; p_tcb->next = p_next; } p_tcb->state = _TCB_LISTING; /* 스케줄러 리스트에 추가됨 */ }
/*=========================================================================== B O S S _ S P Y _ S T A C K _ C H E C K ---------------------------------------------------------------------------*/ void Boss_spy_stack_check(boss_tcb_t *p_tcb) { BOSS_ASSERT(p_tcb->ex.sp_base[0] == (boss_stk_t)0xEEEEEEEE); // Stack crack BOSS_ASSERT(p_tcb->ex.sp_base[1] == (boss_stk_t)0xEEEEEEEE); while( (p_tcb->ex.sp_peak[-1] != (boss_stk_t)0xEEEEEEEE) || (p_tcb->ex.sp_peak[-2] != (boss_stk_t)0xEEEEEEEE) || (p_tcb->ex.sp_peak[-3] != (boss_stk_t)0xEEEEEEEE) || (p_tcb->ex.sp_peak[-4] != (boss_stk_t)0xEEEEEEEE) #if 0 || (p_tcb->ex.sp_peak[-5] != (boss_stk_t)0xEEEEEEEE) || (p_tcb->ex.sp_peak[-6] != (boss_stk_t)0xEEEEEEEE) || (p_tcb->ex.sp_peak[-7] != (boss_stk_t)0xEEEEEEEE) || (p_tcb->ex.sp_peak[-8] != (boss_stk_t)0xEEEEEEEE) #endif ) { p_tcb->ex.sp_peak--; if(p_tcb->ex.sp_peak <= p_tcb->ex.sp_base) { BOSS_ASSERT(_BOSS_FALSE); // Stack overflow for(;;); } } BOSS_ASSERT(p_tcb->ex.sp_limit[-2] == (boss_stk_t)0xEEEEEEEE); // Stack crack BOSS_ASSERT(p_tcb->ex.sp_limit[-1] == (boss_stk_t)0xEEEEEEEE); }
/*=========================================================================== B O S S _ T M R _ S T A R T ---------------------------------------------------------------------------*/ void Boss_tmr_start( boss_tcb_t *p_tcb, boss_sigs_t sig, boss_tmr_ms_t tmr_ms, boss_tmr_ms_t rpt_ms ) { boss_tmr_t *p_tmr; BOSS_ASSERT(p_tcb != _BOSS_NULL); p_tmr = Boss_malloc(sizeof(boss_tmr_t)); p_tmr->p_tcb = p_tcb; p_tmr->sig = sig; p_tmr->tmr_ms = tmr_ms; p_tmr->rpt_ms = rpt_ms; p_tmr->prev = _BOSS_NULL; p_tmr->next = _BOSS_NULL; BOSS_IRQ_DISABLE(); /* 타이머 추가 */ if(_boss_timer_list != _BOSS_NULL) { BOSS_ASSERT(_boss_timer_list->prev == _BOSS_NULL); _boss_timer_list->prev = p_tmr; p_tmr->next = _boss_timer_list; } _boss_timer_list = p_tmr; Boss_sigs_clear(p_tcb, sig); BOSS_IRQ_RESTORE(); }
void addAtIndex(const T & e, const size_t & index) { BOSS_ASSERT(index <= size(), "Can't add at index: Index = %d, Size = %d", index, size()); BOSS_ASSERT(_size < capacity(),"Array over capacity: Size = %d",capacity()); copyShiftRight(index); _arr[index] = e; }
/*=========================================================================== B O S S _ T M R _ M F R E E _ D E L ---------------------------------------------------------------------------*/ void Boss_tmr_mfree_del(boss_tmr_t *p_tmr) { BOSS_ASSERT(p_tmr != _BOSS_NULL); Boss_tmr_stop(p_tmr); // 등록된 Timer이면 중지 Boss_mfree(p_tmr); }
/*=========================================================================== M A I N ---------------------------------------------------------------------------*/ int main(void) { Boss_device_init(); Boss_init(idle_main, &idle_tcb, (boss_stk_t *)idle_stack, sizeof(idle_stack)); Boss_task_create( aa_main, /* Task Entry Point */ _BOSS_NULL, /* Task Argument */ &aa_tcb, /* TCB(Task Control Block)*/ AA_PRIO_1, /* Priority */ (boss_stk_t *)aa_stk, /* Stack Point (Base) */ sizeof(aa_stk), /* Stack Size (Bytes) */ "AA" ); Boss_task_create( bb_main, _BOSS_NULL, &bb_tcb, BB_PRIO_2, (boss_stk_t *)bb_stk, sizeof(bb_stk), "BB" ); Boss_start(); /* Boss Scheduling Start */ BOSS_ASSERT(_BOSS_FALSE); /* Invalid */ return 0; }
Vec<T,max_capacity>(const size_t & size,const T & val) : _size(size) ,_capacity(max_capacity) { BOSS_ASSERT(size <= max_capacity,"Vec initializing with size > capacity, Size = %d, Capacity = %d",size,_capacity); fill(val); }
void remove_by_swap(const size_t & index) { BOSS_ASSERT(index < size(),"Vector out of bounds exception, Size = %d, Index = %d",size(),index); std::swap(_arr[index],_arr[size()-1]); pop_back(); }
/*=========================================================================== _ B O S S _ T I M E R _ C A L L B A C K _ E X E C U T E ---------------------------------------------------------------------------*/ void _Boss_timer_callback_execute(void) { boss_reg_t irq_storage; _Boss_sched_lock(); BOSS_IRQ_DISABLE_SR(irq_storage); while(_boss_timer_exe_list != _BOSS_NULL) { boss_tmr_t *p_done = _boss_timer_exe_list; _boss_timer_exe_list = p_done->next; BOSS_ASSERT(p_done->prev == _TRIMER_EXE_FIRST_PREV); if(p_done->next != _BOSS_NULL) { p_done->next->prev = _TRIMER_EXE_FIRST_PREV; } p_done->prev = _BOSS_NULL; p_done->next = _BOSS_NULL; BOSS_IRQ_RESTORE_SR(irq_storage); p_done->tmr_cb(p_done); // Callback Execute BOSS_IRQ_DISABLE_SR(irq_storage); } BOSS_IRQ_RESTORE_SR(irq_storage); _Boss_sched_free(); }
/*=========================================================================== _ B O S S _ S C H E D _ L O C K ---------------------------------------------------------------------------*/ void _Boss_sched_lock(void) { BOSS_ASSERT(_sched_locking < _SCHED_LOCKING_MAX); BOSS_IRQ_DISABLE(); _sched_locking++; BOSS_IRQ_RESTORE(); }
void copyShiftRight(const size_t & index) { BOSS_ASSERT(_size < capacity(),"Array over capacity: Size = %d",capacity()); for (size_t i(_size + 1); i > index; --i) { _arr[i] = _arr[i-1]; } _size++; }
/*=========================================================================== _ B O S S _ S C H E D _ F R E E ---------------------------------------------------------------------------*/ void _Boss_sched_free(void) { BOSS_ASSERT(_sched_locking > 0); BOSS_IRQ_DISABLE(); _sched_locking--; BOSS_IRQ_RESTORE(); _Boss_schedule(); }
void copyShiftLeft(const size_t & index) { BOSS_ASSERT(size() > 0, "Can't shift left when empty"); for (size_t i(index); i < size()-1; ++i) { _arr[i] = _arr[i+1]; } _size--; }
/*=========================================================================== B O S S _ S T A R T ---------------------------------------------------------------------------*/ void Boss_start(void) { BOSS_ASSERT( (_sched_locking == 1) && (_current_tcb == _BOSS_NULL) ); BOSS_IRQ_DISABLE(); _current_tcb = _sched_tcb_list; /* Best TCB */ _sched_locking = 0; /* 스케줄링 허용 */ BOSS_IRQ_RESTORE(); _Boss_start_schedule(); /* 스케줄러 시작 */ }
/*=========================================================================== _ B O S S _ S P Y _ C O N T E X T ---------------------------------------------------------------------------*/ void _Boss_spy_context(boss_tcb_t *curr_tcb, boss_tcb_t *best_tcb) { { /* [ Stack ] */ BOSS_ASSERT(curr_tcb->sp_base[0] == (boss_stk_t)0xEEEEEEEE); // Stack invasion while( (curr_tcb->sp_peak[-1] != (boss_stk_t)0xEEEEEEEE) || (curr_tcb->sp_peak[-2] != (boss_stk_t)0xEEEEEEEE) || (curr_tcb->sp_peak[-3] != (boss_stk_t)0xEEEEEEEE) || (curr_tcb->sp_peak[-4] != (boss_stk_t)0xEEEEEEEE) ) { curr_tcb->sp_peak--; BOSS_ASSERT(curr_tcb->sp_peak > curr_tcb->sp_base); // Stack overflow } } { /* [ C P U ] */ boss_u32_t now_us = _Boss_spy_elapse_us(); if( now_us < curr_tcb->cpu_ent_us ) { /* Tick Timer Pend */ now_us = now_us + ((boss_u32_t)_BOSS_TICK_MS_ * (boss_u32_t)1000); BOSS_ASSERT(now_us >= curr_tcb->cpu_ent_us); } curr_tcb->cpu_sum_us += now_us - curr_tcb->cpu_ent_us; best_tcb->cpu_ent_us = now_us; } /* [ Context Switch Number ] */ best_tcb->context++; /* [ ARM Cortex-Mx MSP (Main Stack Pointer) ] */ BOSS_ASSERT(_spy_msp.sp_base[0] == (boss_stk_t)0xEEEEEEEE); // Stack invasion while( (_spy_msp.sp_peak[-1] != (boss_stk_t)0xEEEEEEEE) || (_spy_msp.sp_peak[-2] != (boss_stk_t)0xEEEEEEEE) || (_spy_msp.sp_peak[-3] != (boss_stk_t)0xEEEEEEEE) || (_spy_msp.sp_peak[-4] != (boss_stk_t)0xEEEEEEEE) ) { _spy_msp.sp_peak--; BOSS_ASSERT(_spy_msp.sp_peak > _spy_msp.sp_base); // MSP Stack overflow } }
/*=========================================================================== _ B O S S _ M E M _ P O O L _ I N I T ---------------------------------------------------------------------------*/ static void _Boss_mem_pool_init(void) { _boss_mem_blk_t *first_blk = (_boss_mem_blk_t *)_memory_pool; BOSS_ASSERT( ((boss_uptr_t)_memory_pool & (_ALIGN_SIZE - 1)) == 0 ); BOSS_ASSERT( (sizeof(_memory_pool) & (_ALIGN_SIZE - 1)) == 0 ); BOSS_ASSERT( first_blk->size == 0 ); first_blk->in_use = _BOSS_FALSE; first_blk->size = sizeof(_memory_pool); first_blk->prev = _BOSS_NULL; first_blk->next = _BOSS_NULL; #ifdef _BOSS_MEM_INFO_ _boss_mem_info.used_size = 0; _boss_mem_info.used_peak = 0; _boss_mem_info.block = 1; _boss_mem_info.first = (_boss_mem_blk_t *)_memory_pool; #endif }
/*=========================================================================== B O S S _ I N I T ---------------------------------------------------------------------------*/ void Boss_init(void (*idle_task)(void *), boss_tcb_t *idle_tcb, boss_stk_t *sp_base, boss_uptr_t stk_bytes) { BOSS_ASSERT( (_sched_tcb_list == _BOSS_NULL) && (_sched_locking == 0) ); BOSS_IRQ_DISABLE(); _sched_locking = 1; /* 스케줄링 금지 */ _Boss_tcb_init(idle_tcb, PRIO_BOSS_IDLE, idle_task, _BOSS_NULL, sp_base, stk_bytes, "Idle"); idle_tcb->state = _TCB_LISTING; _sched_tcb_list = idle_tcb; BOSS_IRQ_RESTORE(); }
/*=========================================================================== B O S S _ T A S K _ C R E A T E ---------------------------------------------------------------------------*/ void Boss_task_create( void (*task)(void *p_arg), void *p_arg, boss_tcb_t *p_tcb, boss_prio_t prio, boss_stk_t *sp_base, boss_uptr_t stk_bytes, const char *name ) { BOSS_ASSERT(_sched_tcb_list != _BOSS_NULL); _Boss_tcb_init(p_tcb, prio, task, p_arg, sp_base, stk_bytes, name); BOSS_IRQ_DISABLE(); _Boss_sched_list_insert(p_tcb); BOSS_IRQ_RESTORE(); _Boss_schedule(); }
/*=========================================================================== _ B O S S _ S W I T C H _ C U R R E N T _ T C B ---------------------------------------------------------------------------*/ boss_stk_t *_Boss_switch_current_tcb(boss_stk_t *cur_task_sp) { BOSS_ASSERT(_sched_locking == 0); _current_tcb->sp = cur_task_sp; /* 실행중인 Task SP */ #ifdef _BOSS_SPY_ _Boss_spy_context(_current_tcb, _sched_tcb_list); #endif _current_tcb = _sched_tcb_list; /* Current TCB 변경 */ cur_task_sp = _current_tcb->sp; /* 실행할 Task SP */ return cur_task_sp; }
/*=========================================================================== B O S S _ T A S K _ P R I O R I T Y ---------------------------------------------------------------------------*/ void Boss_task_priority(boss_tcb_t *p_tcb, boss_prio_t new_prio) { BOSS_ASSERT(new_prio < PRIO_BOSS_IDLE); BOSS_IRQ_DISABLE(); p_tcb->prio = new_prio; if(p_tcb->state == _TCB_LISTING) /* schedule list update */ { _Boss_sched_list_remove(p_tcb); _Boss_sched_list_insert(p_tcb); } BOSS_IRQ_RESTORE(); _Boss_schedule(); }
/*=========================================================================== B O S S _ T A S K _ D E L E T E ---------------------------------------------------------------------------*/ void Boss_task_delete(void) { boss_tcb_t *cur_tcb; BOSS_ASSERT( (_BOSS_IRQ_() == 0) && (_BOSS_ISR_() == 0) && (Boss_sched_locking() == 0) ); cur_tcb = Boss_self(); BOSS_IRQ_DISABLE(); _Boss_sched_list_remove(cur_tcb); cur_tcb->wait = 0; BOSS_IRQ_RESTORE(); _Boss_schedule(); }
/*=========================================================================== B O S S _ W A I T ---------------------------------------------------------------------------*/ boss_sigs_t Boss_wait(boss_sigs_t wait_sigs) { boss_tcb_t *cur_tcb; BOSS_ASSERT( (_BOSS_IRQ_() == 0) && (_BOSS_ISR_() == 0) && (Boss_sched_locking() == 0) && (wait_sigs != 0) ); cur_tcb = Boss_self(); cur_tcb->wait = wait_sigs; BOSS_IRQ_DISABLE(); if( (cur_tcb->sigs & wait_sigs) == 0 ) /* 실행할 시그널이 없을면 */ { _Boss_sched_list_remove(cur_tcb); /* 스케줄러 리스트에서 제거 */ _Boss_context_switch(); /* 문맥 전환 실행 */ } BOSS_IRQ_RESTORE(); return Boss_sigs_receive(); }
/*=========================================================================== M A I N ---------------------------------------------------------------------------*/ int main(void) { (void)Boss_init(idle_task, _BOSS_NULL, idle_stack, sizeof(idle_stack)); (void)Boss_task_create( aa_task, /* Task Entry Point */ _BOSS_NULL, /* Task Argument */ aa_stk, /* 스택 포인터(base) */ sizeof(aa_stk), /* 스택 크기(Bytes) */ PRIO_1, /* 우선순위 */ "AA" /* 테스크 이름 */ ); (void)Boss_task_create(bb_task, _BOSS_NULL, bb_stk, sizeof(bb_stk), PRIO_2, "BB"); Boss_device_init(); /* 타이머 초기화 */ Boss_start(); /* Boss Scheduling Start */ BOSS_ASSERT(_BOSS_FALSE); /* Invalid */ return 0; }
/*=========================================================================== B O S S _ T M R _ S T A R T ---------------------------------------------------------------------------*/ void Boss_tmr_start(boss_tmr_t *p_tmr, boss_tmr_ms_t tmr_ms, tmr_cb_t callback) { Boss_tmr_stop(p_tmr); // 등록된 Timer이면 중지 p_tmr->tmr_ms = tmr_ms; p_tmr->tmr_cb = callback; p_tmr->prev = _TRIMER_ACT_FIRST_PREV; p_tmr->next = _BOSS_NULL; BOSS_IRQ_DISABLE(); if(_boss_timer_act_list != _BOSS_NULL) { BOSS_ASSERT(_boss_timer_act_list->prev == _TRIMER_ACT_FIRST_PREV); _boss_timer_act_list->prev = p_tmr; p_tmr->next = _boss_timer_act_list; } _boss_timer_act_list = p_tmr; BOSS_IRQ_RESTORE(); }
/*=========================================================================== M A I N ---------------------------------------------------------------------------*/ int main(void) { (void)Boss_init(idle_task, _BOSS_NULL, idle_stack, sizeof(idle_stack)); (void)Boss_task_create( aa_task, /* Task Entry Point */ _BOSS_NULL, /* Task Argument */ aa_stk, /* 스택 포인터(base) */ sizeof(aa_stk), /* 스택 크기(Bytes) */ PRIO_1, /* 우선순위 */ "AA" /* 테스크 이름 */ ); { int idx = 0; boss_prio_t prio = PRIO_3; for(idx=0; idx < CX_TASK_MAX; idx++) { char name[10]; sprintf(name, "C%02d", idx + 1); //prio++; /* 우선순위 및 타임아웃 테스트 */ (void)Boss_task_create( cx_task, /* Task Entry Point */ (void *)idx, /* Task Argument */ cx_stk[idx], /* Stack Point (Base) */ sizeof(cx_stk[idx]), /* Stack Size (Bytes) */ prio, /* Priority */ name /* Task Name String */ ); } } Boss_device_init(); /* 타이머 초기화 */ Boss_start(); /* Boss Scheduling Start */ BOSS_ASSERT(_BOSS_FALSE); /* Invalid */ return 0; }
/*=========================================================================== _ B O S S _ S P Y _ M S P _ C H E C K ---------------------------------------------------------------------------*/ void _Boss_spy_msp_check(void) { /* [ ARM Cortex-Mx MSP (Main Stack Pointer) ] */ while( (_boss_spy_msp_peak[-1] != (boss_stk_t)0xEEEEEEEE) || (_boss_spy_msp_peak[-2] != (boss_stk_t)0xEEEEEEEE) || (_boss_spy_msp_peak[-3] != (boss_stk_t)0xEEEEEEEE) || (_boss_spy_msp_peak[-4] != (boss_stk_t)0xEEEEEEEE) #if 1 || (_boss_spy_msp_peak[-5] != (boss_stk_t)0xEEEEEEEE) || (_boss_spy_msp_peak[-6] != (boss_stk_t)0xEEEEEEEE) || (_boss_spy_msp_peak[-7] != (boss_stk_t)0xEEEEEEEE) || (_boss_spy_msp_peak[-8] != (boss_stk_t)0xEEEEEEEE) #endif ) { _boss_spy_msp_peak--; if(_boss_spy_msp_peak <= _Boss_spy_msp_base()) { BOSS_ASSERT(_BOSS_FALSE); // MSP Stack overflow for(;;); } } }
/*=========================================================================== _ B O S S _ S P Y _ S E T U P ---------------------------------------------------------------------------*/ void _Boss_spy_setup(boss_tcb_t *p_tcb, boss_stk_t *sp_base, boss_uptr_t bytes) { { /* SPY TCB 등록 */ boss_reg_t idx; for(idx = 0; idx < _BOSS_SPY_TCB_MAX; idx++) { if(_spy_tcb_tbl[idx] == _BOSS_NULL) { _spy_tcb_tbl[idx] = p_tcb; break; } } BOSS_ASSERT(idx < _BOSS_SPY_TCB_MAX); } { /* [ Stack ] */ boss_uptr_t size = bytes / sizeof(boss_stk_t); boss_uptr_t i; for(i = 0; i < size; i++) { sp_base[i] = (boss_stk_t)0xEEEEEEEE; // 스택 [E] empty } p_tcb->sp_base = &sp_base[0]; p_tcb->sp_peak = &sp_base[size-1]; p_tcb->sp_limit = &sp_base[size]; } /* [ C P U ] */ p_tcb->cpu_ent_us = 0; p_tcb->cpu_sum_us = 0; /* [ Context Switch Number ] */ p_tcb->context = 0; }
/*=========================================================================== B O S S _ M A L L O C ---------------------------------------------------------------------------*/ void *Boss_malloc(boss_uptr_t size) { static boss_reg_t _mem_pool_init = _BOSS_FALSE; _boss_mem_blk_t *p_alloc; if(_mem_pool_init == _BOSS_FALSE) { BOSS_IRQ_DISABLE(); _Boss_mem_pool_init(); /* Memory Pool init */ _mem_pool_init = _BOSS_TRUE; BOSS_IRQ_RESTORE(); } /* 메모리 크기 정렬 */ size = size + ( sizeof(_boss_mem_blk_t) + (_ALIGN_SIZE-1) ); size = size & ~(_ALIGN_SIZE-1); p_alloc = (_boss_mem_blk_t *)_memory_pool; //BOSS_ASSERT(p_alloc->size > size); /* First 할당 */ BOSS_IRQ_DISABLE(); /* 할당 가능한 블럭을 찾는다. */ while( p_alloc && ((p_alloc->size < size) || (p_alloc->in_use != _BOSS_FALSE)) ) { p_alloc = p_alloc->next; } if(p_alloc != _BOSS_NULL) { if( p_alloc->size > (size + sizeof(_boss_mem_blk_t) + _ALIGN_SIZE) ) { /* 메모리 블럭 분할 시 */ _boss_mem_blk_t *p_prev = p_alloc; p_prev->size = p_prev->size - size; /* 블럭 분할 */ p_alloc = (_boss_mem_blk_t *)((boss_uptr_t)p_prev + p_prev->size); p_alloc->size = size; p_alloc->prev = p_prev; p_alloc->next = p_prev->next; p_prev->next = p_alloc; if(p_alloc->next != _BOSS_NULL) { p_alloc->next->prev = p_alloc; } #ifdef _BOSS_MEM_INFO_ _boss_mem_info.block++; #endif } p_alloc->in_use = _MEM_MAGIC_CODE_; /* 메모리 할당 */ #ifdef _BOSS_MEM_INFO_ _boss_mem_info.used_size += p_alloc->size; if( _boss_mem_info.used_size > _boss_mem_info.used_peak ) { _boss_mem_info.used_peak = _boss_mem_info.used_size; } #endif p_alloc = (_boss_mem_blk_t *)( (boss_uptr_t)p_alloc + sizeof(_boss_mem_blk_t) ); } BOSS_IRQ_RESTORE(); BOSS_ASSERT(p_alloc != _BOSS_NULL); /* 메모리 FULL */ return (void *)p_alloc; }
/*=========================================================================== B O S S _ M F R E E ---------------------------------------------------------------------------*/ void Boss_mfree(void *p) { _boss_mem_blk_t *p_prev; _boss_mem_blk_t *p_free; _boss_mem_blk_t *p_next; p_free = (_boss_mem_blk_t *)( (boss_uptr_t)p - sizeof(_boss_mem_blk_t) ); BOSS_ASSERT( p_free->in_use == _MEM_MAGIC_CODE_ ); BOSS_ASSERT( (_MEM_POOL_START <= (void *)p_free) && ((void *)p_free < _MEM_POOL_END) ); BOSS_IRQ_DISABLE(); BOSS_ASSERT( (p_free->prev != _BOSS_NULL) ? (p_free->prev->next == p_free) : (_MEM_POOL_START == p_free) ); BOSS_ASSERT( (p_free->next != _BOSS_NULL) ? (p_free->next->prev == p_free) : ((boss_uptr_t)p_free + p_free->size == (boss_uptr_t)_MEM_POOL_END) ); #ifdef _BOSS_MEM_INFO_ _boss_mem_info.used_size -= p_free->size; #endif p_free->in_use = _BOSS_FALSE; /* 메모리 블럭 해제 */ p_next = p_free->next; if( (p_next != _BOSS_NULL) && (p_next->in_use == _BOSS_FALSE) ) /* 병합 (뒤) */ { BOSS_ASSERT( ((boss_uptr_t)p_next - (boss_uptr_t)p_free) == p_free->size); p_free->size = p_free->size + p_next->size; p_free->next = p_next->next; if(p_next->next != _BOSS_NULL) { p_next->next->prev = p_free; } #ifdef _BOSS_MEM_INFO_ p_next->size = 0; p_next->next = _BOSS_NULL; p_next->prev = _BOSS_NULL; _boss_mem_info.block--; #endif } p_prev = p_free->prev; if( (p_prev != _BOSS_NULL) && (p_prev->in_use == _BOSS_FALSE) ) /* (앞) 병합 */ { BOSS_ASSERT( ((boss_uptr_t)p_free - (boss_uptr_t)p_prev) == p_prev->size ); p_prev->size = p_prev->size + p_free->size; p_prev->next = p_free->next; if(p_free->next != _BOSS_NULL) { p_free->next->prev = p_prev; } #ifdef _BOSS_MEM_INFO_ p_free->size = 0; p_free->next = _BOSS_NULL; p_free->prev = _BOSS_NULL; _boss_mem_info.block--; #endif } BOSS_IRQ_RESTORE(); }