/*! * Unlock monitor (or block trying) */ int sys__monitor_unlock ( monitor_t *monitor ) { kmonitor_t *kmonitor; ASSERT_ERRNO_AND_EXIT ( monitor && monitor->ptr, E_INVALID_HANDLE ); kmonitor = monitor->ptr; ASSERT_ERRNO_AND_EXIT ( kmonitor->owner == k_get_active_thread (), E_NOT_OWNER ); disable_interrupts (); SET_ERRNO ( SUCCESS ); kmonitor->owner = k_threadq_get ( &kmonitor->queue ); if ( !k_release_thread ( &kmonitor->queue ) ) kmonitor->lock = FALSE; else k_schedule_threads (); enable_interrupts (); EXIT ( SUCCESS ); }
/*! * Block thread (on conditional variable) and release monitor */ int sys__monitor_wait ( monitor_t *monitor, monitor_q *queue ) { kmonitor_t *kmonitor; kmonitor_q *kqueue; ASSERT_ERRNO_AND_EXIT ( monitor && monitor->ptr, E_INVALID_HANDLE ); ASSERT_ERRNO_AND_EXIT ( queue && queue->ptr, E_INVALID_HANDLE ); kmonitor = monitor->ptr; kqueue = queue->ptr; ASSERT_ERRNO_AND_EXIT ( kmonitor->owner == k_get_active_thread (), E_NOT_OWNER ); disable_interrupts (); SET_ERRNO ( SUCCESS ); k_set_thread_qdata ( NULL, kmonitor ); k_enqueue_thread ( NULL, &kqueue->queue ); kmonitor->owner = k_threadq_get ( &kmonitor->queue ); if ( !k_release_thread ( &kmonitor->queue ) ) kmonitor->lock = FALSE; k_schedule_threads (); enable_interrupts (); EXIT ( SUCCESS ); }
/*! * Lock monitor (or block trying) */ int sys__monitor_lock ( monitor_t *monitor ) { kmonitor_t *kmonitor; ASSERT_ERRNO_AND_EXIT ( monitor && monitor->ptr, E_INVALID_HANDLE ); disable_interrupts (); kmonitor = monitor->ptr; SET_ERRNO ( SUCCESS ); if ( !kmonitor->lock ) { kmonitor->lock = TRUE; kmonitor->owner = k_get_active_thread (); } else { k_enqueue_thread ( NULL, &kmonitor->queue ); k_schedule_threads (); } enable_interrupts (); EXIT ( SUCCESS ); }
int sys__set_signal_handler (int sig_prio, void *sig_handler) { kthread_t *kthr; kthrmsg_qs *thrmsg; SYS_ENTRY(); kthr = k_get_active_thread(); thrmsg = k_get_thrmsg ( kthr ); thrmsg->signal_handler[sig_prio] = sig_handler; SYS_EXIT( SUCCESS ); }
/*! * Define thread behavior towards messages and signals */ int sys__thread_msg_set (uint min_msg_prio, int min_sig_prio, void *sig_handler) { /* local variables */ kthread_t *kthr; kthrmsg_qs *thrmsg; kthr = k_get_active_thread (); thrmsg = k_get_thrmsg ( kthr ); thrmsg->msgq.min_prio = min_msg_prio; thrmsg->sig_prio = min_sig_prio; thrmsg->signal_handler = sig_handler; EXIT ( SUCCESS ); }
/*! * Process syscalls * (syscall is forwarded from arch interrupt subsystem to k_syscall) */ void k_syscall ( uint irqn ) { int id, retval; void *act_thr, *context, *params; ASSERT ( irqn == SOFTWARE_INTERRUPT ); act_thr = k_get_active_thread (); context = k_get_thread_context ( act_thr ); id = arch_syscall_get_id ( context ); ASSERT ( id >= 0 && id < SYSFUNCS ); params = arch_syscall_get_params ( context ); retval = k_sysfunc[id] ( params ); if ( id != THREAD_EXIT ) arch_syscall_set_retval ( context, retval ); }
/*! * Define thread behavior towards messages and signals */ int sys__thread_msg_set ( void *p ) { /* parameters on thread stack */ uint min_msg_prio; int min_sig_prio; void *sig_handler; /* local variables */ kthread_t *kthr; kthrmsg_qs *thrmsg; min_msg_prio = *( (uint *) p ); p += sizeof (uint); min_sig_prio = *( (int *) p ); p += sizeof (int); sig_handler = *( (void **) p ); kthr = k_get_active_thread (); thrmsg = k_get_thrmsg ( kthr ); thrmsg->msgq.min_prio = min_msg_prio; thrmsg->sig_prio = min_sig_prio; thrmsg->signal_handler = sig_handler; EXIT ( SUCCESS ); }
/*! Define thread behavior towards messages and signals */ int sys__thread_msg_set (uint min_msg_prio, int min_sig_prio) { /* local variables */ kthread_t *kthr; kthrmsg_qs *thrmsg; SYS_ENTRY(); kthr = k_get_active_thread (); thrmsg = k_get_thrmsg ( kthr ); thrmsg->msgq.min_prio = min_msg_prio; thrmsg->sig_prio = min_sig_prio; //dodano int index; for (index = 0; index < HANDLER_NUM; index++) { thrmsg->signal_handler[index] = NULL; } //kraj dodavanja SYS_EXIT ( SUCCESS ); }
/*! * Create new alarm * \param alarm Alarm parameters * \returns status (0 for success), but also in 'param->alarm.id' is pointer to * newly created alarm (handler) */ int k_alarm_new ( void **id, alarm_t *alarm ) { kalarm_t *kalarm; kalarm = kmalloc ( sizeof (kalarm_t) ); ASSERT ( kalarm ); kalarm->alarm = *alarm; /* copy alarm data */ /* param checking is skipped - assuming all is OK */ k_threadq_init ( &kalarm->queue ); #ifdef DEBUG kalarm->magic = ALARM_MAGIC; #endif *id = kalarm; /* return value = handler */ kalarm->thread = k_get_active_thread (); k_alarm_add ( kalarm ); RETURN ( SUCCESS ); }
/*! * Receive message from queue (global or from own thread message queue) */ int sys__msg_recv ( void *p ) { /* parameters on thread stack */ int src_type; /* MSG_QUEUE or MSG_THREAD */ void *src; /* (msg_q *) or (thread_t *) */ msg_t *msg; /* { type, size, data[0..size-1] } */ int type; /* message type (identifier) */ size_t size; /* size of 'data' member */ uint flags; /* local variables */ kthread_t *kthr; kthrmsg_qs *thrmsg; kgmsg_q *kgmsgq; kmsg_q *kmsgq; msg_q *msgq; kmsg_t *kmsg; src_type = *( (int *) p ); p += sizeof (int); src = *( (void **) p ); p += sizeof (void *); msg = *( (msg_t **) p ); p += sizeof (msg_t *); type = *( (int *) p ); p += sizeof (int); size = *( (size_t *) p ); p += sizeof (size_t); flags = *( (uint *) p ); ASSERT_ERRNO_AND_EXIT ( src && msg, E_INVALID_HANDLE ); src = U2K_GET_ADR ( src, k_get_active_process () ); msg = U2K_GET_ADR ( msg, k_get_active_process () ); ASSERT_ERRNO_AND_EXIT ( src_type == MSG_THREAD || src_type == MSG_QUEUE, E_INVALID_TYPE ); if ( src_type == MSG_THREAD ) { kthr = k_get_active_thread (); thrmsg = k_get_thrmsg ( kthr ); kmsgq = &thrmsg->msgq; } else { /* src_type == MSG_QUEUE */ msgq = src; kgmsgq = msgq->handle; ASSERT_ERRNO_AND_EXIT ( kgmsgq && kgmsgq->id == msgq->id, E_INVALID_HANDLE ); kmsgq = &kgmsgq->mq; } /* get first message from queue */ kmsg = list_get ( &kmsgq->msgs, FIRST ); if ( type != 0 ) /* type != 0 => search for first message 'type' */ while ( kmsg && kmsg->msg.type != type ) kmsg = list_get_next ( &kmsg->list ); if ( kmsg ) /* have message */ { if ( size < kmsg->msg.size ) { msg->size = 0; EXIT ( E_TOO_BIG ); } msg->type = kmsg->msg.type; msg->size = kmsg->msg.size; memcpy ( msg->data, kmsg->msg.data, msg->size ); kmsg = list_remove ( &kmsgq->msgs, FIRST, &kmsg->list ); ASSERT ( kmsg ); kfree ( kmsg ); EXIT ( SUCCESS ); } else { /* queue empty! */ if ( !( flags & IPC_WAIT ) ) EXIT ( E_EMPTY ); SET_ERRNO ( E_RETRY ); /* block thread */ k_enqueue_thread ( NULL, &kmsgq->thrq ); k_schedule_threads (); RETURN ( E_RETRY ); } }
/*! Receive message from queue (global or from own thread message queue) */ int sys__msg_recv ( int src_type, void *src, msg_t *msg, int type, size_t size, uint flags ) { kthread_t *kthr; kthrmsg_qs *thrmsg; kgmsg_q *kgmsgq; kmsg_q *kmsgq; msg_q *msgq; kmsg_t *kmsg; SYS_ENTRY(); ASSERT_ERRNO_AND_SYS_EXIT ( src_type == MSG_THREAD || ( src_type == MSG_QUEUE && src ), E_INVALID_TYPE ); ASSERT_ERRNO_AND_SYS_EXIT ( msg && size > 0, E_INVALID_HANDLE ); if ( src_type == MSG_THREAD ) { kthr = k_get_active_thread (); thrmsg = k_get_thrmsg ( kthr ); kmsgq = &thrmsg->msgq; } else { /* src_type == MSG_QUEUE */ msgq = src; kgmsgq = msgq->handle; ASSERT_ERRNO_AND_SYS_EXIT ( kgmsgq && kgmsgq->id == msgq->id, E_INVALID_HANDLE ); kmsgq = &kgmsgq->mq; } /* get first message from queue */ kmsg = list_get ( &kmsgq->msgs, FIRST ); if ( type != 0 ) /* type != 0 => search for first message 'type' */ while ( kmsg && kmsg->msg.type != type ) kmsg = list_get_next ( &kmsg->list ); if ( kmsg ) /* have message */ { if ( size < kmsg->msg.size ) { msg->size = 0; SYS_EXIT ( E_TOO_BIG ); } msg->type = kmsg->msg.type; msg->size = kmsg->msg.size; memcpy ( msg->data, kmsg->msg.data, msg->size ); kmsg = list_remove ( &kmsgq->msgs, FIRST, &kmsg->list ); ASSERT ( kmsg ); kfree ( kmsg ); SYS_EXIT ( SUCCESS ); } else { /* queue empty! */ if ( !( flags & IPC_WAIT ) ) SYS_EXIT ( E_EMPTY ); //SET_ERRNO ( E_RETRY ); /* block thread */ k_enqueue_thread ( NULL, &kmsgq->thrq ); k_schedule_threads (); SYS_EXIT ( E_RETRY ); } }