pok_ret_t pok_thread_sleep (uint32_t time) { uint64_t mytime; mytime = time + POK_GETTICK(); pok_sched_lock_current_thread_timed (mytime); pok_sched (); return POK_ERRNO_OK; }
/** * The \a tid argument is relative to partition thread index */ pok_ret_t pok_partition_restart_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_thread_restart (tid + POK_CURRENT_PARTITION.thread_index_low); pok_sched (); return (POK_ERRNO_OK); }
/** * 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) { uint32_t id; if (POK_SCHED_CURRENT_THREAD != POK_CURRENT_PARTITION.thread_error) { return POK_ERRNO_THREAD; } id = tid + POK_CURRENT_PARTITION.thread_index_low; if (POK_CURRENT_PARTITION.thread_index_low > id || POK_CURRENT_PARTITION.thread_index_high < id) { return POK_ERRNO_THREADATTR; } /* * We check which thread try to call this function. Only the error handling * thread can stop other threads. */ pok_sched_stop_thread (id); pok_sched (); return (POK_ERRNO_OK); }
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; }
/** * 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; }
pok_ret_t pok_thread_suspend (void) { pok_sched_stop_self (); pok_sched (); return POK_ERRNO_OK; }
pok_ret_t pok_thread_sleep_until (uint32_t time) { pok_sched_lock_current_thread_timed ((uint64_t)time); pok_sched (); return POK_ERRNO_OK; }