📄 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 != 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 + -