예제 #1
0
파일: thread.c 프로젝트: Rafe/CuRT
err_t thread_resume(tid_t tid)
{
	cpu_sr_t cpu_sr;
	thread_struct *pthread;

	if (tid < IDLE_THREAD_TID || tid > MAX_THREAD)
		return RET_ERR;

	if (thread_table[tid] == NULL)
		return RET_ERR;

	cpu_sr = save_cpu_sr();
	pthread = thread_table[tid];
	if (pthread->state == BLOCK) {
		pthread->state = READY;
		delete_list(&pthread->node);
		insert_back_list(&ready_list[pthread->prio], &pthread->node);
		prio_exist_flag[pthread->prio] = true;
		restore_cpu_sr(cpu_sr);
		schedule(SCHED_THREAD_REQUEST);
		return RET_NO_ERR;
	}
	restore_cpu_sr(cpu_sr);
	return RET_ERR;
}
예제 #2
0
파일: thread.c 프로젝트: Rafe/CuRT
err_t thread_suspend(tid_t tid)
{
	cpu_sr_t cpu_sr;
	thread_struct *pthread;

	if (tid < IDLE_THREAD_TID || tid > MAX_THREAD)
		return RET_ERR;

	if (thread_table[tid] == NULL)
		return RET_ERR;

	cpu_sr = save_cpu_sr();
	pthread = thread_table[tid];
	if (current_thread->tid == tid) {
		pthread->state = BLOCK;
		insert_back_list(&blocked_list, &pthread->node);
		restore_cpu_sr(cpu_sr);
		schedule(SCHED_THREAD_REQUEST);
		return RET_NO_ERR;
	}
	else if (pthread->prio > current_thread->prio &&
	         pthread->state == READY) {
		pthread->state = BLOCK;
		delete_list(&pthread->node);
		insert_back_list(&blocked_list, &pthread->node);
		restore_cpu_sr(cpu_sr);
		schedule(SCHED_THREAD_REQUEST);
		return RET_NO_ERR;
	}
	restore_cpu_sr(cpu_sr);
	return RET_ERR;
}
예제 #3
0
파일: sync.c 프로젝트: hdl645/study_cuRT
err_t sem_try_pend(sem_struct *sem)
{
	cpu_sr_t cpu_sr;

	cpu_sr = save_cpu_sr();
	if (sem->value > 0) {
		sem->value--;
		restore_cpu_sr(cpu_sr);
		return RET_NO_ERR;
	}
	else {
		restore_cpu_sr(cpu_sr);
		return RET_ERR;
	}
}
예제 #4
0
파일: sync.c 프로젝트: hdl645/study_cuRT
void sem_pend(sem_struct *sem)
{
	cpu_sr_t cpu_sr;
	list_node_t *pnode;
	thread_struct *pthread;

	cpu_sr = save_cpu_sr();
	if (sem->value == 0) {
		if (!is_empty_list(&sem->wait_list)) {
			for (pnode = begin_list(&sem->wait_list);
			     pnode != end_list(&sem->wait_list); 
			     pnode = next_list(pnode)) {
				pthread = entry_list(pnode, thread_struct, node);
				if (current_thread->prio < pthread->prio) {
					current_thread->state = EVENT_WAIT;
					insert_before_list(
						pnode,
						&current_thread->node);
					break;
				}
			}
		}
		if (current_thread->state != EVENT_WAIT) {
			current_thread->state = EVENT_WAIT;
			insert_back_list(&sem->wait_list, &current_thread->node);
		}
		schedule(SCHED_THREAD_REQUEST);
		return;
	}
	sem->value--;
	restore_cpu_sr(cpu_sr);
}
예제 #5
0
파일: kernel.c 프로젝트: pianyu/mCuRT
/**
 * @brief Invoke the scheduler
 * The scheduler is called in the following two cases:
 *   - thread's time_quantum value is 0 (SCHED_TIME_EXPIRE) and then stop.
 *   - Request the execution for higher priority thread (SCHED_THREAD_REQUEST).
 */
void schedule(SCHED_TYPE sched_type)
{
	int top_prio;
	cpu_sr_t cpu_sr;

	cpu_sr = save_cpu_sr();
	top_prio = get_top_prio();
	/* If the timer expires... */
	if (sched_type == SCHED_TIME_EXPIRE) {
		/* Threads that are currently running will continue to run it
		 * at the highest priority */
		if (current_thread->prio < top_prio) {
			current_thread->time_quantum = TIME_QUANTUM;
			restore_cpu_sr(cpu_sr);
			return;
		}

		select_next_thread(top_prio);
		put_current_ready();

		/* actual context switching */
		context_switch_in_interrupt();
	}
	/* requested by a thread */
	else if (sched_type == SCHED_THREAD_REQUEST ) {
		/* Threads that are currently running will continue to run it
		 * at the highest priority. */
		if (current_thread->state == RUNNING &&
		    current_thread->prio < top_prio ) {
			current_thread->time_quantum = TIME_QUANTUM;
			restore_cpu_sr(cpu_sr);
			return;
		}

		select_next_thread(top_prio);

		if (current_thread->state == RUNNING) {
			put_current_ready();
		}
		/* context switching */
		context_switch();
	}
	total_csw_cnt++;
	restore_cpu_sr(cpu_sr);
}
예제 #6
0
파일: sync.c 프로젝트: hdl645/study_cuRT
void sem_post(sem_struct *sem)
{
	thread_struct *pthread;
	cpu_sr_t cpu_sr;

	cpu_sr = save_cpu_sr();
	if (!is_empty_list(&sem->wait_list)) {
		pthread = entry_list(delete_front_list(&sem->wait_list),
		                     thread_struct, node);
		pthread->state = READY;
		insert_back_list(&ready_list[pthread->prio], &pthread->node);
		prio_exist_flag[pthread->prio] = true;
		restore_cpu_sr(cpu_sr);
		schedule(SCHED_THREAD_REQUEST);
		return;
	}
	sem->value++;
	restore_cpu_sr(cpu_sr);
}
예제 #7
0
/**
 * @brief Create thread
 *
 * @param thread - thread of the information contained threads structure
 * @param thread_stk - Created a pointer to the thread stack space
 * @param func - Generated a thread of the function
 * @param name - Thread name
 * @param prio - The priority of threads
 * @param pdata - Pass parameters to the function of a thread running
 * @retval RET_NO_ERR
 * @retval RET_ERR
 */
tid_t thread_create(thread_struct *thread,
		    stk_t *thread_stk,
		    THREAD_FUNC func,
		    char *name,
		    u8_t prio,
		    void *pdata)
{
	cpu_sr_t cpu_sr;
	stk_t *pstk;
	thread_struct *pthread;
	tid_t tid;

	if (thread == NULL || thread_stk == NULL || func == NULL ||
	    name == NULL || (prio >= MAX_PRIO))
		return RET_ERR;

	pstk = thread_stk;
	pthread = thread;

	/* no failback */
	if ((tid = get_tid()) == RET_ERR) {
		return RET_ERR;
	}

	/* constrct thread_struct */
	pthread->tid = tid;
	pthread->stack_ptr = init_thread_stack(func, pdata, pstk);
	pthread->name = name;
	pthread->prio = prio;
	pthread->time_quantum = TIME_QUANTUM;
	pthread->delayed_time = 0;
	pthread->state = READY;

	cpu_sr = save_cpu_sr();
	thread_table[tid] = pthread;
	prio_exist_flag[prio] = true;
	total_thread_cnt++;
	insert_back_list(&ready_list[prio], &pthread->node);
	restore_cpu_sr(cpu_sr);

	/* if priority higher than existing thread, invoke the scheduler. */
	if (is_start_os == true && current_thread->prio > prio) {
		schedule(SCHED_THREAD_REQUEST);
	}

	printf("thread_create:%d\n", prio);

	return tid;
}
예제 #8
0
파일: thread.c 프로젝트: Rafe/CuRT
err_t thread_delay(u32_t tick)
{
	cpu_sr_t cpu_sr;

	if (tick > 0) { /* Delay must be greater than 0. */
		cpu_sr = save_cpu_sr();
		current_thread->state = DELAY;
		current_thread->delayed_time = tick;
		insert_back_list(&delayed_list, &current_thread->node);
		restore_cpu_sr(cpu_sr);
		schedule(SCHED_THREAD_REQUEST);
		return RET_NO_ERR;
	}
	return RET_ERR;
}
예제 #9
0
파일: kernel.c 프로젝트: pianyu/mCuRT
void start_curt()
{
	cpu_sr_t cpu_sr;
	list_node_t *pnode;
	int top_prio;

	cpu_sr = save_cpu_sr();
	is_start_os = true;
	/* examine the highest priority thread executed */
	top_prio = get_top_prio();
	pnode = delete_front_list(&ready_list[top_prio]);
	if (is_empty_list(&ready_list[top_prio]))
		prio_exist_flag[top_prio] = false;
	current_thread = entry_list(pnode, thread_struct, node);
	current_thread->state = RUNNING;
	restore_cpu_sr(cpu_sr);
	restore_context();
}
예제 #10
0
파일: kernel.c 프로젝트: pianyu/mCuRT
/**
 * @brief time tick advanced
 * Maintain time_quantum
 */
void advance_time_tick()
{
	cpu_sr_t cpu_sr;
	list_node_t *pnode;
	thread_struct *pthread;
	thread_struct *readyed_thread = NULL;

	cpu_sr = save_cpu_sr();
	os_time_tick++;
	/* If there are delays in the list of threads... */
	if (!is_empty_list(&delayed_list)) {
		for (pnode = begin_list(&delayed_list);
		     pnode != end_list(&delayed_list);
		     pnode = next_list(pnode) ) {
			pthread = entry_list(pnode, thread_struct, node);
			pthread->delayed_time--;
			/* ready to change the status */
			if (readyed_thread != NULL) {
				delete_list(&readyed_thread->node);
				readyed_thread->state = READY;
				readyed_thread->time_quantum = TIME_QUANTUM;
				insert_back_list(
					&ready_list[readyed_thread->prio],
					&readyed_thread->node);
				prio_exist_flag[readyed_thread->prio] = true;
				readyed_thread = NULL;
			}
			if (pthread->delayed_time <= 0) {
				readyed_thread = pthread;
			}
		}
		if (readyed_thread != NULL) {
			delete_list(&readyed_thread->node);
			readyed_thread->state = READY;
			readyed_thread->time_quantum = TIME_QUANTUM;
			insert_back_list(
				&ready_list[readyed_thread->prio],
				&readyed_thread->node);
			prio_exist_flag[readyed_thread->prio] = true;
		}
	}
	current_thread->time_quantum--;
	restore_cpu_sr(cpu_sr);
}
예제 #11
0
파일: thread.c 프로젝트: Rafe/CuRT
err_t thread_delete(tid_t tid)
{
	cpu_sr_t cpu_sr;

	if (tid < IDLE_THREAD_TID || tid > MAX_THREAD)
		return RET_ERR;

	if (thread_table[tid] == NULL)
		return RET_ERR;

	cpu_sr = save_cpu_sr();
	if (tid == current_thread->tid) {
		current_thread->state = TERMINATE;
		insert_back_list(&termination_wait_list, &current_thread->node); 
		restore_cpu_sr(cpu_sr);
		schedule(SCHED_THREAD_REQUEST);
		return RET_NO_ERR;
	}
	return RET_ERR;
}
예제 #12
0
파일: kernel.c 프로젝트: pianyu/mCuRT
/**
 * @brief rountine for idle thread
 * @param data
 */
void idle_thread_func(void *data)
{
	cpu_sr_t cpu_sr;
	thread_struct *pthread;
	list_node_t *pnode;

	while (1) {
		cpu_sr = save_cpu_sr();
		/* check if there is any terminated thread to be recycled */
		if (!is_empty_list(&termination_wait_list)) {
			pnode = delete_front_list(&termination_wait_list);
			pthread = entry_list(pnode, thread_struct, node);
			thread_table[pthread->tid] = NULL;
			total_thread_cnt--;
		}
		restore_cpu_sr(cpu_sr);
		/* always does this */
		thread_yield();
	}
}