/*! * Delete global message queue */ int sys__delete_msg_queue ( void *p ) { /* parameter on thread stack */ msg_q *msgq; /* local variables */ kgmsg_q *gmsgq; msgq = *( (msg_q **) p ); ASSERT_ERRNO_AND_EXIT ( msgq, E_INVALID_HANDLE ); msgq = U2K_GET_ADR ( msgq, k_get_active_process () ); gmsgq = msgq->handle; ASSERT_ERRNO_AND_EXIT ( gmsgq->id == msgq->id, E_INVALID_HANDLE ); k_msgq_clean ( &gmsgq->mq ); k_release_all_threads ( &gmsgq->mq.thrq ); k_free_unique_id ( gmsgq->id ); kfree ( gmsgq ); msgq->id = 0; msgq->handle = NULL; EXIT ( SUCCESS ); }
/*! * End current thread (exit from it) * \param status Exit status number */ int sys__thread_exit ( void *p ) { int status; status = *( (int *) p ); active_thread->state = THR_STATE_PASSIVE; active_thread->ref_cnt--; active_thread->exit_status = status; #ifdef MESSAGES k_msgq_clean ( &active_thread->msg.msgq ); #endif /* release thread stack */ if ( active_thread->stack ) kfree ( active_thread->stack ); k_delete_thread_private_storage ( active_thread, active_thread->private_storage ); if ( !active_thread->ref_cnt ) { k_remove_thread_descriptor ( active_thread ); active_thread = NULL; } else { k_release_all_threads ( &active_thread->join_queue ); } k_schedule_threads (); return 0; }
/*! * Delete alarm * \param param Alarm * \returns status (0 for success) */ int k_alarm_remove ( void *id ) { kalarm_t *kalarm; int reschedule = 0; kalarm = id; ASSERT ( kalarm && kalarm->magic == ALARM_MAGIC ); /* remove from active alarms (if it was there) */ if ( kalarm->active ) list_remove ( &kalarms, FIRST, &kalarm->list ); #ifdef DEBUG kalarm->magic = 0; #endif SET_ERRNO ( SUCCESS ); /* release all waiting threads, if any */ reschedule = k_release_all_threads ( &kalarm->queue ); kfree ( kalarm ); reschedule += k_schedule_alarms (); if ( reschedule ) k_schedule_threads (); RETURN ( SUCCESS ); }
/*! * End current thread (exit from it) * \param status Exit status number */ int sys__thread_exit ( void *p ) { int status; status = *( (int *) p ); active_thread->state = THR_STATE_PASSIVE; active_thread->ref_cnt--; active_thread->exit_status = status; active_thread->proc->thr_count--; #ifdef MESSAGES k_msgq_clean ( &active_thread->msg.msgq ); #endif /* release thread stack */ if ( active_thread->stack ) { if ( active_thread->proc->m.start ) /* user level thread */ ffs_free ( active_thread->proc->stack_pool, active_thread->stack ); else /* kernel level thread */ kfree ( active_thread->stack ); } k_delete_thread_private_storage ( active_thread, active_thread->private_storage ); if ( active_thread->proc->thr_count == 0 && active_thread->proc->pi ) { /* last (non-kernel) thread - remove process */ ASSERT ( list_remove ( &procs, FIRST, &active_thread->proc->all ) ); active_thread->proc->prog->started = FALSE; kfree ( active_thread->proc ); } if ( !active_thread->ref_cnt ) { k_remove_thread_descriptor ( active_thread ); active_thread = NULL; } else { k_release_all_threads ( &active_thread->join_queue ); } k_schedule_threads (); return 0; }
/*! * Destroy monitor (and unblock all threads blocked on it) */ int sys__monitor_queue_destroy ( monitor_q *queue ) { kmonitor_q *kqueue; ASSERT_ERRNO_AND_EXIT ( queue && queue->ptr, E_INVALID_HANDLE ); disable_interrupts (); kqueue = queue->ptr; if ( k_release_all_threads ( &kqueue->queue ) ) k_schedule_threads (); kfree ( kqueue ); queue->ptr = NULL; enable_interrupts (); EXIT ( SUCCESS ); }
/*! * Destroy monitor (and unblock all threads blocked on it) */ int sys__monitor_destroy ( monitor_t *monitor ) { kmonitor_t *kmonitor; ASSERT_ERRNO_AND_EXIT ( monitor && monitor->ptr, E_INVALID_HANDLE ); disable_interrupts (); kmonitor = monitor->ptr; if ( k_release_all_threads ( &kmonitor->queue ) ) k_schedule_threads (); kfree ( kmonitor ); monitor->ptr = NULL; enable_interrupts (); EXIT ( SUCCESS ); }
/*! * Delete global message queue */ int sys__delete_msg_queue ( msg_q *msgq ) { kgmsg_q *gmsgq; ASSERT_ERRNO_AND_EXIT ( msgq, E_INVALID_HANDLE ); gmsgq = msgq->handle; ASSERT_ERRNO_AND_EXIT ( gmsgq->id == msgq->id, E_INVALID_HANDLE ); k_msgq_clean ( &gmsgq->mq ); k_release_all_threads ( &gmsgq->mq.thrq ); k_free_unique_id ( gmsgq->id ); kfree ( gmsgq ); msgq->id = 0; msgq->handle = NULL; EXIT ( SUCCESS ); }
/*! * Iterate through active alarms and activate newly expired ones */ static int k_schedule_alarms () { kalarm_t *first; time_t time, ref_time; int resched_thr = 0; kprocess_t *proc; arch_get_time ( &time ); ref_time = time; time_add ( &ref_time, &threshold ); /* should any alarm be activated? */ first = list_get ( &kalarms, FIRST ); while ( first != NULL ) { if ( time_cmp ( &first->alarm.exp_time, &ref_time ) <= 0 ) { /* 'activate' alarm */ /* but first remove alarm from list */ first = list_remove ( &kalarms, FIRST, NULL ); if ( first->alarm.flags & ALARM_PERIODIC ) { /* calculate next activation time */ time_add ( &first->alarm.exp_time, &first->alarm.period ); /* put back into list */ list_sort_add ( &kalarms, first, &first->list, alarm_cmp ); } else { first->active = 0; } if ( first->alarm.action ) { /* call directly: first->alarm.action ( first->alarm.param ); or create new thread for that job: */ if ( first->thread ) { /* alarm scheduled by thread */ proc = k_get_thread_process ( first->thread ); k_create_thread ( first->alarm.action, first->alarm.param, proc->pi->exit, k_get_thread_prio ( first->thread ) + 1, NULL, 0, 1, proc ); resched_thr++; } else { /* alarm scheduled by kernel */ first->alarm.action ( first->alarm.param ); } } resched_thr += k_release_all_threads ( &first->queue ); first = list_get ( &kalarms, FIRST ); } else { break; } } first = list_get ( &kalarms, FIRST ); if ( first ) { ref_time = first->alarm.exp_time; time_sub ( &ref_time, &time ); arch_timer_set ( &ref_time, k_timer_interrupt ); } return resched_thr; }