Beispiel #1
0
/*!
 * Unlock mutex object
 * \param mutex Mutex descriptor (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__pthread_mutex_unlock ( pthread_mutex_t *mutex )
{
	kpthread_mutex_t *kmutex;
	kobject_t *kobj;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( mutex, EINVAL );

	kobj = mutex->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj->list ),
				EINVAL );
	kmutex = kobj->kobject;
	ASSERT_ERRNO_AND_EXIT ( kmutex && kmutex->id == mutex->id, EINVAL );

	if ( kmutex->owner != kthread_get_active() )
	{
		SET_ERRNO ( EPERM );
		return EXIT_FAILURE;
	}

	SET_ERRNO ( EXIT_SUCCESS );

	kmutex->owner = kthreadq_get ( &kmutex->queue );
	if ( kmutex->owner )
	{
		kthreadq_release ( &kmutex->queue );
		kthreads_schedule ();
	}

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #2
0
/*!
 * Change scheduling parameters
 * \param thread User level thread descriptor
 * \param policy Thread scheduling policy
 * \param param Additional scheduling parameters (when policy != SCHED_FIFO)
 * \return 0
 */
int sys__pthread_setschedparam ( pthread_t *thread, int policy,
				 sched_param_t *param )
{
	kthread_t *kthread;
	int retval;

	SYS_ENTRY();

	kthread = thread->ptr;
	ASSERT_ERRNO_AND_EXIT ( kthread, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( kthread_get_id (kthread) == thread->id, ESRCH );
	ASSERT_ERRNO_AND_EXIT ( kthread_is_alive (kthread), ESRCH );

	ASSERT_ERRNO_AND_EXIT ( policy == SCHED_FIFO, ENOTSUP );

	if ( param )
	{
		ASSERT_ERRNO_AND_EXIT (
			param->sched_priority >= THREAD_MIN_PRIO &&
			param->sched_priority <= THREAD_MAX_PRIO, EINVAL );
	}

	retval = kthread_setschedparam ( kthread, policy, param );
	if ( retval == EXIT_SUCCESS )
		SYS_EXIT ( EXIT_SUCCESS, retval );
	else
		SYS_EXIT ( retval, EXIT_FAILURE );
}
Beispiel #3
0
/*!
 * Lock mutex object
 * \param mutex Mutex descriptor (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__pthread_mutex_lock ( pthread_mutex_t *mutex )
{
	kpthread_mutex_t *kmutex;
	kobject_t *kobj;
	int retval = EXIT_SUCCESS;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( mutex, EINVAL );

	kobj = mutex->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj->list ),
				EINVAL );
	kmutex = kobj->kobject;
	ASSERT_ERRNO_AND_EXIT ( kmutex && kmutex->id == mutex->id, EINVAL );

	retval = mutex_lock ( kmutex, kthread_get_active () );

	if ( retval == 1 )
		kthreads_schedule ();

	 /* errno is already set */
	if ( retval != -1 )
		SYS_RETURN ( EXIT_SUCCESS );
	else
		SYS_RETURN ( EXIT_FAILURE );
}
Beispiel #4
0
/*!
 * Initialize mutex object
 * \param mutex Mutex descriptor (user level descriptor)
 * \param mutexattr Mutex parameters
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__pthread_mutex_init ( pthread_mutex_t *mutex,
			      pthread_mutexattr_t *mutexattr )
{
	kpthread_mutex_t *kmutex;
	kobject_t *kobj;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( mutex, EINVAL );

	kobj = kmalloc_kobject ( sizeof (kpthread_mutex_t) );
	ASSERT_ERRNO_AND_EXIT ( kobj, ENOMEM );
	kmutex = kobj->kobject;

	kmutex->id = k_new_id ();
	kmutex->owner = NULL;
	kmutex->flags = 0;
	kmutex->ref_cnt = 1;
	kthreadq_init ( &kmutex->queue );

	mutex->ptr = kobj;
	mutex->id = kmutex->id;

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #5
0
/*!
 * Destroy semaphore object
 * \param sem Semaphore descriptor (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__sem_destroy ( sem_t *sem )
{
	ksem_t *ksem;
	kobject_t *kobj;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( sem, EINVAL );

	kobj = sem->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj->list ),
				EINVAL );
	ksem = kobj->kobject;
	ASSERT_ERRNO_AND_EXIT ( ksem && ksem->id == sem->id, EINVAL );

	ASSERT_ERRNO_AND_EXIT (kthreadq_get (&ksem->queue) == NULL, ENOTEMPTY);

	ksem->ref_cnt--;

	/* additional cleanup here (e.g. if semaphore is shared leave it) */
	if ( ksem->ref_cnt )
		SYS_EXIT ( EBUSY, EXIT_FAILURE );

	kfree_kobject ( kobj );

	sem->ptr = NULL;
	sem->id = 0;

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #6
0
/*!
 * Decrement (lock) semaphore value by 1 (if not 0 when thread is blocked)
 * \param sem Semaphore descriptor (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__sem_wait ( sem_t *sem )
{
	ksem_t *ksem;
	kobject_t *kobj;
	kthread_t *kthread;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( sem, EINVAL );

	kthread = kthread_get_active ();

	kobj = sem->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj->list ),
				EINVAL );
	ksem = kobj->kobject;
	ASSERT_ERRNO_AND_EXIT ( ksem && ksem->id == sem->id, EINVAL );

	kthread_set_errno ( kthread, EXIT_SUCCESS );
	kthread_set_syscall_retval ( kthread, EXIT_SUCCESS );

	if ( ksem->sem_value > 0 )
	{
		ksem->sem_value--;
		ksem->last_lock = kthread;
	}
	else {
		kthread_enqueue ( kthread, &ksem->queue );
		kthreads_schedule ();
	}

	SYS_EXIT ( kthread_get_errno(NULL), kthread_get_syscall_retval(NULL) );
}
Beispiel #7
0
/*!
 * Destroy conditional variable object
 * \param cond conditional variable descriptor (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__pthread_cond_destroy ( pthread_cond_t *cond )
{
	kpthread_cond_t *kcond;
	kobject_t *kobj;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( cond, EINVAL );

	kobj = cond->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj->list ),
				EINVAL );
	kcond = kobj->kobject;
	ASSERT_ERRNO_AND_EXIT ( kcond && kcond->id == cond->id, EINVAL );

	kcond->ref_cnt--;

	/* additional cleanup here (e.g. if cond.var. is shared leave it) */
	if ( kcond->ref_cnt )
		SYS_EXIT ( EBUSY, EXIT_FAILURE );

	kfree_kobject ( kobj );

	cond->ptr = NULL;
	cond->id = 0;

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #8
0
/*!
 * Initialize semaphore object
 * \param sem Semaphore descriptor (user level descriptor)
 * \param pshared Shall semaphore object be shared between processes
 * \param value Initial semaphore value
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__sem_init ( sem_t *sem, int pshared, int value )
{
	ksem_t *ksem;
	kobject_t *kobj;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( sem, EINVAL );

	kobj = kmalloc_kobject ( sizeof (ksem_t) );
	ASSERT_ERRNO_AND_EXIT ( kobj, ENOMEM );
	ksem = kobj->kobject;

	ksem->id = k_new_id ();
	ksem->sem_value = value;
	ksem->last_lock = NULL;
	ksem->flags = 0;
	ksem->ref_cnt = 1;
	kthreadq_init ( &ksem->queue );

	if ( pshared )
		ksem->flags |= PTHREAD_PROCESS_SHARED;

	sem->ptr = kobj;
	sem->id = ksem->id;

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #9
0
/*! Set and get current thread error status */
int sys__set_errno ( int errno )
{
	SYS_ENTRY();

	kthread_set_errno ( NULL, errno );

	SYS_RETURN ( EXIT_SUCCESS );
}
Beispiel #10
0
/*!
 * End current thread (exit from it)
 * \param retval Pointer to exit status
 */
int sys__pthread_exit ( void *retval )
{
	SYS_ENTRY();

	kthread_exit ( kthread_get_active(), retval );

	ASSERT ( FALSE ); /* should not return here! */

	SYS_EXIT ( EXIT_FAILURE, EXIT_FAILURE );
}
Beispiel #11
0
/*! Return calling thread descriptor
 * \param thread Thread descriptor (user level descriptor)
 * \return 0
 */
int sys__pthread_self ( pthread_t *thread )
{
	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( thread, ESRCH );

	thread->ptr = kthread_get_active ();
	thread->id = kthread_get_id (NULL);

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #12
0
int sys__get_errno_ptr ( int **errno )
{
	SYS_ENTRY();

	if ( errno )
	{
		*errno = kthread_get_errno_ptr (NULL);
		SYS_RETURN ( EXIT_SUCCESS );
	}
	else {
		SYS_RETURN ( EXIT_FAILURE );
	}
}
Beispiel #13
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 );
}
Beispiel #14
0
/*!
 * Set current time
 * \param clockid Clock to use
 * \param time Time to set
 * \return status
 */
int sys__clock_settime ( clockid_t clockid, timespec_t *time )
{
	int retval;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT (
		time && (clockid==CLOCK_REALTIME || clockid==CLOCK_MONOTONIC),
		EINVAL
	);

	retval = kclock_settime ( clockid, time );

	SYS_EXIT ( retval, retval );
}
Beispiel #15
0
static int cond_release ( pthread_cond_t *cond, int release_all )
{
	kpthread_cond_t *kcond;
	kpthread_mutex_t *kmutex;
	kobject_t *kobj_cond, *kobj_mutex;
	kthread_t *kthread;
	int retval = 0;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( cond, EINVAL );

	kobj_cond = cond->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj_cond, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj_cond->list ),
				EINVAL );
	kcond = kobj_cond->kobject;
	ASSERT_ERRNO_AND_EXIT ( kcond && kcond->id == cond->id, EINVAL );

	kthread_set_errno ( kthread_get_active (), EXIT_SUCCESS );

	if ( (kthread = kthreadq_remove ( &kcond->queue, NULL )) )
	{
		kobj_mutex = kthread_get_private_param ( kthread );
		kmutex = kobj_mutex->kobject;

		retval = mutex_lock ( kmutex, kthread );
		if ( retval == 0 )
			kthread_move_to_ready ( kthread, LAST );

		/* process other threads in queue */
		while ( release_all &&
			(kthread = kthreadq_remove ( &kcond->queue, NULL )) )
		{
			kthread_set_errno ( kthread, EXIT_SUCCESS );

			kobj_mutex = kthread_get_private_param ( kthread );
			kmutex = kobj_mutex->kobject;

			kthread_enqueue ( kthread, &kmutex->queue );
		}
	}

	if ( retval > -1 )
		kthreads_schedule ();

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #16
0
/*!
 * Create new thread (params on user stack!)
 * \param thread User level thread descriptor
 * \param attr Thread attributes
 * \param start_routine Starting function for new thread
 * \param arg Parameter sent to starting function
 * (parameters are on calling thread stack)
 */
int sys__pthread_create ( pthread_t *thread, pthread_attr_t *attr,
			  void *(*start_routine) (void *), void *arg )
{
	kthread_t *kthread;
	uint flags = 0;
	int sched_policy = SCHED_FIFO;
	int sched_priority = THREAD_DEF_PRIO;
	void *stackaddr = NULL;
	size_t stacksize = 0;

	SYS_ENTRY();

	if ( attr )
	{
		flags = attr->flags;
		sched_policy = attr->sched_policy;
		sched_priority = attr->sched_params.sched_priority;
		stackaddr = attr->stackaddr;
		stacksize = attr->stacksize;

		ASSERT_ERRNO_AND_EXIT ( sched_policy == SCHED_FIFO,
					ENOTSUP );
		ASSERT_ERRNO_AND_EXIT (
			sched_priority >= THREAD_MIN_PRIO &&
			sched_priority <= THREAD_MAX_PRIO,
			ENOMEM
		);

		/* if ( flags & SOMETHING ) change attributes ... */
	}

	kthread = kthread_create ( start_routine, arg, flags,
				   sched_policy, sched_priority,
				   stackaddr, stacksize );

	ASSERT_ERRNO_AND_EXIT ( kthread, ENOMEM );

	if ( thread )
	{
		thread->ptr = kthread;
		thread->id = kthread_get_id (kthread);
	}

	kthreads_schedule ();

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #17
0
/*! printf (or return) system information (and details) */
int sys__sysinfo ( char *buffer, size_t buf_size )
{
	/* only basic info defined in kernel/startup.c */
	extern char system_info[];

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( buffer, EINVAL );

	if ( strlen ( system_info ) > buf_size )
		SYS_EXIT ( ENOMEM, EXIT_FAILURE );

	strcpy ( buffer, system_info );

	k_memory_info ();

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #18
0
/*!
 * Wait on conditional variable
 * \param cond conditional variable descriptor (user level descriptor)
 * \param mutex Mutex descriptor (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__pthread_cond_wait ( pthread_cond_t *cond, pthread_mutex_t *mutex )
{
	kpthread_cond_t *kcond;
	kpthread_mutex_t *kmutex;
	kobject_t *kobj_cond, *kobj_mutex;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( cond && mutex, EINVAL );

	kobj_cond = cond->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj_cond, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj_cond->list ),
				EINVAL );
	kcond = kobj_cond->kobject;
	ASSERT_ERRNO_AND_EXIT ( kcond && kcond->id == cond->id, EINVAL );

	kobj_mutex = mutex->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj_mutex, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj_mutex->list),
				EINVAL );
	kmutex = kobj_mutex->kobject;
	ASSERT_ERRNO_AND_EXIT ( kmutex && kmutex->id == mutex->id, EINVAL );

	ASSERT_ERRNO_AND_EXIT ( kmutex->owner == kthread_get_active(), EPERM );

	kthread_set_errno ( NULL, EXIT_SUCCESS );
	kthread_set_syscall_retval ( NULL, EXIT_SUCCESS );

	/* move thread in conditional variable queue */
	kthread_enqueue ( NULL, &kcond->queue );

	/* save reference to mutex object */
	kthread_set_private_param ( NULL, kobj_mutex );

	/* release mutex */
	kmutex->owner = kthreadq_get ( &kmutex->queue );
	if ( kmutex->owner )
		kthreadq_release ( &kmutex->queue );

	kthreads_schedule ();

	SYS_EXIT ( kthread_get_errno(NULL), kthread_get_syscall_retval(NULL) );
}
Beispiel #19
0
/*! Create global message queue */
int sys__create_msg_queue ( msg_q *msgq, uint min_prio )
{
    kgmsg_q *gmsgq;

    SYS_ENTRY();

    ASSERT_ERRNO_AND_SYS_EXIT ( msgq, E_INVALID_HANDLE );

    gmsgq = kmalloc ( sizeof ( kgmsg_q ) );
    ASSERT_ERRNO_AND_SYS_EXIT ( gmsgq, E_NO_MEMORY );

    list_init ( &gmsgq->mq.msgs ); /* list for messages */
    k_threadq_init ( &gmsgq->mq.thrq ); /* list for blocked threads */

    gmsgq->mq.min_prio = min_prio;
    msgq->id = gmsgq->id = k_new_unique_id ();
    msgq->handle = gmsgq;

    list_append ( &kmsg_qs, gmsgq, &gmsgq->all ); /* all msg.q. list */

    SYS_EXIT ( SUCCESS );
}
Beispiel #20
0
/*!
 * Increment (lock) semaphore value by 1 (or unblock one thread that is blocked)
 * \param sem Semaphore descriptor (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__sem_post ( sem_t *sem )
{
	ksem_t *ksem;
	kobject_t *kobj;
	kthread_t *kthread, *released;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( sem, EINVAL );

	kthread = kthread_get_active ();

	kobj = sem->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj->list ),
				EINVAL );
	ksem = kobj->kobject;
	ASSERT_ERRNO_AND_EXIT ( ksem && ksem->id == sem->id, EINVAL );

	kthread_set_errno ( kthread, EXIT_SUCCESS );
	kthread_set_syscall_retval ( kthread, EXIT_SUCCESS );

	released = kthreadq_get ( &ksem->queue ); /* first to release */

	if ( !released || ksem->sem_value < 0 )
	{
		/* if initial semaphore value (set by sem_init) was negative,
		 * semaphore will not release threads until its value
		 * reaches zero (small extension of POSIX semaphore) */
		ksem->sem_value++;
	}
	else {
		kthreadq_release ( &ksem->queue );
		kthreads_schedule ();
	}

	SYS_EXIT ( kthread_get_errno(NULL), kthread_get_syscall_retval(NULL) );
}
Beispiel #21
0
/*!
 * Initialize conditional variable object
 * \param cond conditional variable descriptor (user level descriptor)
 * \param condattr conditional variable descriptor (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__pthread_cond_init (pthread_cond_t *cond, pthread_condattr_t *condattr)
{
	kpthread_cond_t *kcond;
	kobject_t *kobj;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( cond, EINVAL );

	kobj = kmalloc_kobject ( sizeof (kpthread_cond_t) );
	ASSERT_ERRNO_AND_EXIT ( kobj, ENOMEM );
	kcond = kobj->kobject;

	kcond->id = k_new_id ();
	kcond->flags = 0;
	kcond->ref_cnt = 1;
	kthreadq_init ( &kcond->queue );

	cond->ptr = kobj;
	cond->id = kcond->id;

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #22
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 );
}
Beispiel #23
0
/*!
 * Wait for thread termination
 * \param thread Thread descriptor (user level descriptor)
 * \param retval Where to store exit status of joined thread
 * \return 0 if thread already gone; -1 if not finished and 'wait' not set;
 *         'thread exit status' otherwise
 */
int sys__pthread_join ( pthread_t *thread, void **retval )
{
	kthread_t *kthread;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( thread, ESRCH );

	kthread = thread->ptr;

	if ( kthread_get_id (kthread) != thread->id )
	{
		/* at 'kthread' is now something else */
		SYS_EXIT ( ESRCH, EXIT_FAILURE );
	}
	else if ( kthread_is_alive (kthread) )
	{
		kthread_set_errno ( NULL, EXIT_SUCCESS );
		kthread_set_syscall_retval ( NULL, EXIT_SUCCESS );

		kthread_set_private_param ( kthread_get_active(), retval );

		kthread_wait_thread ( NULL, kthread );

		kthreads_schedule ();

		SYS_EXIT ( kthread_get_errno(NULL),
			   kthread_get_syscall_retval(NULL) );
	}
	else {
		/* target thread is passive, collect status and free descr. */
		kthread_collect_status ( kthread, retval );

		SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
	}
}
Beispiel #24
0
/*!
 * Destroy mutex object
 * \param mutex Mutex descriptor (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__pthread_mutex_destroy ( pthread_mutex_t *mutex )
{
	kpthread_mutex_t *kmutex;
	kobject_t *kobj;

	SYS_ENTRY();

	ASSERT_ERRNO_AND_EXIT ( mutex, EINVAL );

	kobj = mutex->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj->list ),
				EINVAL );

	kmutex = kobj->kobject;
	ASSERT_ERRNO_AND_EXIT ( kmutex && kmutex->id == mutex->id, EINVAL );

	ASSERT_ERRNO_AND_EXIT (
		kmutex->owner == NULL /* mutex locked! */ &&
		kthreadq_get ( &kmutex->queue ) == NULL,
		ENOTEMPTY
	);

	kmutex->ref_cnt--;

	/* additional cleanup here (e.g. if mutex is shared leave it) */
	if ( kmutex->ref_cnt )
		SYS_EXIT ( EBUSY, EXIT_FAILURE );

	kfree_kobject ( kobj );

	mutex->ptr = NULL;
	mutex->id = 0;

	SYS_EXIT ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #25
0
/*! Delete global message queue */
int sys__delete_msg_queue ( msg_q *msgq )
{
    kgmsg_q *gmsgq;

    SYS_ENTRY();

    ASSERT_ERRNO_AND_SYS_EXIT ( msgq, E_INVALID_HANDLE );

    gmsgq = msgq->handle;
    ASSERT_ERRNO_AND_SYS_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;

    SYS_EXIT ( SUCCESS );
}
Beispiel #26
0
int sys__get_errno ()
{
	SYS_ENTRY();
	SYS_RETURN ( kthread_get_errno (NULL) );
}
Beispiel #27
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 );
    }
}
Beispiel #28
0
/*! Send message to queue or signal to thread */
int sys__msg_post ( int dest_type, void *dest, msg_t *msg, uint flags )
{
    thread_t *thr;
    kthread_t *kthr, *new_kthr;
    kthrmsg_qs *thrmsg;
    kgmsg_q *kgmsgq;
    kmsg_q *kmsgq;
    msg_q *msgq;
    kmsg_t *kmsg;
    msg_t *cmsg;

    SYS_ENTRY();

    ASSERT_ERRNO_AND_SYS_EXIT ( dest && msg, E_INVALID_HANDLE );

    if ( dest_type == MSG_THREAD || dest_type == MSG_SIGNAL )
    {
        thr = dest;
        kthr = k_get_kthread ( thr );
        ASSERT_ERRNO_AND_SYS_EXIT ( kthr, E_DONT_EXIST );
        thrmsg = k_get_thrmsg ( kthr );
        kmsgq = &thrmsg->msgq;
    }
    else if ( dest_type == MSG_QUEUE )
    {
        msgq = dest;
        kgmsgq = msgq->handle;
        ASSERT_ERRNO_AND_SYS_EXIT ( kgmsgq && kgmsgq->id == msgq->id,
                                    E_INVALID_HANDLE );
        kmsgq = &kgmsgq->mq;
    }
    else {
        SYS_EXIT ( E_INVALID_TYPE );
    }

    if ( dest_type == MSG_THREAD || dest_type == MSG_QUEUE )
    {
        /* send message to queue */
        if ( kmsgq->min_prio <= msg->type ) /* msg has required prio. */
        {
            kmsg = kmalloc ( sizeof (kmsg_t) + msg->size );
            ASSERT_ERRNO_AND_SYS_EXIT ( kmsg, E_NO_MEMORY );

            kmsg->msg.type = msg->type;
            kmsg->msg.size = msg->size;
            memcpy ( kmsg->msg.data, msg->data, msg->size );

            list_append ( &kmsgq->msgs, kmsg, &kmsg->list );

            /* is thread waiting for message? */
            if ( k_release_thread ( &kmsgq->thrq ) )
                k_schedule_threads ();

            SYS_EXIT ( SUCCESS );
        }
        else { /* ignore message */
            SYS_EXIT ( E_IGNORED );
        }
    }

    /* must be MSG_SIGNAL */
    //promijenjen uvijet
    //ako je signal_handler postavljen, tada šalji signal
    if ( thrmsg->sig_prio <= msg->type && thrmsg->signal_handler[msg->type] != NULL )
    {
        /* create thread that will service this signal */

        cmsg = k_create_thread_private_storage ( kthr,
                sizeof (msg_t) + msg->size );
        cmsg->type = msg->type;
        cmsg->size = msg->size;
        memcpy ( cmsg->data, msg->data, msg->size );

        new_kthr = k_create_thread (
                       //koji handler???
                       thrmsg->signal_handler[msg->type], cmsg, pi.exit,
                       k_get_thread_prio ( kthr ) + 1, NULL, 0, 1
                   );
        ASSERT_ERRNO_AND_SYS_EXIT ( new_kthr, k_get_errno() );

        k_set_thread_private_storage ( new_kthr, cmsg );

        //SET_ERRNO ( SUCCESS );

        k_schedule_threads ();

        SYS_EXIT ( SUCCESS );
    }
    else { /* ignore signal */
        SYS_EXIT ( E_IGNORED );
    }
}