📄 os_core_linux_kernel.c
字号:
/* 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 != 0PJ_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 != 0PJ_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 + -