Ejemplo n.º 1
0
/**
 * Stop a thread inside a partition.
 * The \a tid argument is relative to the partition, meaning
 * that it corresponds to a number which bounds are
 * 0 .. number of tasks inside the partition.
 */
pok_ret_t pok_partition_stop_thread (const uint32_t tid)
{
	if (POK_SCHED_CURRENT_THREAD != POK_CURRENT_PARTITION.thread_error)
	{
		return POK_ERRNO_THREAD;
	}

	/*
	 * We check which thread try to call this function. Only the error handling
	 * thread can stop other threads.
	 */
	pok_sched_stop_thread (tid + POK_CURRENT_PARTITION.thread_index_low);
	return (POK_ERRNO_OK);
}
Ejemplo n.º 2
0
pok_ret_t pok_partition_set_mode (const uint8_t pid, const pok_partition_mode_t mode)
{
	pok_ret_t ret = POK_ERRNO_OK;
	uint32_t thread_id;
  uint32_t indexLow, indexHigh;

	switch (mode)
	{
		case POK_PARTITION_MODE_NORMAL:
#ifdef POK_NEEDS_DEBUG
   printf ("SET_PARTITON_MODE : partition[%d] MODE = NORMAL  \n", pid );
#endif

			indexLow  = pok_partitions[pid].thread_index_low;
			indexHigh = pok_partitions[pid].thread_index_high;
			// Update the thread states pok_threads in indexLow - indexHigh (excluded)
			for (thread_id = indexLow ; thread_id < indexHigh ; thread_id++)
			{
 #ifdef POK_NEEDS_SCHED_O1_SPLIT
				/* idle thread is always ready in the periodic threads queue */
				pok_partitions[pid].runnables |= (1 << (IDLE_THREAD - pok_partitions[pid].thread_index_low));  
 #endif
				// Check thread is not idle, kernel or (partition main) current thread and each thread belongs to the current partition
				if ((thread_id != IDLE_THREAD) && (thread_id != KERNEL_THREAD) && (thread_id != POK_CURRENT_PARTITION.current_thread)
					&& !pok_thread_is_suspended(pok_threads[thread_id])
					&& pok_threads[thread_id].state == POK_STATE_WAITING) { // the thread has been started

 #ifdef POK_NEEDS_SCHED_O1_SPLIT
					/* if the thread is a successor set its bit in the successor bitmask and 
	 				 * reset its bit in the executed_predecessors bitmask
	 				 */
					if ( ((bool_t[])POK_CONFIG_SUCCESSOR_THREADS)[pok_threads[thread_id].id] == TRUE)
					{
						pok_partitions[pid].successors |= (1 << (pok_threads[thread_id].pos - pok_partitions[pid].thread_index_low));
						pok_partitions[pid].executed_predecessors &= 
									~(1 << (pok_threads[thread_id].pos - pok_partitions[pid].thread_index_low));
					}
					/* if the thread is a predecessor set the bitmask corresponding to its successor in the successors_bitmasks */
					if (((bool_t[])POK_CONFIG_PREDECESSOR_THREADS)[pok_threads[thread_id].id] == TRUE)
					{
						int successor_id = ((int[])POK_CONFIG_SUCCESSORS_ID)[pok_threads[thread_id].id] + pok_partitions[pid].thread_index_low;
						successors_bitmasks[pok_threads[thread_id].id] =
									(1 << (pok_thread_ids_to_pos_map[successor_id] - pok_partitions[pid].thread_index_low));
					}
 #endif /* end ifdef POK_NEEDS_SCHED_O1_SPLIT */

					if (pok_thread_aperiodic(pok_threads[thread_id])){
 #ifdef POK_NEEDS_SCHED_O1
  #ifdef POK_NEEDS_SCHED_O1_SPLIT
						/* set the thread bit in the sporadic_mask bitmask */
						pok_partitions[pid].sporadic_bitmask |= (1 << (pok_threads[thread_id].pos - pok_partitions[pid].thread_index_low));
  #endif
						if(pok_threads[thread_id].timeout != NULL)
							// initiate a time counter with duration DELAY_TIME;
							pok_sched_set_asynch_event(thread_id,
										pok_threads[thread_id].timeout->timer,
										POK_EVENT_DELAYED_START);						
						else
						{
  #ifdef POK_NEEDS_SCHED_O1_SPLIT
							/* insert the thread bitmask in the ready (FIFO) queue;
							 * this because at the beginning all sporadic threads are ready */
							pok_sched_insert_sporadic_in_queue(1 << (pok_threads[thread_id].pos - pok_partitions[pid].thread_index_low));
  #else /* POK_NEEDS_SCHED_O1_SPLIT is not defined */
							// set to READY all previously started (not delayed) aperiodic processes (unless the process was suspended);
							pok_partitions[pid].runnables |= (1 << (pok_threads[thread_id].pos -
												pok_partitions[pok_threads[thread_id].partition].thread_index_low));
  #endif /* end ifdef POK_NEEDS_SCHED_O1_SPLIT */
 #endif /* end ifdef POK_NEEDS_SCHED_O1 */
							pok_threads[thread_id].state = POK_STATE_RUNNABLE;
 #ifdef POK_NEEDS_SCHED_FPPS
							insert_in_queue(POK_SCHED_CURRENT_PARTITION,&pok_threads[thread_id]);
 #endif
 
 #ifdef POK_NEEDS_SCHED_O1
						}
 #endif
					}else{
						// periodic thread
						// set first release points of all previously started (not delayed) periodic processes to 
						// their next partition period;
						// The partition period is unused
						// check if  the next activation is set to the beginning of the next time slot of the partition
						pok_threads[thread_id].next_activation = pok_partitions[pok_threads[thread_id].partition].activation 
								+ get_partition_period(pok_threads[thread_id].partition);
 #ifdef POK_NEEDS_SCHED_O1

						if(pok_threads[thread_id].timeout != NULL)
						{
							pok_threads[thread_id].next_activation += pok_threads[thread_id].timeout->timer;
							pok_sched_set_asynch_event(thread_id,pok_threads[thread_id].next_activation,POK_EVENT_DELAYED_START);
						}
						else
						{
 #endif
							pok_threads[thread_id].state = POK_STATE_WAIT_NEXT_ACTIVATION;
 #ifdef POK_NEEDS_SCHED_O1
							uint32_t the_mask = (1 << (pok_threads[thread_id].pos - pok_partitions[pok_threads[thread_id].partition].thread_index_low));

							uint32_t time, limit, period;
							limit = ((uint32_t)pok_partitions[pok_threads[thread_id].partition].activation) + POK_CONFIG_SCHEDULING_MAJOR_FRAME;
							period = get_partition_period(pok_threads[thread_id].partition);
							for (time =pok_threads[thread_id].next_activation; time <= limit; time += period)
							{
								int position = time % POK_CONFIG_SCHEDULING_MAJOR_FRAME;
								masks[position][POK_STATE_RUNNABLE] |= the_mask;
  #ifdef POK_NEEDS_DEBUG_O1
								printf ("Thread %d will be next activated at %d (= %d + %d * k)\n",
									thread_id, time,
									(int)pok_partitions[pok_threads[thread_id].partition].activation,
									period);
								printf("Adding to mask %d.. %u\n",position,the_mask);
  #endif
							}
						}
 #endif
					}
					// calculate the deadline time of all no dormant processe in the partition
					if (pok_threads[thread_id].state != POK_STATE_STOPPED){
						pok_threads[thread_id].end_time = pok_threads[thread_id].next_activation + pok_threads[thread_id].time_capacity;
					}
				}
			}// end for
	
			// set the partition lock level to 0
			pok_partitions[pid].lock_level = 0;

			// setting the partition mode		
			pok_partitions[pid].mode = mode;

			// stop the calling thread 
			pok_sched_stop_thread(pok_partitions[pid].thread_main);

			// activate the process scheduling
#ifdef POK_NEEDS_SCHED_O1
			pok_sched_end_period();
#else
			pok_sched();
#endif
		
		break;

		default:
			return POK_ERRNO_PARTITION_MODE;
			break;
	} // case

	return ret;
}
Ejemplo n.º 3
0
/**
 * Change the current mode of the partition. Possible mode
 * are describe in core/partition.h. Returns
 * POK_ERRNO_PARTITION_MODE when requested mode is invalid.
 * Else, returns POK_ERRNO_OK
 */
pok_ret_t pok_partition_set_mode (const uint8_t pid, const pok_partition_mode_t mode)
{
    switch (mode)
    {
    case POK_PARTITION_MODE_NORMAL:
        /*
         * We first check that a partition that wants to go
         * to the NORMAL mode is currently in the INIT mode
         */

        if (pok_partitions[pid].mode == POK_PARTITION_MODE_IDLE)
        {
            return POK_ERRNO_PARTITION_MODE;
        }

        if (POK_SCHED_CURRENT_THREAD != POK_CURRENT_PARTITION.thread_main)
        {
            return POK_ERRNO_PARTITION_MODE;
        }

        pok_partitions[pid].mode = mode;  /* Here, we change the mode */

        pok_thread_t* thread;
        unsigned int i;
        for (i = 0; i < pok_partitions[pid].nthreads; i++)
        {
            thread = &(pok_threads[POK_CURRENT_PARTITION.thread_index_low + i]);
            if ((long long)thread->period == -1) {//-1 <==> ARINC INFINITE_TIME_VALUE
                if(thread->state == POK_STATE_DELAYED_START) { // delayed start, the delay is in the wakeup time
                    if(!thread->wakeup_time) {
                        thread->state = POK_STATE_RUNNABLE;
                    } else {
                        thread->state = POK_STATE_WAITING;
                    }
                    thread->wakeup_time += POK_GETTICK();
                    thread->end_time =  thread->wakeup_time + thread->time_capacity;
                }
            } else {
                if(thread->state == POK_STATE_DELAYED_START) { // delayed start, the delay is in the wakeup time
                    thread->next_activation = thread->wakeup_time + POK_CONFIG_SCHEDULING_MAJOR_FRAME + POK_CURRENT_PARTITION.activation;
                    thread->end_time =  thread->next_activation + thread->time_capacity;
                    thread->state = POK_STATE_WAIT_NEXT_ACTIVATION;
                }
            }
        }
        pok_sched_stop_thread (pok_partitions[pid].thread_main);
        /* We stop the thread that call this change. All the time,
         * the thread that init this request is the init thread.
         * When it calls this function, the partition is ready and
         * this thread does not need no longer to be executed
         */

        pok_sched ();
        /*
         * Reschedule, baby, reschedule !
         * In fact, the init thread is stopped, we need to execute
         * the other threads.
         */
        break;

#ifdef POK_NEEDS_ERROR_HANDLING
    case POK_PARTITION_MODE_STOPPED:

        /*
         * Only the error thread can stop the partition
         */
        if ((POK_CURRENT_PARTITION.thread_error == 0 ) ||
                (POK_SCHED_CURRENT_THREAD != POK_CURRENT_PARTITION.thread_error))
        {
            return POK_ERRNO_PARTITION_MODE;
        }

        pok_partitions[pid].mode = mode;  /* Here, we change the mode */
        pok_sched ();
        break;

    case POK_PARTITION_MODE_INIT_WARM:
    case POK_PARTITION_MODE_INIT_COLD:
        if (pok_partitions[pid].mode == POK_PARTITION_MODE_INIT_COLD && mode == POK_PARTITION_MODE_INIT_WARM)
        {
            return POK_ERRNO_PARTITION_MODE;
        }

        /*
         * Check that only the error thread can restart the partition
         */
        if ((POK_CURRENT_PARTITION.thread_error == 0 ) ||
                (POK_SCHED_CURRENT_THREAD != POK_CURRENT_PARTITION.thread_error))
        {
            return POK_ERRNO_PARTITION_MODE;
        }

        /*
         * The partition fallback in the INIT_WARM mode when it
         * was in the NORMAL mode. So, we check the previous mode
         */

        pok_partitions[pid].mode = mode;  /* Here, we change the mode */

        pok_partition_reinit (pid);

        pok_sched ();

        break;
#endif

    default:
        return POK_ERRNO_PARTITION_MODE;
        break;
    }
    return POK_ERRNO_OK;
}