임 베 디 드 운영 체제 커 널 원리 와 개발 (등가 block 메모리 풀 디자인)
typedef struct MEM_POOL
{
RAW_COMMON_BLOCK_OBJECT common_block_obj;
/* Define the number of available memory blocks in the pool. */
RAW_U32 raw_block_pool_available;
/* Define the head pointer of the available block pool. */
RAW_U8 *raw_block_pool_available_list;
} MEM_POOL;
메모리 탱크 의 구 조 는 매우 간단 하 다. 주로 유 니 버 설 블록 구조, block 수치, block 시작 지침 을 포함한다.메모리 탱크 아래 에는 몇 개의 block 을 포함 할 수 있 습 니 다. 모든 block 의 크기 는 같 습 니 다. 또한 block 사 이 는 링크 를 통 해 연결 되 어 있 습 니 다. 이것 은 우리 가 뒤의 코드 를 보면 알 수 있 습 니 다.mempool 의 처리 함수 가 많 지 않 습 니 다. 세 개 만 초기 화, 신청, 방출 함수 입 니 다.RAW_U16 raw_block_pool_create(MEM_POOL *pool_ptr, RAW_U8 *name_ptr, RAW_U32 block_size, RAW_VOID *pool_start, RAW_U32 pool_size)
{
//MEM_POOL *tail_ptr; /* Working block pool pointer */
RAW_U32 blocks; /* Number of blocks in pool */
RAW_U8 *block_ptr; /* Working block pointer */
RAW_U8 *next_block_ptr; /* Next block pointer */
RAW_U8 *end_of_pool; /* End of pool area */
RAW_U8 block_align_mask;
#if (RAW_BLOCK_FUNCTION_CHECK > 0)
/* Check for invalid pool size. */
if (pool_size < (block_size + block_size) ) {
return RAW_BLOCK_SIZE_ERROR;
}
if (pool_ptr == 0) {
return RAW_NULL_OBJECT;
}
if (pool_start == 0) {
return RAW_NULL_POINTER;
}
#endif
block_align_mask = sizeof(void *) - 1u;
if (((RAW_U32)pool_start & block_align_mask)){
return RAW_INVALID_ALIGN;
}
if ((pool_size & block_align_mask)) {
return RAW_INVALID_ALIGN;
}
if ((block_size & block_align_mask)) {
return RAW_INVALID_ALIGN;
}
/*Init the list*/
list_init(&pool_ptr->common_block_obj.block_list);
/* Setup the basic block pool fields. */
pool_ptr ->common_block_obj.name = name_ptr;
pool_ptr ->common_block_obj.block_way = 0;
/* Calculate the end of the pool's memory area. */
end_of_pool = (RAW_U8 *) pool_start + pool_size;
/* Walk through the pool area, setting up the available block list. */
blocks = 0;
block_ptr = (RAW_U8 *) pool_start;
next_block_ptr = block_ptr + block_size;
while (next_block_ptr <= end_of_pool) {
blocks++;
if (next_block_ptr == end_of_pool) {
break;
}
/* Setup the link to the next block. */
*((RAW_U8 * *) block_ptr) = next_block_ptr;
/* Advance to the next block. */
block_ptr = next_block_ptr;
/* Update the next block pointer. */
next_block_ptr = block_ptr + block_size;
}
/* Set the last block's forward pointer to NULL. */
*((RAW_U8 * *) block_ptr) = 0;
/* Save the remaining information in the pool control block. */
pool_ptr ->raw_block_pool_available = blocks;
pool_ptr ->raw_block_pool_available_list = (RAW_U8 *) pool_start;
return RAW_SUCCESS;
}
위 는 메모리 탱크 의 생 성 함수 입 니 다. 입 참 은 모두 다섯 개의 매개 변수 가 있 는데 그것 이 바로 mempool 구조, 이름, block 크기, pool 시작 주소, pool 크기 입 니 다.함수 기본 내용 은 다음 과 같다.(1) 메모리 탱크, 포인터 파라미터 의 합 법성 을 판단 한다.
(2) 포인터 가 n 바이트 의 정렬 여 부 를 검사 합 니 다. n 은 주소 의 크기 에 달 려 있 습 니 다.
(3) 블록 체인 테이블 을 구축 하고 앞 뒤 가 연결 되 며 마지막 블록 은 NULL 지침 을 가리킨다.
(4) pool 의 첫 주 소 를 raw 에 할당 합 니 다.block_pool_available_list, 함수 반환.
RAW_U16 raw_block_allocate(MEM_POOL *pool_ptr, RAW_VOID **block_ptr, RAW_U32 wait_option)
{
RAW_U16 status;
RAW_U8 *work_ptr;
RAW_SR_ALLOC();
#if (RAW_BLOCK_FUNCTION_CHECK > 0)
if (pool_ptr == 0) {
return RAW_NULL_OBJECT;
}
if (block_ptr == 0) {
return RAW_NULL_POINTER;
}
if (raw_int_nesting) {
if (wait_option != RAW_NO_WAIT) {
return RAW_NOT_CALLED_BY_ISR;
}
}
#endif
RAW_CRITICAL_ENTER();
/* Determine if there is an available block. */
if (pool_ptr ->raw_block_pool_available) {
/* Yes, a block is available. Decrement the available count. */
pool_ptr ->raw_block_pool_available--;
/* Pickup the current block pointer. */
work_ptr = pool_ptr ->raw_block_pool_available_list;
/* Return the first available block to the caller. */
*((RAW_U8 **)block_ptr) = work_ptr;
/* Modify the available list to point at the next block in the pool. */
pool_ptr ->raw_block_pool_available_list = *((RAW_U8 **)work_ptr);
/* Set status to success. */
status = RAW_SUCCESS;
}
/*if no block memory is available then do it depend wait_option*/
else {
if (wait_option == RAW_NO_WAIT) {
*((RAW_U8 **)block_ptr) = 0;
RAW_CRITICAL_EXIT();
return RAW_NO_PEND_WAIT;
}
/*system is locked so task can not be blocked just return immediately*/
if (raw_sched_lock) {
*((RAW_U8 **)block_ptr) = 0;
RAW_CRITICAL_EXIT();
return RAW_SCHED_DISABLE;
}
raw_pend_object(&pool_ptr->common_block_obj, raw_task_active, wait_option);
RAW_CRITICAL_EXIT();
raw_sched();
RAW_CRITICAL_ENTER();
*((RAW_U8 **)block_ptr) = 0;
status = block_state_post_process(raw_task_active, block_ptr);
RAW_CRITICAL_EXIT();
}
return status;
}
다른 메모리 풀 신청 함수 와 달리 wait 가 있 습 니 다.option 옵션.현재 적당 한 block 이 없다 면 대기 처 리 를 선택 할 수 있다 는 것 이다.다른 스 레 드 가 메모 리 를 방출 하면 스케줄 링 을 받 아 계속 실행 할 수 있 습 니 다.물론 기다 리 지 않 아 도 됩 니 다. 적당 한 block 을 찾 지 못 하면 바로 NULL 로 돌아 갑 니 다.RAW_U16 raw_block_release(MEM_POOL *pool_ptr, RAW_VOID *block_ptr)
{
LIST *block_list_head;
RAW_U8 *work_ptr; /* Working block pointer */
RAW_U8 need_schedule = 0;
RAW_SR_ALLOC();
#if (RAW_BLOCK_FUNCTION_CHECK > 0)
if (block_ptr == 0) {
return RAW_NULL_OBJECT;
}
if (pool_ptr == 0) {
return RAW_NULL_OBJECT;
}
#endif
block_list_head = &pool_ptr->common_block_obj.block_list;
RAW_CRITICAL_ENTER();
work_ptr = ((RAW_U8 *) block_ptr);
if (is_list_empty(block_list_head)) {
/* Put the block back in the available list. */
*((RAW_U8 **) work_ptr) = pool_ptr ->raw_block_pool_available_list;
/* Adjust the head pointer. */
pool_ptr ->raw_block_pool_available_list = work_ptr;
/* Increment the count of available blocks. */
pool_ptr ->raw_block_pool_available++;
}
else {
need_schedule = 1;
wake_send_msg(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list), block_ptr);
}
RAW_CRITICAL_EXIT();
if (need_schedule) {
raw_sched();
}
/* Return completion status. */
return RAW_SUCCESS;
}
다른 메모리 free 함수 와 달리 여기 free 함수 에 wake 가 하나 더 생 겼 습 니 다.send_msg 기능.물론 자원 을 기다 리 는 스 레 드 가 존재 한다 면 자원 을 이 스 레 드 에 보 내 는 동시에 이 스 레 드 를 깨 우 고 needschedule 을 1 로 설정 해 야 합 니 다.물론 기다 리 는 스 레 드 가 없다 면 링크 앞 에 메모 리 를 직접 삽입 하면 됩 니 다. 이렇게 간단 합 니 다.이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.