diff options
| author | Bernard Xiong <[email protected]> | 2016-05-10 09:22:01 +0800 |
|---|---|---|
| committer | Bernard Xiong <[email protected]> | 2016-05-10 09:22:01 +0800 |
| commit | 64feef0dde9d8353ffe4a3f257ab17848ccf6f53 (patch) | |
| tree | dd3f096b8a3c249e5327cc34a0c105c5125099e1 /components/libc/pthreads/pthread_mutex.c | |
| parent | eb320a0104bbaa6c1235fe899b6d099fdabe8c25 (diff) | |
[LIBC] mv pthreads/libdl to libc and rename dfs_lwip to dfs_net
Diffstat (limited to 'components/libc/pthreads/pthread_mutex.c')
| -rw-r--r-- | components/libc/pthreads/pthread_mutex.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/components/libc/pthreads/pthread_mutex.c b/components/libc/pthreads/pthread_mutex.c new file mode 100644 index 0000000000..40fd870e81 --- /dev/null +++ b/components/libc/pthreads/pthread_mutex.c @@ -0,0 +1,251 @@ +/* + * File : pthread_mutex.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2010-10-26 Bernard the first version + */ + +#include <rtthread.h> +#include "pthread.h" + +#define MUTEXATTR_SHARED_MASK 0x0010 +#define MUTEXATTR_TYPE_MASK 0x000f + +const pthread_mutexattr_t pthread_default_mutexattr = PTHREAD_PROCESS_PRIVATE; + +int pthread_mutexattr_init(pthread_mutexattr_t *attr) +{ + if (attr) + { + *attr = pthread_default_mutexattr; + + return 0; + } + + return EINVAL; +} +RTM_EXPORT(pthread_mutexattr_init); + +int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) +{ + if (attr) + { + *attr = -1; + + return 0; + } + + return EINVAL; +} +RTM_EXPORT(pthread_mutexattr_destroy); + +int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) +{ + if (attr && type) + { + int atype = (*attr & MUTEXATTR_TYPE_MASK); + + if (atype >= PTHREAD_MUTEX_NORMAL && atype <= PTHREAD_MUTEX_ERRORCHECK) + { + *type = atype; + + return 0; + } + } + + return EINVAL; +} +RTM_EXPORT(pthread_mutexattr_gettype); + +int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) +{ + if (attr && type >= PTHREAD_MUTEX_NORMAL && type <= PTHREAD_MUTEX_ERRORCHECK) + { + *attr = (*attr & ~MUTEXATTR_TYPE_MASK) | type; + + return 0; + } + + return EINVAL; +} +RTM_EXPORT(pthread_mutexattr_settype); + +int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) +{ + if (!attr) + return EINVAL; + + switch (pshared) + { + case PTHREAD_PROCESS_PRIVATE: + *attr &= ~MUTEXATTR_SHARED_MASK; + return 0; + + case PTHREAD_PROCESS_SHARED: + *attr |= MUTEXATTR_SHARED_MASK; + return 0; + } + + return EINVAL; +} +RTM_EXPORT(pthread_mutexattr_setpshared); + +int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared) +{ + if (!attr || !pshared) + return EINVAL; + + *pshared = (*attr & MUTEXATTR_SHARED_MASK) ? PTHREAD_PROCESS_SHARED + : PTHREAD_PROCESS_PRIVATE; + return 0; +} +RTM_EXPORT(pthread_mutexattr_getpshared); + +int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + rt_err_t result; + char name[RT_NAME_MAX]; + static rt_uint16_t pthread_mutex_number = 0; + + if (!mutex) + return EINVAL; + + /* build mutex name */ + rt_snprintf(name, sizeof(name), "pmtx%02d", pthread_mutex_number ++); + if (attr == RT_NULL) + mutex->attr = pthread_default_mutexattr; + else + mutex->attr = *attr; + + /* init mutex lock */ + result = rt_mutex_init(&(mutex->lock), name, RT_IPC_FLAG_FIFO); + if (result != RT_EOK) + return EINVAL; + + /* detach the object from system object container */ + rt_object_detach(&(mutex->lock.parent.parent)); + + return 0; +} +RTM_EXPORT(pthread_mutex_init); + +int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + if (!mutex || mutex->attr == -1) + return EINVAL; + + /* it's busy */ + if (mutex->lock.owner != RT_NULL) + return EBUSY; + + rt_memset(mutex, 0, sizeof(pthread_mutex_t)); + mutex->attr = -1; + + return 0; +} +RTM_EXPORT(pthread_mutex_destroy); + +int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + int mtype; + rt_err_t result; + + if (!mutex) + return EINVAL; + + if (mutex->attr == -1) + { + /* init mutex */ + pthread_mutex_init(mutex, RT_NULL); + } + + mtype = mutex->attr & MUTEXATTR_TYPE_MASK; + rt_enter_critical(); + if (mutex->lock.owner == rt_thread_self() && + mtype != PTHREAD_MUTEX_RECURSIVE) + { + rt_exit_critical(); + + return EDEADLK; + } + rt_exit_critical(); + + result = rt_mutex_take(&(mutex->lock), RT_WAITING_FOREVER); + if (result == RT_EOK) + return 0; + + return EINVAL; +} +RTM_EXPORT(pthread_mutex_lock); + +int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + rt_err_t result; + + if (!mutex) + return EINVAL; + if (mutex->attr == -1) + { + /* init mutex */ + pthread_mutex_init(mutex, RT_NULL); + } + + if (mutex->lock.owner != rt_thread_self()) + { + int mtype; + mtype = mutex->attr & MUTEXATTR_TYPE_MASK; + + /* error check, return EPERM */ + if (mtype == PTHREAD_MUTEX_ERRORCHECK) + return EPERM; + + /* no thread waiting on this mutex */ + if (mutex->lock.owner == RT_NULL) + return 0; + } + + result = rt_mutex_release(&(mutex->lock)); + if (result == RT_EOK) + return 0; + + return EINVAL; +} +RTM_EXPORT(pthread_mutex_unlock); + +int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + rt_err_t result; + + if (!mutex) + return EINVAL; + if (mutex->attr == -1) + { + /* init mutex */ + pthread_mutex_init(mutex, RT_NULL); + } + + result = rt_mutex_take(&(mutex->lock), 0); + if (result == RT_EOK) + return 0; + + return EBUSY; +} +RTM_EXPORT(pthread_mutex_trylock); + |
