/*!
 * Create global message queue
 */
int sys__create_msg_queue ( void *p )
{
	/* parameters on thread stack */
	msg_q *msgq;
	uint min_prio;
	/* local variables */
	kgmsg_q *gmsgq;

	msgq = *( (msg_q **) p );	p += sizeof (msg_q *);
	min_prio = *( (uint *) p );

	ASSERT_ERRNO_AND_EXIT ( msgq, E_INVALID_HANDLE );

	msgq = U2K_GET_ADR ( msgq, k_get_active_process () );

	gmsgq = kmalloc ( sizeof ( kgmsg_q ) );
	ASSERT_ERRNO_AND_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 */

	EXIT ( SUCCESS );
}
/*!
 * 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 );
}
Beispiel #3
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 #4
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 #5
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 #6
0
/*!
 * Send signal to thread (from thread)
 * \param pid Thread descriptor (user level descriptor)
 * \param signo Signal number
 * \param sigval Parameter to send with signal
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__sigqueue ( void *p )
{
	pid_t pid;
	int signo;
	sigval_t sigval;

	pthread_t thread, sender;
	kthread_t *kthread;
	siginfo_t sig;

	pid =    *( (pid_t *) p );	p += sizeof (pid_t);
	signo =  *( (int *) p );	p += sizeof (int);
	sigval = *( (sigval_t *) p );

	ASSERT_ERRNO_AND_EXIT ( signo > 0 && signo <= SIGMAX, EINVAL );

	thread = (pthread_t) pid; /* pid_t should be pthread_t */
	ASSERT_ERRNO_AND_EXIT ( thread.ptr, EINVAL );

	kthread = thread.ptr;
	ASSERT_ERRNO_AND_EXIT ( kthread_get_id (kthread) == thread.id, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( kthread_check_kthread ( kthread ), EINVAL );

	sender.id = kthread_get_id (NULL);
	sender.ptr = kthread_get_active ();

	sig.si_signo = signo;
	sig.si_value = sigval;
	sig.si_pid = sender;
	sig.si_code = SI_USER;
	sig.si_errno = 0;

	EXIT ( ksignal_queue ( kthread, &sig ) );
}
Beispiel #7
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 ( void *p )
{
	pthread_t *thread;
	int policy;
	sched_param_t *param;

	kthread_t *kthread;

	thread = *( (pthread_t **) p );		p += sizeof (pthread_t *);
	policy = *( (int *) p );		p += sizeof (int);
	param =  *( (sched_param_t **) p );

	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 >= 0 && policy < SCHED_NUM, EINVAL );

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

	return kthread_setschedparam ( kthread, policy, param );
}
/*!
 * 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 );
}
Beispiel #9
0
/*! Change thread scheduling parameters ------------------------------------- */
int kthread_setschedparam (kthread_t *kthread, int policy, sched_param_t *param)
{
	int sched_priority;

	ASSERT_ERRNO_AND_EXIT ( kthread, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( kthread_is_alive (kthread), ESRCH );
	ASSERT_ERRNO_AND_EXIT ( policy >= 0 && policy < SCHED_NUM, EINVAL );

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

		if ( param->sched_priority )
			sched_priority = param->sched_priority;
		else
			sched_priority = kthread->sched_priority;
	}
	else {
		sched_priority = kthread->sched_priority;
	}

	/* change in priority? */
	if ( kthread->sched_priority != sched_priority )
		kthread_set_prio ( kthread, sched_priority );

	return EXIT_SUCCESS;
}
Beispiel #10
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 ( void *p )
{
	pthread_mutex_t *mutex;

	kpthread_mutex_t *kmutex;
	kobject_t *kobj;

	mutex = *( (pthread_mutex_t **) p );
	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 ();
	}

	return EXIT_SUCCESS;
}
Beispiel #11
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 #12
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 ( void *p )
{
	sem_t *sem;

	ksem_t *ksem;
	kobject_t *kobj;

	sem = *( (sem_t **) p );

	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 )
		EXIT2 ( EBUSY, EXIT_FAILURE );

	kfree_kobject ( kobj );

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

	EXIT2 ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #13
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 ( void *p )
{
	sem_t *sem;

	ksem_t *ksem;
	kobject_t *kobj;
	kthread_t *kthread;

	sem = *( (sem_t **) p );
	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 );

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

	return EXIT_SUCCESS;
}
Beispiel #14
0
/*!
 * Create new timer
 * \param clockid	Clock used in timer
 * \param evp		Timer expiration action
 * \param timerid	Timer descriptor is returned in this variable
 * \return status	0 for success
 */
int sys__timer_create ( void *p )
{
	clockid_t clockid;
	sigevent_t *evp;
	timer_t *timerid;

	ktimer_t *ktimer;
	int retval = EXIT_SUCCESS;
	kobject_t *kobj;

	clockid =	*( (clockid_t *) p );	p += sizeof (clockid_t);
	evp =		*( (sigevent_t **) p );	p += sizeof (sigevent_t *);
	timerid =	*( (timer_t **) p );

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

	retval = ktimer_create ( clockid, evp, &ktimer, kthread_get_active() );
	if ( retval == EXIT_SUCCESS )
	{
		kobj = kmalloc_kobject ( 0 );
		kobj->kobject = ktimer;
		timerid->id = ktimer->id;
		timerid->ptr = kobj;
	}
	EXIT ( retval );
}
Beispiel #15
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 ( void *p )
{
	sem_t *sem;
	int pshared;
	int value;

	ksem_t *ksem;
	kobject_t *kobj;

	sem =		*( (sem_t **) p );	p += sizeof (sem_t *);
	pshared =	*( (int *) p );		p += sizeof (int);
	value =		*( (uint *) p );

	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;

	EXIT2 ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #16
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 ( void *p )
{
	pthread_cond_t *cond;

	kpthread_cond_t *kcond;
	kobject_t *kobj;

	cond = *( (pthread_cond_t **) p );
	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 )
		EXIT2 ( EBUSY, EXIT_FAILURE );

	kfree_kobject ( kobj );

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

	EXIT2 ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #17
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 ( void *p )
{
	pthread_mutex_t *mutex;

	kpthread_mutex_t *kmutex;
	kobject_t *kobj;
	int retval = EXIT_SUCCESS;

	mutex = *( (pthread_mutex_t **) p );
	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 ();

	return retval != -1;
}
Beispiel #18
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 ( void *p )
{
	pthread_mutex_t *mutex;
	/* pthread_mutexattr_t *mutexattr; not implemented */

	kpthread_mutex_t *kmutex;
	kobject_t *kobj;

	mutex = *( (pthread_mutex_t **) p ); /* p += sizeof (pthread_mutex_t *);
	mutexattr = *( (pthread_mutexattr_t *) p ); */

	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;

	EXIT2 ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #19
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 #20
0
/*!
 * Get timer expiration time
 * \param timerid	Timer descriptor (user descriptor)
 * \param value		Where to store time to next timer expiration (+period)
 * \return status	0 for success
 */
int sys__timer_gettime ( void *p )
{
	timer_t *timerid;
	itimerspec_t *value;

	ktimer_t *ktimer;
	int retval;
	kobject_t *kobj;

	timerid = *( (timer_t **) p );		p += sizeof (timer_t *);
	value =	  *( (itimerspec_t **) p );

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

	ktimer = kobj->kobject;
	ASSERT_ERRNO_AND_EXIT ( ktimer && ktimer->id == timerid->id, EINVAL );

	retval = ktimer_gettime ( ktimer, value );

	EXIT ( retval );
}
Beispiel #21
0
/*!
 * Delete timer
 * \param timerid	Timer descriptor (user descriptor)
 * \return status	0 for success
 */
int sys__timer_delete ( void *p )
{
	timer_t *timerid;

	ktimer_t *ktimer;
	int retval;
	kobject_t *kobj;

	timerid = *( (timer_t **) p );

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

	ktimer = kobj->kobject;
	ASSERT_ERRNO_AND_EXIT ( ktimer && ktimer->id == timerid->id, EINVAL );

	retval = ktimer_delete ( ktimer );

	kfree_kobject ( kobj );

	EXIT ( retval );
}
/*!
 * 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 );
}
Beispiel #23
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 ( void *p )
{
	pthread_cond_t *cond;
	/* pthread_condattr_t *condattr; not implemented */

	kpthread_cond_t *kcond;
	kobject_t *kobj;

	cond = *( (pthread_cond_t **) p ); /* p += sizeof (pthread_cond_t *);
	condattr = *( (pthread_condattr_t *) p ); */

	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;

	EXIT2 ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #24
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 ( void *p )
{
	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;

	thread = *( (pthread_t **) p );		p += sizeof (pthread_t *);
	attr = *( (pthread_attr_t **) p );	p += sizeof (pthread_attr_t *);
	start_routine = *( (void **) p );	p += sizeof (void *);
	arg = *( (void **) p );

	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 >= 0 && sched_policy < SCHED_NUM,
			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);
	}

	SET_ERRNO ( EXIT_SUCCESS );

	kthreads_schedule ();

	return EXIT_SUCCESS;
}
Beispiel #25
0
/*!
 * Close a message queue
 * \param mqdes Queue descriptor address (user level descriptor)
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__mq_close ( void *p )
{
	mqd_t *mqdes;

	kmq_queue_t *kq_queue;
	kobject_t *kobj;
	kmq_msg_t *kmq_msg;
	kthread_t *kthread;

	mqdes = *( (mqd_t **) p );

	ASSERT_ERRNO_AND_EXIT ( mqdes, EBADF );

	kobj = mqdes->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj, EBADF );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj->list ),
				EBADF );

	kq_queue = kobj->kobject;
	kq_queue = list_find_and_remove ( &kmq_queue, &kq_queue->list );

	if ( !kq_queue || kq_queue->id != mqdes->id )
		EXIT2 ( EBADF, EXIT_FAILURE );

	kq_queue->ref_cnt--;

	if ( !kq_queue->ref_cnt )
	{
		/* remove messages */
		while( (kmq_msg = list_remove(&kq_queue->msg_list,FIRST,NULL)) )
			kfree (kmq_msg);

		/* remove blocked threads */
		while ( (kthread = kthreadq_remove (&kq_queue->send_q, NULL)) )
		{
			kthread_move_to_ready ( kthread, LAST );
			kthread_set_errno ( kthread, EBADF );
			kthread_set_syscall_retval ( kthread, EXIT_FAILURE );
		}
		while ( (kthread = kthreadq_remove (&kq_queue->recv_q, NULL)) )
		{
			kthread_move_to_ready ( kthread, LAST );
			kthread_set_errno ( kthread, EBADF );
			kthread_set_syscall_retval ( kthread, EXIT_FAILURE );
		}

		list_remove ( &kmq_queue, 0, &kq_queue->list );
		k_free_id ( kq_queue->id );
		kfree ( kq_queue->name );
		kfree ( kq_queue );
	}

	/* remove kernel object descriptor */
	kfree_kobject ( kobj );

	EXIT2 ( EXIT_SUCCESS, EXIT_SUCCESS );
}
Beispiel #26
0
/*!
 * Wait for signal
 * \param set Signals thread is waiting for
 * \param info Where to save caught signal
 * \return signal number if signal is caught,
 *         -1 otherwise and appropriate error number is set
 */
int sys__sigwaitinfo ( void *p )
{
	sigset_t *set;
	siginfo_t *info;

	kthread_t *kthread;
	ksignal_handling_t *sh;
	ksiginfo_t *ksig, *next;
	int retval;

	set =   *( (sigset_t **) p );		p += sizeof (sigset_t *);
	info =  *( (siginfo_t **) p );

	ASSERT_ERRNO_AND_EXIT ( set, EINVAL );
	set = U2K_GET_ADR ( set, kthread_get_process (NULL) );
	ASSERT_ERRNO_AND_EXIT ( set, EINVAL );

	if ( info )
		info = U2K_GET_ADR ( info, kthread_get_process (NULL) );

	kthread = kthread_get_active ();
	sh = kthread_get_sigparams ( kthread );

	/* first, search for such signal in pending signals */
	ksig = list_get ( &sh->pending_signals, FIRST );
	while ( ksig )
	{
		next = list_get_next ( &ksig->list );

		if ( sigtestset ( set, ksig->siginfo.si_signo ) )
		{
			retval = ksig->siginfo.si_signo;
			if ( info )
				*info = ksig->siginfo;

			list_remove ( &sh->pending_signals, 0, &ksig->list );
			kfree ( ksig );

			EXIT2 ( EXIT_SUCCESS, retval );
		}

		ksig = next;
	}

	/*
	 * if no pending signal found that matches given mask
	 * suspend thread until signal is received
	 */
	kthread_suspend ( kthread, ksignal_received_signal, NULL );
	kthreads_schedule ();

	EXIT ( EINTR ); /* if other events wake thread */
}
Beispiel #27
0
static int cond_release ( void *p, int release_all )
{
	pthread_cond_t *cond;

	kpthread_cond_t *kcond;
	kpthread_mutex_t *kmutex;
	kobject_t *kobj_cond, *kobj_mutex;
	kthread_t *kthread;
	int retval = 0;

	cond = *( (pthread_cond_t **) p );
	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, 0, NULL, NULL);
		}
	}

	if ( retval > -1 )
		kthreads_schedule ();

	return EXIT_SUCCESS;
}
Beispiel #28
0
/*!
 * Modify thread signal mask
 * \param how How to modify current must
 * \param set Mask to use in modification
 * \param oset Where to store old mask
 * \return 0 if successful, -1 otherwise and appropriate error number is set
 */
int sys__pthread_sigmask ( void *p )
{
	int how;
	sigset_t *set;
	sigset_t *oset;

	ksignal_handling_t *sh;
	int retval = EXIT_SUCCESS;

	how =  *( (int *) p );		p += sizeof (int);
	set =  *( (sigset_t **) p );	p += sizeof (sigset_t *);
	oset = *( (sigset_t **) p );

	ASSERT_ERRNO_AND_EXIT ( set, EINVAL );
	set = U2K_GET_ADR ( set, kthread_get_process (NULL) );
	ASSERT_ERRNO_AND_EXIT ( set, EINVAL );

	sh = kthread_get_sigparams ( NULL );

	if (oset)
		oset = U2K_GET_ADR ( oset, kthread_get_process (NULL) );

	if (oset)
		*oset = *sh->mask;

	switch ( how )
	{
	case SIG_BLOCK:
		sigaddsets ( sh->mask, set );
		break;

	case SIG_UNBLOCK:
		sigaddsets ( sh->mask, set );
		break;

	case SIG_SETMASK:
		*sh->mask = *set;
		break;

	default:
		retval = EINVAL;
	}

	/* reevaluate pending signals with new mask */
	if ( retval == EXIT_SUCCESS )
		retval = ksignal_process_pending ( kthread_get_active () );

	EXIT ( retval );
}
/*!
 * Retrieve parameters for existing alarm (get its values)
 * \param alarm Pointer where alarm parameters will be stored
 * \return status (0 for success)
 */
int sys__alarm_get ( void *id, alarm_t *alarm )
{
	kalarm_t *kalarm;

	ASSERT_ERRNO_AND_EXIT ( id && alarm, E_INVALID_HANDLE );

	kalarm = id;

	ASSERT_ERRNO_AND_EXIT ( kalarm && kalarm->magic == ALARM_MAGIC,
				E_INVALID_HANDLE );

	*alarm = kalarm->alarm;

	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 );
}