/*!
 * 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 );
}
Exemple #4
0
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 );
}
Exemple #8
0
/*! 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 );
	}
}
Exemple #11
0
/*! 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 );
    }
}