/*! Initialize EDF scheduler */ static int edf_init ( ksched_t *ksched ) { ksched->params.edf.active = NULL; kthreadq_init ( &ksched->params.edf.ready ); kthreadq_init ( &ksched->params.edf.wait ); return 0; }
/*! Init EDF scheduler */ static int edf_init ( ksched_t *self ) { ASSERT ( self == &ksched_edf ); self->params.edf.active = NULL; kthreadq_init ( &self->params.edf.ready ); kthreadq_init ( &self->params.edf.wait ); return 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 ); }
/*! * 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 ); }
/*! * 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 ); }
/*! Initialize device (and call its initializer, if set) */ int k_device_init ( kdevice_t *kdev, int flags, void *params, void *callback ) { int retval = 0; ASSERT ( kdev ); if ( flags ) kdev->dev.flags = flags; if ( params ) kdev->dev.params = params; kdev->locked = FALSE; kthreadq_init ( &kdev->thrq ); if ( kdev->dev.init ) retval = kdev->dev.init ( flags, params, &kdev->dev ); if ( !retval && kdev->dev.irq_handler ) { (void) arch_register_interrupt_handler ( kdev->dev.irq_num, kdev->dev.irq_handler, &kdev->dev ); arch_irq_enable ( kdev->dev.irq_num ); } if ( callback ) kdev->dev.callback = callback; return retval; }
/*! * 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 ); }
/*! * 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 ); }
/*! * Create new thread * \param start_routine Starting function for new thread * \param arg Parameter sent to starting function * \param sched_policy Thread scheduling policy * \param sched_priority Thread priority * \param stackaddr Address of thread stack (if not NULL) * \param stacksize Stack size * \param proc Process descriptor thread belongs to * \return Pointer to descriptor of created kernel thread */ kthread_t *kthread_create ( void *start_routine, void *arg, uint flags, int sched_policy, int sched_priority, sched_supp_t *sched_param, void *stackaddr, size_t stacksize, kprocess_t *proc ) { ASSERT ( proc ); kthread_t *kthread; /* thread descriptor */ kthread = kmalloc ( sizeof (kthread_t) ); ASSERT ( kthread ); /* initialize thread descriptor */ kthread->id = k_new_id (); kthread->proc = proc; kthread->proc->thread_count++; kthread->queue = NULL; kthreadq_init ( &kthread->join_queue ); kthread_create_new_state ( kthread, start_routine, arg, stackaddr, stacksize, FALSE ); kthread->state.flags = flags; list_init ( &kthread->states ); /* connect signal mask in descriptor with state */ kthread->sig_handling.mask = &kthread->state.sigmask; ksignal_thread_init ( kthread ); list_append ( &all_threads, kthread, &kthread->all ); kthread->sched_policy = sched_policy; if ( sched_priority < 0 ) sched_priority = 0; if ( sched_priority >= PRIO_LEVELS ) sched_priority = PRIO_LEVELS - 1; kthread->sched_priority = sched_priority; kthread->ref_cnt = 1; kthread_move_to_ready ( kthread, LAST ); ksched2_thread_add (kthread, sched_policy, sched_priority, sched_param); return kthread; }
/*! initialize data structure for ready threads */ void ksched_init () { int i; ready.prio_levels = PRIO_LEVELS; ready.rq = kmalloc ( ready.prio_levels * sizeof(kthread_q) ); ready.mask_len = (ready.prio_levels + UINT_SIZE - 1) / UINT_SIZE; ready.mask = kmalloc ( ready.mask_len * sizeof(uint) ); /* queue for ready threads is empty */ for ( i = 0; i < ready.prio_levels; i++ ) kthreadq_init ( &ready.rq[i] ); for ( i = 0; i < ready.mask_len; i++ ) ready.mask[i] = 0; #ifdef SCHED_RR_SIMPLE if ( sys__feature ( FEATURE_SCHED_RR, FEATURE_GET, 0 ) ) ksched_rr_start_timer (); #endif }
/*! * 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 ); }
/*! * Open a message queue * \param name Queue name * \param oflag Opening flags * \param mode Permissions on created queue (only when O_CREAT is set) * \param attr Message queue attributes (only when O_CREAT is set) * \param mqdes Return queue descriptor address (user level descriptor) * \return 0 if successful, -1 otherwise and appropriate error number is set */ int sys__mq_open ( void *p ) { char *name; int oflag; /* mode_t mode; not used in this implementation */ mq_attr_t *attr; mqd_t *mqdes; kmq_queue_t *kq_queue; kobject_t *kobj; name = *( (char **) p ); p += sizeof (char *); oflag = *( (int *) p ); p += sizeof (int); /* mode = *( (mode_t *) p ); */ p += sizeof (mode_t); attr = *( (mq_attr_t **) p ); p += sizeof (mq_attr_t*); mqdes = *( (mqd_t **) p ); ASSERT_ERRNO_AND_EXIT ( name && mqdes, EBADF ); ASSERT_ERRNO_AND_EXIT ( strlen (name) < NAME_MAX, EBADF ); kq_queue = list_get ( &kmq_queue, FIRST ); while ( kq_queue && strcmp ( name, kq_queue->name ) ) kq_queue = list_get_next ( &kq_queue->list ); if ( ( kq_queue && ( (oflag & O_CREAT) || (oflag & O_EXCL) ) ) || ( !kq_queue && !(oflag & O_CREAT ) ) ) { mqdes->ptr = (void *) -1; mqdes->id = -1; EXIT2 ( EEXIST, EXIT_FAILURE ); } if ( !kq_queue && (oflag & O_CREAT) ) { kq_queue = kmalloc ( sizeof (kmq_queue_t) ); if ( attr ) kq_queue->attr = *attr; kq_queue->id = k_new_id (); kq_queue->attr.mq_curmsgs = 0; kq_queue->name = kmalloc ( strlen (name) + 1 ); strcpy ( kq_queue->name, name ); kq_queue->ref_cnt = 0; list_init ( &kq_queue->msg_list ); kthreadq_init ( &kq_queue->recv_q ); kthreadq_init ( &kq_queue->send_q ); list_append ( &kmq_queue, kq_queue, &kq_queue->list ); } kq_queue->ref_cnt++; kobj = kmalloc_kobject ( 0 ); kobj->kobject = kq_queue; kobj->flags = oflag; mqdes->ptr = kobj; mqdes->id = kq_queue->id; EXIT2 ( EXIT_SUCCESS, EXIT_SUCCESS ); }