⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_core_linux_kernel.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
    
    /* Create the new thread by running a task through keventd. */

#if 0
    /* Initialize the task queue struct. */
    thread->tq.sync = 0;
    INIT_LIST_HEAD(&thread->tq.list);
    thread->tq.routine = kthread_launcher;
    thread->tq.data = thread;

    /* and schedule it for execution. */
    schedule_task(&thread->tq);
#endif
    kthread_launcher(thread);

    /* Wait until thread has reached the setup_thread routine. */
    TRACE_((THIS_FILE, "...wait for the new thread..."));
    down(&thread->startstop_sem);

    TRACE_((THIS_FILE, "...main thread resumed..."));
    return PJ_SUCCESS;
}

PJ_DEF(const char*) pj_thread_get_name(pj_thread_t *thread)
{
    return thread->obj_name;
}

PJ_DEF(pj_status_t) pj_thread_resume(pj_thread_t *thread)
{
    up(&thread->suspend_sem);
    return PJ_SUCCESS;
}

PJ_DEF(pj_thread_t*) pj_thread_this(void)
{
    return (pj_thread_t*)pj_thread_local_get(thread_tls_id);
}

PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
{
    TRACE_((THIS_FILE, "pj_thread_join()"));
    down(&p->startstop_sem);
    TRACE_((THIS_FILE, "  joined!"));
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *thread)
{
    PJ_ASSERT_RETURN(thread != NULL, PJ_EINVALIDOP);
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
{
    pj_highprec_t ticks;
    pj_thread_t *thread = pj_thread_this();

    PJ_ASSERT_RETURN(thread != NULL, PJ_EBUG);
    
    /* Use high precision calculation to make sure we don't
     * crop values:
     *
     *	ticks = HZ * msec / 1000
     */
    ticks = HZ;
    pj_highprec_mul(ticks, msec);
    pj_highprec_div(ticks, 1000);

    TRACE_((THIS_FILE, "this thread will sleep for %u ticks", ticks));
    interruptible_sleep_on_timeout( &thread->queue, ticks);
    return PJ_SUCCESS;
}


///////////////////////////////////////////////////////////////////////////////
PJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool, 
				      pj_atomic_value_t value,
				      pj_atomic_t **ptr_var)
{
    pj_atomic_t *t = pj_pool_calloc(pool, 1, sizeof(pj_atomic_t));
    if (!t) return PJ_ENOMEM;

    atomic_set(&t->atom, value);
    *ptr_var = t;
    
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_atomic_destroy( pj_atomic_t *var )
{
    return PJ_SUCCESS;
}

PJ_DEF(void) pj_atomic_set(pj_atomic_t *var, pj_atomic_value_t value)
{
    atomic_set(&var->atom, value);
}

PJ_DEF(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *var)
{
    return atomic_read(&var->atom);
}

PJ_DEF(void) pj_atomic_inc(pj_atomic_t *var)
{
    atomic_inc(&var->atom);
}

PJ_DEF(void) pj_atomic_dec(pj_atomic_t *var)
{
    atomic_dec(&var->atom);
}

PJ_DEF(void) pj_atomic_add( pj_atomic_t *var, pj_atomic_value_t value )
{
    atomic_add(value, &var->atom);
}


///////////////////////////////////////////////////////////////////////////////
PJ_DEF(pj_status_t) pj_thread_local_alloc(long *index)
{
    if (tls_id >= MAX_TLS_ID)
	return PJ_ETOOMANY;
    
    *index = tls_id++;

    return PJ_SUCCESS;
}

PJ_DEF(void) pj_thread_local_free(long index)
{
    pj_assert(index >= 0 && index < MAX_TLS_ID);
}

PJ_DEF(pj_status_t) pj_thread_local_set(long index, void *value)
{
    pj_assert(index >= 0 && index < MAX_TLS_ID);
    tls_values[index] = value;
    return PJ_SUCCESS;
}

PJ_DEF(void*) pj_thread_local_get(long index)
{
    pj_assert(index >= 0 && index < MAX_TLS_ID);
    return tls_values[index];
}


///////////////////////////////////////////////////////////////////////////////
PJ_DEF(void) pj_enter_critical_section(void)
{
    spin_lock_irqsave(&critical_section, spinlock_flags);
}

PJ_DEF(void) pj_leave_critical_section(void)
{
    spin_unlock_irqrestore(&critical_section, spinlock_flags);
}


///////////////////////////////////////////////////////////////////////////////
PJ_DEF(pj_status_t) pj_mutex_create( pj_pool_t *pool, 
				     const char *name, 
				     int type,
				     pj_mutex_t **ptr_mutex)
{
    pj_mutex_t *mutex;
    
    PJ_UNUSED_ARG(name);

    mutex = pj_pool_alloc(pool, sizeof(pj_mutex_t));
    if (!mutex)
	return PJ_ENOMEM;

    init_MUTEX(&mutex->sem);

    mutex->recursive = (type == PJ_MUTEX_RECURSE);
    mutex->owner = NULL;
    mutex->own_count = 0;
    
    /* Done. */
    *ptr_mutex = mutex;
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
					    pj_mutex_t **mutex )
{
    return pj_mutex_create(pool, name, PJ_MUTEX_SIMPLE, mutex);
}

PJ_DEF(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
					       const char *name,
					       pj_mutex_t **mutex )
{
    return pj_mutex_create( pool, name, PJ_MUTEX_RECURSE, mutex);
}

PJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)
{
    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);

    if (mutex->recursive) {
	pj_thread_t *this_thread = pj_thread_this();
	if (mutex->owner == this_thread) {
	    ++mutex->own_count;
	} else {
	    down(&mutex->sem);
	    pj_assert(mutex->own_count == 0);
	    mutex->owner = this_thread;
	    mutex->own_count = 1;
	}
    } else {
	down(&mutex->sem);
    }
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)
{
    long rc;

    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);

    if (mutex->recursive) {
	pj_thread_t *this_thread = pj_thread_this();
	if (mutex->owner == this_thread) {
	    ++mutex->own_count;
	} else {
	    rc = down_interruptible(&mutex->sem);
	    if (rc != 0)
		return PJ_RETURN_OS_ERROR(-rc);
	    pj_assert(mutex->own_count == 0);
	    mutex->owner = this_thread;
	    mutex->own_count = 1;
	}
    } else {
	int rc = down_trylock(&mutex->sem);
	if (rc != 0)
	    return PJ_RETURN_OS_ERROR(-rc);
    }
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)
{
    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);

    if (mutex->recursive) {
	pj_thread_t *this_thread = pj_thread_this();
	if (mutex->owner == this_thread) {
	    pj_assert(mutex->own_count > 0);
	    --mutex->own_count;
	    if (mutex->own_count == 0) {
		mutex->owner = NULL;
		up(&mutex->sem);
	    }
	} else {
	    pj_assert(!"Not owner!");
	    return PJ_EINVALIDOP;
	}
    } else {
	up(&mutex->sem);
    }
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)
{
    PJ_ASSERT_RETURN(mutex != NULL, PJ_EINVAL);

    return PJ_SUCCESS;
}

#if defined(PJ_DEBUG) && PJ_DEBUG != 0
PJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)
{
    if (mutex->recursive)
	return mutex->owner == pj_thread_this();
    else
	return 1;
}
#endif	/* PJ_DEBUG */


#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0

PJ_DEF(pj_status_t) pj_sem_create(  pj_pool_t *pool, 
                                    const char *name,
				    unsigned initial, 
                                    unsigned max,
				    pj_sem_t **sem)
{
    pj_sem_t *sem;

    PJ_UNUSED_ARG(max);

    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);
    
    sem = pj_pool_alloc(pool, sizeof(pj_sem_t));
    sema_init(&sem->sem, initial);
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)
{
    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);

    down(&sem->sem);
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)
{
    int rc;

    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);

    rc = down_trylock(&sem->sem);
    if (rc != 0) {
	return PJ_RETURN_OS_ERROR(-rc);
    } else {
	return PJ_SUCCESS;
    }
}

PJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)
{
    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);

    up(&sem->sem);
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)
{
    PJ_ASSERT_RETURN(pool && sem, PJ_EINVAL);

    return PJ_SUCCESS;
}

#endif	/* PJ_HAS_SEMAPHORE */




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -