Browse Source

Embedded GPLv2 license in pthreads

yiyue.fang 12 years ago
parent
commit
8ab2b287b8

+ 86 - 71
components/pthreads/clock_time.c

@@ -3,15 +3,26 @@
  * This file is part of RT-Thread RTOS
  * COPYRIGHT (C) 2012, RT-Thread Development Team
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
+ *  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
  * 2012-12-08     Bernard      fix the issue of _timevalue.tv_usec initialization, 
  *                             which found by Rob <rdent@iinet.net.au>
  */
+
 #include <rtthread.h>
 #include <pthread.h>
 
@@ -26,11 +37,11 @@ void clock_time_system_init()
     device = rt_device_find("rtc");
     if (device != RT_NULL)
     {
-		/* get realtime seconds */
+        /* get realtime seconds */
         rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
     }
 
-	/* get tick */
+    /* get tick */
     tick = rt_tick_get();
 
     _timevalue.tv_usec = (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
@@ -39,102 +50,106 @@ void clock_time_system_init()
 
 int clock_time_to_tick(const struct timespec *time)
 {
-	int tick;
-	int nsecond, second;
-	struct timespec tp;
-
-	RT_ASSERT(time != RT_NULL);
-
-	tick = RT_WAITING_FOREVER;
-	if (time != NULL)
-	{
-		/* get current tp */
-		clock_gettime(CLOCK_REALTIME, &tp);
-
-		if ((time->tv_nsec - tp.tv_nsec) < 0)
-		{
-			nsecond = NANOSECOND_PER_SECOND - (tp.tv_nsec - time->tv_nsec);
-			second  = time->tv_sec - tp.tv_sec - 1;
-		}
-		else
-		{
-			nsecond = time->tv_nsec - tp.tv_nsec;
-			second  = time->tv_sec - tp.tv_sec;
-		}
-
-		tick = second * RT_TICK_PER_SECOND + nsecond * RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND;
-		if (tick < 0) tick = 0;
-	}
-
-	return tick;
+    int tick;
+    int nsecond, second;
+    struct timespec tp;
+
+    RT_ASSERT(time != RT_NULL);
+
+    tick = RT_WAITING_FOREVER;
+    if (time != NULL)
+    {
+        /* get current tp */
+        clock_gettime(CLOCK_REALTIME, &tp);
+
+        if ((time->tv_nsec - tp.tv_nsec) < 0)
+        {
+            nsecond = NANOSECOND_PER_SECOND - (tp.tv_nsec - time->tv_nsec);
+            second  = time->tv_sec - tp.tv_sec - 1;
+        }
+        else
+        {
+            nsecond = time->tv_nsec - tp.tv_nsec;
+            second  = time->tv_sec - tp.tv_sec;
+        }
+
+        tick = second * RT_TICK_PER_SECOND + nsecond * RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND;
+        if (tick < 0) tick = 0;
+    }
+
+    return tick;
 }
 RTM_EXPORT(clock_time_to_tick);
 
-int clock_getres  (clockid_t clockid, struct timespec *res)
+int clock_getres(clockid_t clockid, struct timespec *res)
 {
-	if ((clockid != CLOCK_REALTIME) || (res == RT_NULL))
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+    if ((clockid != CLOCK_REALTIME) || (res == RT_NULL))
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
 
-	res->tv_sec = 0;
-	res->tv_nsec = NANOSECOND_PER_SECOND/RT_TICK_PER_SECOND;
+    res->tv_sec = 0;
+    res->tv_nsec = NANOSECOND_PER_SECOND/RT_TICK_PER_SECOND;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(clock_getres);
 
-int clock_gettime (clockid_t clockid, struct timespec *tp)
+int clock_gettime(clockid_t clockid, struct timespec *tp)
 {
-	rt_tick_t tick;
+    rt_tick_t tick;
 
-	if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL))
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+    if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL))
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
 
-	/* get tick */
-	tick = rt_tick_get();
+    /* get tick */
+    tick = rt_tick_get();
 
-	tp->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND;
-	tp->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * NANOSECOND_PER_TICK) * 1000;
-	
-	return 0;
+    tp->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND;
+    tp->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * NANOSECOND_PER_TICK) * 1000;
+    
+    return 0;
 }
 RTM_EXPORT(clock_gettime);
 
-int clock_settime (clockid_t clockid, const struct timespec *tp)
+int clock_settime(clockid_t clockid, const struct timespec *tp)
 {
-	int second;
-	rt_tick_t tick;
+    int second;
+    rt_tick_t tick;
     rt_device_t device;
 
-	if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL))
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+    if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL))
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
 
-	/* get second */
-	second = tp->tv_sec;
-	/* get tick */
+    /* get second */
+    second = tp->tv_sec;
+    /* get tick */
     tick = rt_tick_get();
 
-	/* update timevalue */
+    /* update timevalue */
     _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
     _timevalue.tv_sec = second - tick/RT_TICK_PER_SECOND - 1;
 
-	/* update for RTC device */
+    /* update for RTC device */
     device = rt_device_find("rtc");
     if (device != RT_NULL)
     {
-		/* set realtime seconds */
+        /* set realtime seconds */
         rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second);
     }
-	else return -1;
+    else
+        return -1;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(clock_settime);

+ 231 - 187
components/pthreads/mqueue.c

@@ -1,3 +1,26 @@
+/*
+ * File      : mqueue.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, 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
+ */
+
 #include "mqueue.h"
 #include "pthread_internal.h"
 
@@ -5,266 +28,285 @@ static mqd_t posix_mq_list = RT_NULL;
 static struct rt_semaphore posix_mq_lock;
 void posix_mq_system_init()
 {
-	rt_sem_init(&posix_mq_lock, "pmq", 1, RT_IPC_FLAG_FIFO);
+    rt_sem_init(&posix_mq_lock, "pmq", 1, RT_IPC_FLAG_FIFO);
 }
 
 rt_inline void posix_mq_insert(mqd_t pmq)
 {
-	pmq->next = posix_mq_list;
-	posix_mq_list = pmq;
+    pmq->next = posix_mq_list;
+    posix_mq_list = pmq;
 }
 
 static void posix_mq_delete(mqd_t pmq)
 {
-	mqd_t iter;
-	if (posix_mq_list == pmq)
-	{
-		posix_mq_list = pmq->next;
-
-		rt_mq_delete(pmq->mq);
-		rt_free(pmq);
-
-		return;
-	}
-	for (iter = posix_mq_list; iter->next != RT_NULL; iter = iter->next)
-	{
-		if (iter->next == pmq)
-		{
-			/* delete this mq */
-			if (pmq->next != RT_NULL)
-				iter->next = pmq->next;
-			else
-				iter->next = RT_NULL;
-
-			/* delete RT-Thread mqueue */
-			rt_mq_delete(pmq->mq);
-			rt_free(pmq);
-			return ;
-		}
-	}
+    mqd_t iter;
+    if (posix_mq_list == pmq)
+    {
+        posix_mq_list = pmq->next;
+
+        rt_mq_delete(pmq->mq);
+        rt_free(pmq);
+
+        return;
+    }
+    for (iter = posix_mq_list; iter->next != RT_NULL; iter = iter->next)
+    {
+        if (iter->next == pmq)
+        {
+            /* delete this mq */
+            if (pmq->next != RT_NULL)
+                iter->next = pmq->next;
+            else
+                iter->next = RT_NULL;
+
+            /* delete RT-Thread mqueue */
+            rt_mq_delete(pmq->mq);
+            rt_free(pmq);
+
+            return ;
+        }
+    }
 }
 
 static mqd_t posix_mq_find(const char* name)
 {
-	mqd_t iter;
-	rt_object_t object;
+    mqd_t iter;
+    rt_object_t object;
 
-	for (iter = posix_mq_list; iter != RT_NULL; iter = iter->next)
-	{
-		object = (rt_object_t)(iter->mq);
+    for (iter = posix_mq_list; iter != RT_NULL; iter = iter->next)
+    {
+        object = (rt_object_t)(iter->mq);
 
-		if (strncmp(object->name, name, RT_NAME_MAX) == 0)
-		{
-			return iter;
-		}
-	}
+        if (strncmp(object->name, name, RT_NAME_MAX) == 0)
+        {
+            return iter;
+        }
+    }
 
-	return RT_NULL;
+    return RT_NULL;
 }
 
-int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat,
-		struct mq_attr *omqstat)
+int mq_setattr(mqd_t                 mqdes,
+               const struct mq_attr *mqstat,
+               struct mq_attr       *omqstat)
 {
-	rt_set_errno(-RT_ERROR);
-	return -1;
+    rt_set_errno(-RT_ERROR);
+
+    return -1;
 }
 RTM_EXPORT(mq_setattr);
 
 int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat)
 {
-	if ((mqdes == RT_NULL) || mqstat == RT_NULL)
-	{
-		rt_set_errno(EBADF);
-		return -1;
-	}
-
-	mqstat->mq_maxmsg = mqdes->mq->max_msgs;
-	mqstat->mq_msgsize = mqdes->mq->msg_size;
-	mqstat->mq_curmsgs = 0;
-	mqstat->mq_flags = 0;
-
-	return 0;
+    if ((mqdes == RT_NULL) || mqstat == RT_NULL)
+    {
+        rt_set_errno(EBADF);
+
+        return -1;
+    }
+
+    mqstat->mq_maxmsg = mqdes->mq->max_msgs;
+    mqstat->mq_msgsize = mqdes->mq->msg_size;
+    mqstat->mq_curmsgs = 0;
+    mqstat->mq_flags = 0;
+
+    return 0;
 }
 RTM_EXPORT(mq_getattr);
 
 mqd_t mq_open(const char *name, int oflag, ...)
 {
-	mqd_t mqdes;
-	va_list arg;
-	mode_t mode;
-	struct mq_attr *attr = RT_NULL;
+    mqd_t mqdes;
+    va_list arg;
+    mode_t mode;
+    struct mq_attr *attr = RT_NULL;
 
     /* lock posix mqueue list */
     rt_sem_take(&posix_mq_lock, RT_WAITING_FOREVER);
 
     mqdes = RT_NULL;
-	if (oflag & O_CREAT)
-	{
-	    va_start(arg, oflag);
-	    mode = (mode_t) va_arg(arg, unsigned int); mode = mode;
-	    attr = (struct mq_attr *) va_arg(arg, struct mq_attr *);
-	    va_end(arg);
-
-	    if (oflag & O_EXCL)
-	    {
-	    	if (posix_mq_find(name) != RT_NULL)
-	    	{
-	    		rt_set_errno(EEXIST);
-	    		goto __return;
-	    	}
-	    }
-	    mqdes = (mqd_t) rt_malloc (sizeof(struct mqdes));
-	    if (mqdes == RT_NULL)
-	    {
-	    	rt_set_errno(ENFILE);
-	    	goto __return;
-	    }
-
-	    /* create RT-Thread message queue */
-		mqdes->mq = rt_mq_create(name, attr->mq_msgsize, attr->mq_maxmsg, RT_IPC_FLAG_FIFO);
-		if (mqdes->mq == RT_NULL) /* create failed */
-		{
-			rt_set_errno(ENFILE);
-			goto __return;
-		}
-		/* initialize reference count */
-		mqdes->refcount = 1;
-		mqdes->unlinked = 0;
-
-		/* insert mq to posix mq list */
-		posix_mq_insert(mqdes);
-	}
-	else
-	{
-		/* find mqueue */
-		mqdes = posix_mq_find(name);
-		if (mqdes != RT_NULL)
-		{
-			mqdes->refcount ++; /* increase reference count */
-		}
-		else
-		{
-			rt_set_errno(ENOENT);
-			goto __return;
-		}
-	}
-	rt_sem_release(&posix_mq_lock);
-	return mqdes;
+    if (oflag & O_CREAT)
+    {
+        va_start(arg, oflag);
+        mode = (mode_t)va_arg(arg, unsigned int);
+        mode = mode;
+        attr = (struct mq_attr *)va_arg(arg, struct mq_attr *);
+        va_end(arg);
+
+        if (oflag & O_EXCL)
+        {
+            if (posix_mq_find(name) != RT_NULL)
+            {
+                rt_set_errno(EEXIST);
+                goto __return;
+            }
+        }
+        mqdes = (mqd_t) rt_malloc (sizeof(struct mqdes));
+        if (mqdes == RT_NULL)
+        {
+            rt_set_errno(ENFILE);
+            goto __return;
+        }
+
+        /* create RT-Thread message queue */
+        mqdes->mq = rt_mq_create(name, attr->mq_msgsize, attr->mq_maxmsg, RT_IPC_FLAG_FIFO);
+        if (mqdes->mq == RT_NULL) /* create failed */
+        {
+            rt_set_errno(ENFILE);
+            goto __return;
+        }
+        /* initialize reference count */
+        mqdes->refcount = 1;
+        mqdes->unlinked = 0;
+
+        /* insert mq to posix mq list */
+        posix_mq_insert(mqdes);
+    }
+    else
+    {
+        /* find mqueue */
+        mqdes = posix_mq_find(name);
+        if (mqdes != RT_NULL)
+        {
+            mqdes->refcount ++; /* increase reference count */
+        }
+        else
+        {
+            rt_set_errno(ENOENT);
+            goto __return;
+        }
+    }
+    rt_sem_release(&posix_mq_lock);
+
+    return mqdes;
 
 __return:
-	/* release lock */
-	rt_sem_release(&posix_mq_lock);
-
-	/* release allocated memory */
-	if (mqdes != RT_NULL)
-	{
-		if (mqdes->mq != RT_NULL)
-		{
-			/* delete RT-Thread message queue */
-			rt_mq_delete(mqdes->mq);
-		}
-		rt_free(mqdes);
-	}
-	return RT_NULL;
+    /* release lock */
+    rt_sem_release(&posix_mq_lock);
+
+    /* release allocated memory */
+    if (mqdes != RT_NULL)
+    {
+        if (mqdes->mq != RT_NULL)
+        {
+            /* delete RT-Thread message queue */
+            rt_mq_delete(mqdes->mq);
+        }
+        rt_free(mqdes);
+    }
+    return RT_NULL;
 }
 RTM_EXPORT(mq_open);
 
 ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
 {
-	rt_err_t result;
+    rt_err_t result;
 
-	if ((mqdes == RT_NULL) || (msg_ptr == RT_NULL))
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+    if ((mqdes == RT_NULL) || (msg_ptr == RT_NULL))
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
 
-	result = rt_mq_recv(mqdes->mq, msg_ptr, msg_len, RT_WAITING_FOREVER);
-	if (result == RT_EOK)
-		return msg_len;
+    result = rt_mq_recv(mqdes->mq, msg_ptr, msg_len, RT_WAITING_FOREVER);
+    if (result == RT_EOK)
+        return msg_len;
 
-	rt_set_errno(EBADF);
-	return -1;
+    rt_set_errno(EBADF);
+    return -1;
 }
 RTM_EXPORT(mq_receive);
 
 int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
 {
-	rt_err_t result;
+    rt_err_t result;
+
+    if ((mqdes == RT_NULL) || (msg_ptr == RT_NULL))
+    {
+        rt_set_errno(EINVAL);
 
-	if ((mqdes == RT_NULL) || (msg_ptr == RT_NULL))
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+        return -1;
+    }
+
+    result = rt_mq_send(mqdes->mq, (void*)msg_ptr, msg_len);
+    if (result == RT_EOK)
+        return 0;
 
-	result = rt_mq_send(mqdes->mq, (void*)msg_ptr, msg_len);
-	if (result == RT_EOK)
-		return 0;
+    rt_set_errno(EBADF);
 
-	rt_set_errno(EBADF);
-	return -1;
+    return -1;
 }
 RTM_EXPORT(mq_send);
 
-ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
-	unsigned *msg_prio, const struct timespec *abs_timeout)
+ssize_t mq_timedreceive(mqd_t                  mqdes,
+                        char                  *msg_ptr,
+                        size_t                 msg_len,
+                        unsigned              *msg_prio,
+                        const struct timespec *abs_timeout)
 {
-	int tick;
-	rt_err_t result;
+    int tick;
+    rt_err_t result;
+
+    /* parameters check */
+    if ((mqdes == RT_NULL) || (msg_ptr == RT_NULL))
+    {
+        rt_set_errno(EINVAL);
 
-	/* parameters check */
-	if ((mqdes == RT_NULL) || (msg_ptr == RT_NULL))
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+        return -1;
+    }
 
-	tick = clock_time_to_tick(abs_timeout);
+    tick = clock_time_to_tick(abs_timeout);
 
-	result = rt_mq_recv(mqdes->mq, msg_ptr, msg_len, tick);
-	if (result == RT_EOK) return msg_len;
+    result = rt_mq_recv(mqdes->mq, msg_ptr, msg_len, tick);
+    if (result == RT_EOK)
+        return msg_len;
 
-	if (result == -RT_ETIMEOUT)
-		rt_set_errno(ETIMEDOUT);
-	else
-		rt_set_errno(EBADMSG);
+    if (result == -RT_ETIMEOUT)
+        rt_set_errno(ETIMEDOUT);
+    else
+        rt_set_errno(EBADMSG);
 
-	return -1;
+    return -1;
 }
 RTM_EXPORT(mq_timedreceive);
 
-int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio,
-		const struct timespec *abs_timeout)
+int mq_timedsend(mqd_t                  mqdes,
+                 const char            *msg_ptr,
+                 size_t                 msg_len,
+                 unsigned               msg_prio,
+                 const struct timespec *abs_timeout)
 {
-	/* RT-Thread does not support timed send */
-	return mq_send(mqdes, msg_ptr, msg_len, msg_prio);
+    /* RT-Thread does not support timed send */
+    return mq_send(mqdes, msg_ptr, msg_len, msg_prio);
 }
 RTM_EXPORT(mq_timedsend);
 
 int mq_notify(mqd_t mqdes, const struct sigevent *notification)
 {
-	rt_set_errno(-RT_ERROR);
-	return -1;
+    rt_set_errno(-RT_ERROR);
+
+    return -1;
 }
 RTM_EXPORT(mq_notify);
 
 int mq_close(mqd_t mqdes)
 {
-	if (mqdes == RT_NULL)
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+    if (mqdes == RT_NULL)
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
 
     /* lock posix mqueue list */
     rt_sem_take(&posix_mq_lock, RT_WAITING_FOREVER);
     mqdes->refcount --;
     if (mqdes->refcount == 0)
     {
-    	/* delete from posix mqueue list */
-    	if (mqdes->unlinked)
-    		posix_mq_delete(mqdes);
+        /* delete from posix mqueue list */
+        if (mqdes->unlinked)
+            posix_mq_delete(mqdes);
     }
     rt_sem_release(&posix_mq_lock);
 
@@ -274,26 +316,28 @@ RTM_EXPORT(mq_close);
 
 int mq_unlink(const char *name)
 {
-	mqd_t pmq;
+    mqd_t pmq;
 
     /* lock posix mqueue list */
     rt_sem_take(&posix_mq_lock, RT_WAITING_FOREVER);
     pmq = posix_mq_find(name);
     if (pmq != RT_NULL)
     {
-    	pmq->unlinked = 1;
-    	if (pmq->refcount == 0)
-    	{
-    		/* remove this mqueue */
-    		posix_mq_delete(pmq);
-    	}
+        pmq->unlinked = 1;
+        if (pmq->refcount == 0)
+        {
+            /* remove this mqueue */
+            posix_mq_delete(pmq);
+        }
         rt_sem_release(&posix_mq_lock);
+
         return 0;
     }
     rt_sem_release(&posix_mq_lock);
 
     /* no this entry */
     rt_set_errno(ENOENT);
+
     return -1;
 }
 RTM_EXPORT(mq_unlink);

+ 56 - 26
components/pthreads/mqueue.h

@@ -1,3 +1,26 @@
+/*
+ * File      : mqueue.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, 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
+ */
+
 #ifndef __MQUEUE_H__
 #define __MQUEUE_H__
 
@@ -6,38 +29,45 @@
 
 struct mqdes
 {
-	/* reference count and unlinked */
-	rt_uint16_t refcount;
-	rt_uint16_t unlinked;
-
-	/* RT-Thread message queue */
-	rt_mq_t mq;
-	/* next posix mqueue */
-	struct mqdes* next;
+    /* reference count and unlinked */
+    rt_uint16_t refcount;
+    rt_uint16_t unlinked;
+
+    /* RT-Thread message queue */
+    rt_mq_t mq;
+    /* next posix mqueue */
+    struct mqdes* next;
 };
 typedef struct mqdes* mqd_t;
 
 struct mq_attr
 {
-	long mq_flags; 		/* Message queue flags. */
-	long mq_maxmsg; 	/* Maximum number of messages. */
-	long mq_msgsize; 	/* Maximum message size. */
-	long mq_curmsgs; 	/* Number of messages currently queued. */
+    long mq_flags;      /* Message queue flags. */
+    long mq_maxmsg;     /* Maximum number of messages. */
+    long mq_msgsize;    /* Maximum message size. */
+    long mq_curmsgs;    /* Number of messages currently queued. */
 };
 
-int      mq_close(mqd_t mqdes);
-int      mq_getattr(mqd_t mqdes, struct mq_attr *mqstat);
-int      mq_notify(mqd_t mqdes, const struct sigevent *notification);
-mqd_t    mq_open(const char *name, int oflag, ...);
-ssize_t  mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio);
-int      mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);
-int      mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat,
-             struct mq_attr *omqstat);
-ssize_t  mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
-             unsigned *msg_prio, const struct timespec *abs_timeout);
-int      mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio,
-             const struct timespec *abs_timeout);
-
-int      mq_unlink(const char *name);
+int     mq_close(mqd_t mqdes);
+int     mq_getattr(mqd_t mqdes, struct mq_attr *mqstat);
+int     mq_notify(mqd_t mqdes, const struct sigevent *notification);
+mqd_t   mq_open(const char *name, int oflag, ...);
+ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio);
+int     mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);
+int     mq_setattr(mqd_t                 mqdes,
+                   const struct mq_attr *mqstat,
+                   struct mq_attr       *omqstat);
+ssize_t mq_timedreceive(mqd_t                  mqdes,
+                        char                  *msg_ptr,
+                        size_t                 msg_len,
+                        unsigned              *msg_prio,
+                        const struct timespec *abs_timeout);
+int     mq_timedsend(mqd_t                  mqdes,
+                     const char            *msg_ptr,
+                     size_t                 msg_len,
+                     unsigned               msg_prio,
+                     const struct timespec *abs_timeout);
+
+int     mq_unlink(const char *name);
 
 #endif

+ 176 - 151
components/pthreads/posix_types.h

@@ -1,3 +1,26 @@
+/*
+ * File      : posix_types.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, 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
+ */
+
 #ifndef __POSIX_TYPES_H__
 #define __POSIX_TYPES_H__
 
@@ -19,177 +42,179 @@
 #else
 
 /* ARM compiler and IAR compiler */
-#if defined(__CC_ARM) || defined(__IAR_SYSTEMS_ICC__)	
+#if defined(__CC_ARM) || defined(__IAR_SYSTEMS_ICC__)   
 #include <stddef.h>
 #include <stdarg.h>
 #include <string.h>
 
 typedef rt_int32_t clockid_t;
-typedef rt_int32_t key_t;		/* Used for interprocess communication. */
-typedef rt_int32_t pid_t;		/* Used for process IDs and process group IDs. */
-typedef signed long ssize_t;	/* Used for a count of bytes or an error indication. */
-typedef signed long time_t;		/* Used for time in seconds. */
+typedef rt_int32_t key_t;       /* Used for interprocess communication. */
+typedef rt_int32_t pid_t;       /* Used for process IDs and process group IDs. */
+typedef signed long ssize_t;    /* Used for a count of bytes or an error indication. */
+typedef signed long time_t;     /* Used for time in seconds. */
 
-struct timespec {
-	time_t tv_sec;			/* seconds */
-	long tv_nsec;			/* nanoseconds */
+struct timespec
+{
+    time_t tv_sec;          /* seconds */
+    long tv_nsec;           /* nanoseconds */
 };
 
-struct timeval {
+struct timeval
+{
     long    tv_sec;         /* seconds */
     long    tv_usec;        /* microseconds */
 };
 
 /* errno definitions */
-#define EPERM		 1	/* Operation not permitted */
-#define ENOENT		 2	/* No such file or directory */
-#define ESRCH		 3	/* No such process */
-#define EINTR		 4	/* Interrupted system call */
-#define EIO			 5	/* I/O error */
-#define ENXIO		 6	/* No such device or address */
-#define E2BIG		 7	/* Arg list too long */
-#define ENOEXEC		 8	/* Exec format error */
-#define EBADF		 9	/* Bad file number */
-#define ECHILD		10	/* No child processes */
-#define EAGAIN		11	/* Try again */
-#define ENOMEM		12	/* Out of memory */
-#define EACCES		13	/* Permission denied */
-#define EFAULT		14	/* Bad address */
-#define ENOTBLK		15	/* Block device required */
-#define EBUSY		16	/* Device or resource busy */
-#define EEXIST		17	/* File exists */
-#define EXDEV		18	/* Cross-device link */
-#define ENODEV		19	/* No such device */
-#define ENOTDIR		20	/* Not a directory */
-#define EISDIR		21	/* Is a directory */
-#define EINVAL		22	/* Invalid argument */
-#define ENFILE		23	/* File table overflow */
-#define EMFILE		24	/* Too many open files */
-#define ENOTTY		25	/* Not a typewriter */
-#define ETXTBSY		26	/* Text file busy */
-#define EFBIG		27	/* File too large */
-#define ENOSPC		28	/* No space left on device */
-#define ESPIPE		29	/* Illegal seek */
-#define EROFS		30	/* Read-only file system */
-#define EMLINK		31	/* Too many links */
-#define EPIPE		32	/* Broken pipe */
-#define EDOM		33	/* Math argument out of domain of func */
-#define ERANGE		34	/* Math result not representable */
-#define ENOMSG		35	/* No message of desired type */
-#define EIDRM		36	/* Identifier removed */
-#define ECHRNG		37	/* Channel number out of range */
-#define EL2NSYNC	38	/* Level 2 not synchronized */
-#define EL3HLT		39	/* Level 3 halted */
-#define EL3RST		40	/* Level 3 reset */
-#define ELNRNG		41	/* Link number out of range */
-#define EUNATCH		42	/* Protocol driver not attached */
-#define ENOCSI		43	/* No CSI structure available */
-#define EL2HLT		44	/* Level 2 halted */
-#define EDEADLK		45	/* Resource deadlock would occur */
-#define ENOLCK		46	/* No record locks available */
-#define EBADE		50	/* Invalid exchange */
-#define EBADR		51	/* Invalid request descriptor */
-#define EXFULL		52	/* Exchange full */
-#define ENOANO		53	/* No anode */
-#define EBADRQC		54	/* Invalid request code */
-#define EBADSLT		55	/* Invalid slot */
-#define EDEADLOCK	56	/* File locking deadlock error */
-#define EBFONT		59	/* Bad font file format */
-#define ENOSTR		60	/* Device not a stream */
-#define ENODATA		61	/* No data available */
-#define ETIME		62	/* Timer expired */
-#define ENOSR		63	/* Out of streams resources */
-#define ENONET		64	/* Machine is not on the network */
-#define ENOPKG		65	/* Package not installed */
-#define EREMOTE		66	/* Object is remote */
-#define ENOLINK		67	/* Link has been severed */
-#define EADV		68	/* Advertise error */
-#define ESRMNT		69	/* Srmount error */
-#define ECOMM		70	/* Communication error on send */
-#define EPROTO		71	/* Protocol error */
-#define EDOTDOT		73	/* RFS specific error */
-#define EMULTIHOP	74	/* Multihop attempted */
-#define EBADMSG		77	/* Not a data message */
-#define ENAMETOOLONG	78	/* File name too long */
-#define EOVERFLOW	79	/* Value too large for defined data type */
-#define ENOTUNIQ	80	/* Name not unique on network */
-#define EBADFD		81	/* File descriptor in bad state */
-#define EREMCHG		82	/* Remote address changed */
-#define ELIBACC		83	/* Can not access a needed shared library */
-#define ELIBBAD		84	/* Accessing a corrupted shared library */
-#define ELIBSCN		85	/* .lib section in a.out corrupted */
-#define ELIBMAX		86	/* Attempting to link in too many shared libraries */
-#define ELIBEXEC	87	/* Cannot exec a shared library directly */
-#define EILSEQ		88	/* Illegal byte sequence */
-#define ENOSYS		89	/* Function not implemented */
-#define ELOOP		90	/* Too many symbolic links encountered */
-#define ERESTART	91	/* Interrupted system call should be restarted */
-#define ESTRPIPE	92	/* Streams pipe error */
-#define ENOTEMPTY	93	/* Directory not empty */
-#define EUSERS		94	/* Too many users */
-#define ENOTSOCK	95	/* Socket operation on non-socket */
-#define EDESTADDRREQ	96	/* Destination address required */
-#define EMSGSIZE	97	/* Message too long */
-#define EPROTOTYPE	98	/* Protocol wrong type for socket */
-#define ENOPROTOOPT	99	/* Protocol not available */
-#define EPROTONOSUPPORT	120	/* Protocol not supported */
-#define ESOCKTNOSUPPORT	121	/* Socket type not supported */
-#define EOPNOTSUPP	122	/* Operation not supported on transport endpoint */
-#define ENOTSUP		EOPNOTSUPP/* Operation not supported on transport endpoint */
-#define EPFNOSUPPORT	123	/* Protocol family not supported */
-#define EAFNOSUPPORT	124	/* Address family not supported by protocol */
-#define EADDRINUSE	125	/* Address already in use */
-#define EADDRNOTAVAIL	126	/* Cannot assign requested address */
-#define ENETDOWN	127	/* Network is down */
-#define ENETUNREACH	128	/* Network is unreachable */
-#define ENETRESET	129	/* Network dropped connection because of reset */
-#define ECONNABORTED	130	/* Software caused connection abort */
-#define ECONNRESET	131	/* Connection reset by peer */
-#define ENOBUFS		132	/* No buffer space available */
-#define EISCONN		133	/* Transport endpoint is already connected */
-#define ENOTCONN	134	/* Transport endpoint is not connected */
-#define EUCLEAN		135	/* Structure needs cleaning */
-#define ENOTNAM		137	/* Not a XENIX named type file */
-#define ENAVAIL		138	/* No XENIX semaphores available */
-#define EISNAM		139	/* Is a named type file */
-#define EREMOTEIO	140	/* Remote I/O error */
-#define EINIT		141	/* Reserved */
-#define EREMDEV		142	/* Error 142 */
-#define ESHUTDOWN	143	/* Cannot send after transport endpoint shutdown */
-#define ETOOMANYREFS	144	/* Too many references: cannot splice */
-#define ETIMEDOUT	145	/* Connection timed out */
-#define ECONNREFUSED	146	/* Connection refused */
-#define EHOSTDOWN	147	/* Host is down */
-#define EHOSTUNREACH	148	/* No route to host */
-#define EWOULDBLOCK	EAGAIN	/* Operation would block */
-#define EALREADY	149	/* Operation already in progress */
-#define EINPROGRESS	150	/* Operation now in progress */
-#define ESTALE		151	/* Stale NFS file handle */
-#define ECANCELED	158	/* AIO operation canceled */
-#define ENOMEDIUM	159	/* No medium found */
-#define EMEDIUMTYPE	160	/* Wrong medium type */
-#define	ENOKEY		161	/* Required key not available */
-#define	EKEYEXPIRED	162	/* Key has expired */
-#define	EKEYREVOKED	163	/* Key has been revoked */
-#define	EKEYREJECTED	164	/* Key was rejected by service */
-#define EDQUOT		1133	/* Quota exceeded */
+#define EPERM        1  /* Operation not permitted */
+#define ENOENT       2  /* No such file or directory */
+#define ESRCH        3  /* No such process */
+#define EINTR        4  /* Interrupted system call */
+#define EIO          5  /* I/O error */
+#define ENXIO        6  /* No such device or address */
+#define E2BIG        7  /* Arg list too long */
+#define ENOEXEC      8  /* Exec format error */
+#define EBADF        9  /* Bad file number */
+#define ECHILD      10  /* No child processes */
+#define EAGAIN      11  /* Try again */
+#define ENOMEM      12  /* Out of memory */
+#define EACCES      13  /* Permission denied */
+#define EFAULT      14  /* Bad address */
+#define ENOTBLK     15  /* Block device required */
+#define EBUSY       16  /* Device or resource busy */
+#define EEXIST      17  /* File exists */
+#define EXDEV       18  /* Cross-device link */
+#define ENODEV      19  /* No such device */
+#define ENOTDIR     20  /* Not a directory */
+#define EISDIR      21  /* Is a directory */
+#define EINVAL      22  /* Invalid argument */
+#define ENFILE      23  /* File table overflow */
+#define EMFILE      24  /* Too many open files */
+#define ENOTTY      25  /* Not a typewriter */
+#define ETXTBSY     26  /* Text file busy */
+#define EFBIG       27  /* File too large */
+#define ENOSPC      28  /* No space left on device */
+#define ESPIPE      29  /* Illegal seek */
+#define EROFS       30  /* Read-only file system */
+#define EMLINK      31  /* Too many links */
+#define EPIPE       32  /* Broken pipe */
+#define EDOM        33  /* Math argument out of domain of func */
+#define ERANGE      34  /* Math result not representable */
+#define ENOMSG      35  /* No message of desired type */
+#define EIDRM       36  /* Identifier removed */
+#define ECHRNG      37  /* Channel number out of range */
+#define EL2NSYNC    38  /* Level 2 not synchronized */
+#define EL3HLT      39  /* Level 3 halted */
+#define EL3RST      40  /* Level 3 reset */
+#define ELNRNG      41  /* Link number out of range */
+#define EUNATCH     42  /* Protocol driver not attached */
+#define ENOCSI      43  /* No CSI structure available */
+#define EL2HLT      44  /* Level 2 halted */
+#define EDEADLK     45  /* Resource deadlock would occur */
+#define ENOLCK      46  /* No record locks available */
+#define EBADE       50  /* Invalid exchange */
+#define EBADR       51  /* Invalid request descriptor */
+#define EXFULL      52  /* Exchange full */
+#define ENOANO      53  /* No anode */
+#define EBADRQC     54  /* Invalid request code */
+#define EBADSLT     55  /* Invalid slot */
+#define EDEADLOCK   56  /* File locking deadlock error */
+#define EBFONT      59  /* Bad font file format */
+#define ENOSTR      60  /* Device not a stream */
+#define ENODATA     61  /* No data available */
+#define ETIME       62  /* Timer expired */
+#define ENOSR       63  /* Out of streams resources */
+#define ENONET      64  /* Machine is not on the network */
+#define ENOPKG      65  /* Package not installed */
+#define EREMOTE     66  /* Object is remote */
+#define ENOLINK     67  /* Link has been severed */
+#define EADV        68  /* Advertise error */
+#define ESRMNT      69  /* Srmount error */
+#define ECOMM       70  /* Communication error on send */
+#define EPROTO      71  /* Protocol error */
+#define EDOTDOT     73  /* RFS specific error */
+#define EMULTIHOP   74  /* Multihop attempted */
+#define EBADMSG     77  /* Not a data message */
+#define ENAMETOOLONG    78  /* File name too long */
+#define EOVERFLOW   79  /* Value too large for defined data type */
+#define ENOTUNIQ    80  /* Name not unique on network */
+#define EBADFD      81  /* File descriptor in bad state */
+#define EREMCHG     82  /* Remote address changed */
+#define ELIBACC     83  /* Can not access a needed shared library */
+#define ELIBBAD     84  /* Accessing a corrupted shared library */
+#define ELIBSCN     85  /* .lib section in a.out corrupted */
+#define ELIBMAX     86  /* Attempting to link in too many shared libraries */
+#define ELIBEXEC    87  /* Cannot exec a shared library directly */
+#define EILSEQ      88  /* Illegal byte sequence */
+#define ENOSYS      89  /* Function not implemented */
+#define ELOOP       90  /* Too many symbolic links encountered */
+#define ERESTART    91  /* Interrupted system call should be restarted */
+#define ESTRPIPE    92  /* Streams pipe error */
+#define ENOTEMPTY   93  /* Directory not empty */
+#define EUSERS      94  /* Too many users */
+#define ENOTSOCK    95  /* Socket operation on non-socket */
+#define EDESTADDRREQ    96  /* Destination address required */
+#define EMSGSIZE    97  /* Message too long */
+#define EPROTOTYPE  98  /* Protocol wrong type for socket */
+#define ENOPROTOOPT 99  /* Protocol not available */
+#define EPROTONOSUPPORT 120 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 121 /* Socket type not supported */
+#define EOPNOTSUPP  122 /* Operation not supported on transport endpoint */
+#define ENOTSUP     EOPNOTSUPP/* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT    123 /* Protocol family not supported */
+#define EAFNOSUPPORT    124 /* Address family not supported by protocol */
+#define EADDRINUSE  125 /* Address already in use */
+#define EADDRNOTAVAIL   126 /* Cannot assign requested address */
+#define ENETDOWN    127 /* Network is down */
+#define ENETUNREACH 128 /* Network is unreachable */
+#define ENETRESET   129 /* Network dropped connection because of reset */
+#define ECONNABORTED    130 /* Software caused connection abort */
+#define ECONNRESET  131 /* Connection reset by peer */
+#define ENOBUFS     132 /* No buffer space available */
+#define EISCONN     133 /* Transport endpoint is already connected */
+#define ENOTCONN    134 /* Transport endpoint is not connected */
+#define EUCLEAN     135 /* Structure needs cleaning */
+#define ENOTNAM     137 /* Not a XENIX named type file */
+#define ENAVAIL     138 /* No XENIX semaphores available */
+#define EISNAM      139 /* Is a named type file */
+#define EREMOTEIO   140 /* Remote I/O error */
+#define EINIT       141 /* Reserved */
+#define EREMDEV     142 /* Error 142 */
+#define ESHUTDOWN   143 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS    144 /* Too many references: cannot splice */
+#define ETIMEDOUT   145 /* Connection timed out */
+#define ECONNREFUSED    146 /* Connection refused */
+#define EHOSTDOWN   147 /* Host is down */
+#define EHOSTUNREACH    148 /* No route to host */
+#define EWOULDBLOCK EAGAIN  /* Operation would block */
+#define EALREADY    149 /* Operation already in progress */
+#define EINPROGRESS 150 /* Operation now in progress */
+#define ESTALE      151 /* Stale NFS file handle */
+#define ECANCELED   158 /* AIO operation canceled */
+#define ENOMEDIUM   159 /* No medium found */
+#define EMEDIUMTYPE 160 /* Wrong medium type */
+#define ENOKEY      161 /* Required key not available */
+#define EKEYEXPIRED 162 /* Key has expired */
+#define EKEYREVOKED 163 /* Key has been revoked */
+#define EKEYREJECTED    164 /* Key was rejected by service */
+#define EDQUOT      1133    /* Quota exceeded */
 
 #ifdef RT_USING_DFS
 #include <dfs_posix.h>
 #else
 typedef rt_uint16_t mode_t;
-#define O_RDONLY		0x0000000
-#define O_WRONLY		0x0000001
-#define O_RDWR			0x0000002
-#define O_ACCMODE		0x0000003
-#define O_CREAT			0x0000100
-#define O_EXCL			0x0000200
-#define O_TRUNC			0x0001000
-#define O_APPEND		0x0002000
-#define O_DIRECTORY		0x0200000
+#define O_RDONLY        0x0000000
+#define O_WRONLY        0x0000001
+#define O_RDWR          0x0000002
+#define O_ACCMODE       0x0000003
+#define O_CREAT         0x0000100
+#define O_EXCL          0x0000200
+#define O_TRUNC         0x0001000
+#define O_APPEND        0x0002000
+#define O_DIRECTORY     0x0200000
 #endif
 
-#elif defined (__GNUC__)        			/* GNU GCC Compiler, with minilibc */
+#elif defined (__GNUC__)                    /* GNU GCC Compiler, with minilibc */
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/stat.h>

+ 404 - 356
components/pthreads/pthread.c

@@ -1,366 +1,409 @@
+/*
+ * File      : pthread.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, 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
+ */
+
 #include <pthread.h>
 #include <sched.h>
 #include "pthread_internal.h"
 
 int pthread_system_init(void)
 {
-	/* initialize clock and time */
-	clock_time_system_init();
+    /* initialize clock and time */
+    clock_time_system_init();
 
-	/* initialize key area */
-	pthread_key_system_init();
-	/* initialize posix mqueue */
-	posix_mq_system_init();
-	/* initialize posix semaphore */
-	posix_sem_system_init();
+    /* initialize key area */
+    pthread_key_system_init();
+    /* initialize posix mqueue */
+    posix_mq_system_init();
+    /* initialize posix semaphore */
+    posix_sem_system_init();
 
-	return 0;
+    return 0;
 }
 
 static void _pthread_cleanup(rt_thread_t tid)
 {
-	_pthread_data_t *ptd;
-	ptd = _pthread_get_data(tid);
-
-	/* clear cleanup function */
-	tid->cleanup = RT_NULL;
-	if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE)
-	{
-		rt_sem_release(ptd->joinable_sem);
-	}
-	else
-	{
-		/* release pthread resource */
-		pthread_detach(tid);
-	}
+    _pthread_data_t *ptd;
+    ptd = _pthread_get_data(tid);
+
+    /* clear cleanup function */
+    tid->cleanup = RT_NULL;
+    if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE)
+    {
+        rt_sem_release(ptd->joinable_sem);
+    }
+    else
+    {
+        /* release pthread resource */
+        pthread_detach(tid);
+    }
 }
 
-static void pthread_entry_stub(void* parameter)
+static void pthread_entry_stub(void *parameter)
 {
-	_pthread_data_t *ptd;
-	void* value;
+    _pthread_data_t *ptd;
+    void *value;
 
-	ptd = (_pthread_data_t*)parameter;
+    ptd = (_pthread_data_t*)parameter;
 
-	/* execute pthread entry */
-	value = ptd->thread_entry(ptd->thread_parameter);
-	/* set value */
-	ptd->return_value = value;
+    /* execute pthread entry */
+    value = ptd->thread_entry(ptd->thread_parameter);
+    /* set value */
+    ptd->return_value = value;
 }
 
-int pthread_create (pthread_t *tid, const pthread_attr_t *attr, 
-	void *(*start) (void *), void *parameter)
+int pthread_create(pthread_t            *tid,
+                   const pthread_attr_t *attr, 
+                   void *(*start) (void *), void *parameter)
 {
-	int result;
-	void* stack;
-	char name[RT_NAME_MAX];
-	static rt_uint16_t pthread_number = 0;
-	_pthread_data_t *ptd;
-
-	/* tid shall be provided */
-	RT_ASSERT(tid != RT_NULL);
-
-	/* allocate posix thread data */
-	ptd = (_pthread_data_t*)rt_malloc(sizeof(_pthread_data_t));
-	if (ptd == RT_NULL) return ENOMEM;
-	/* clean posix thread data memory */
-	rt_memset(ptd, 0, sizeof(_pthread_data_t));
-	ptd->canceled = 0;
-	ptd->cancelstate = PTHREAD_CANCEL_DISABLE;
-	ptd->canceltype = PTHREAD_CANCEL_DEFERRED;
-	ptd->magic = PTHREAD_MAGIC;
-
-	if (attr != RT_NULL) ptd->attr = *attr;
-	else 
-	{
-		/* use default attribute */
-		pthread_attr_init(&ptd->attr);
-	}
-
-	rt_snprintf(name, sizeof(name), "pth%02d", pthread_number ++);
-	if (ptd->attr.stack_base == 0)
-	{
-		stack = (void*)rt_malloc(ptd->attr.stack_size);
-	}
-	else stack = (void*)(ptd->attr.stack_base);
-
-	if (stack == RT_NULL) 
-	{
-		rt_free(ptd);
-		return ENOMEM;
-	}
-
-	/* pthread is a static thread object */
-	ptd->tid = (rt_thread_t) rt_malloc(sizeof(struct rt_thread));
-	if (ptd->tid == RT_NULL)
-	{
-		if (ptd->attr.stack_base ==0) rt_free(stack);
-		rt_free(ptd);
-		return ENOMEM;
-	}
-
-	if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE)
-	{
-		ptd->joinable_sem = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO);
-		if (ptd->joinable_sem == RT_NULL)
-		{
-			if (ptd->attr.stack_base !=0) rt_free(stack);
-			rt_free(ptd);
-			return ENOMEM;
-		}
-	}
-	else ptd->joinable_sem = RT_NULL;
-
-	/* set parameter */
-	ptd->thread_entry = start;
-	ptd->thread_parameter = parameter;
-
-	/* initial this pthread to system */
-	if (rt_thread_init(ptd->tid, name, pthread_entry_stub, ptd, 
-		stack, ptd->attr.stack_size, 
-		ptd->attr.priority, 5) != RT_EOK)
-	{
-		if (ptd->attr.stack_base ==0) rt_free(stack);
-		if (ptd->joinable_sem != RT_NULL) rt_sem_delete(ptd->joinable_sem);
-		rt_free(ptd);
-		return EINVAL;
-	}
-
-	/* set pthread id */
-	*tid = ptd->tid;
-
-	/* set pthread cleanup function and ptd data */
-	(*tid)->cleanup = _pthread_cleanup;
-	(*tid)->user_data = (rt_uint32_t)ptd;
-
-	/* start thread */
-	result = rt_thread_startup(*tid);
-	if (result == RT_EOK) return 0;
-
-	/* start thread failed */
-	rt_thread_detach(ptd->tid);
-	if (ptd->attr.stack_base ==0) rt_free(stack);
-	if (ptd->joinable_sem != RT_NULL) rt_sem_delete(ptd->joinable_sem);
-
-	rt_free(ptd);
-	return EINVAL;
+    int result;
+    void *stack;
+    char name[RT_NAME_MAX];
+    static rt_uint16_t pthread_number = 0;
+    _pthread_data_t *ptd;
+
+    /* tid shall be provided */
+    RT_ASSERT(tid != RT_NULL);
+
+    /* allocate posix thread data */
+    ptd = (_pthread_data_t*)rt_malloc(sizeof(_pthread_data_t));
+    if (ptd == RT_NULL)
+        return ENOMEM;
+    /* clean posix thread data memory */
+    rt_memset(ptd, 0, sizeof(_pthread_data_t));
+    ptd->canceled = 0;
+    ptd->cancelstate = PTHREAD_CANCEL_DISABLE;
+    ptd->canceltype = PTHREAD_CANCEL_DEFERRED;
+    ptd->magic = PTHREAD_MAGIC;
+
+    if (attr != RT_NULL)
+        ptd->attr = *attr;
+    else 
+    {
+        /* use default attribute */
+        pthread_attr_init(&ptd->attr);
+    }
+
+    rt_snprintf(name, sizeof(name), "pth%02d", pthread_number ++);
+    if (ptd->attr.stack_base == 0)
+    {
+        stack = (void*)rt_malloc(ptd->attr.stack_size);
+    }
+    else
+        stack = (void*)(ptd->attr.stack_base);
+
+    if (stack == RT_NULL) 
+    {
+        rt_free(ptd);
+
+        return ENOMEM;
+    }
+
+    /* pthread is a static thread object */
+    ptd->tid = (rt_thread_t) rt_malloc(sizeof(struct rt_thread));
+    if (ptd->tid == RT_NULL)
+    {
+        if (ptd->attr.stack_base == 0)
+            rt_free(stack);
+        rt_free(ptd);
+
+        return ENOMEM;
+    }
+
+    if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE)
+    {
+        ptd->joinable_sem = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO);
+        if (ptd->joinable_sem == RT_NULL)
+        {
+            if (ptd->attr.stack_base != 0)
+                rt_free(stack);
+            rt_free(ptd);
+
+            return ENOMEM;
+        }
+    }
+    else
+        ptd->joinable_sem = RT_NULL;
+
+    /* set parameter */
+    ptd->thread_entry = start;
+    ptd->thread_parameter = parameter;
+
+    /* initial this pthread to system */
+    if (rt_thread_init(ptd->tid, name, pthread_entry_stub, ptd, 
+        stack, ptd->attr.stack_size, 
+        ptd->attr.priority, 5) != RT_EOK)
+    {
+        if (ptd->attr.stack_base == 0)
+            rt_free(stack);
+        if (ptd->joinable_sem != RT_NULL)
+            rt_sem_delete(ptd->joinable_sem);
+        rt_free(ptd);
+
+        return EINVAL;
+    }
+
+    /* set pthread id */
+    *tid = ptd->tid;
+
+    /* set pthread cleanup function and ptd data */
+    (*tid)->cleanup = _pthread_cleanup;
+    (*tid)->user_data = (rt_uint32_t)ptd;
+
+    /* start thread */
+    result = rt_thread_startup(*tid);
+    if (result == RT_EOK)
+        return 0;
+
+    /* start thread failed */
+    rt_thread_detach(ptd->tid);
+    if (ptd->attr.stack_base == 0)
+        rt_free(stack);
+    if (ptd->joinable_sem != RT_NULL)
+        rt_sem_delete(ptd->joinable_sem);
+
+    rt_free(ptd);
+
+    return EINVAL;
 }
 RTM_EXPORT(pthread_create);
 
 int pthread_detach(pthread_t thread)
 {
-	_pthread_data_t* ptd;
-
-	ptd = _pthread_get_data(thread);
-
-	if (thread->stat == RT_THREAD_CLOSE)
-	{
-		/* delete joinable semaphore */
-		if (ptd->joinable_sem != RT_NULL)
-			rt_sem_delete(ptd->joinable_sem);
-		/* detach thread object */
-		rt_thread_detach(ptd->tid);
-
-		/* release thread resource */
-		if (ptd->attr.stack_base == RT_NULL)
-		{
-			/* release thread allocated stack */
-			rt_free(ptd->tid->stack_addr);
-		}
-
-		/*
-		 * if this thread create the local thread data,
-		 * delete it
-		 */
-		if (ptd->tls != RT_NULL) rt_free(ptd->tls);
-		rt_free(ptd->tid);
-		rt_free(ptd);
-	}
-	else
-	{
-		rt_enter_critical();
-		/* change to detach state */
-		ptd->attr.detachstate = PTHREAD_CREATE_DETACHED;
-
-		/* detach joinable semaphore */
-		rt_sem_delete(ptd->joinable_sem);
-		ptd->joinable_sem = RT_NULL;
-		rt_exit_critical();
-	}
-
-	return 0;
+    _pthread_data_t* ptd;
+
+    ptd = _pthread_get_data(thread);
+
+    if (thread->stat == RT_THREAD_CLOSE)
+    {
+        /* delete joinable semaphore */
+        if (ptd->joinable_sem != RT_NULL)
+            rt_sem_delete(ptd->joinable_sem);
+        /* detach thread object */
+        rt_thread_detach(ptd->tid);
+
+        /* release thread resource */
+        if (ptd->attr.stack_base == RT_NULL)
+        {
+            /* release thread allocated stack */
+            rt_free(ptd->tid->stack_addr);
+        }
+
+        /*
+         * if this thread create the local thread data,
+         * delete it
+         */
+        if (ptd->tls != RT_NULL)
+            rt_free(ptd->tls);
+        rt_free(ptd->tid);
+        rt_free(ptd);
+    }
+    else
+    {
+        rt_enter_critical();
+        /* change to detach state */
+        ptd->attr.detachstate = PTHREAD_CREATE_DETACHED;
+
+        /* detach joinable semaphore */
+        rt_sem_delete(ptd->joinable_sem);
+        ptd->joinable_sem = RT_NULL;
+        rt_exit_critical();
+    }
+
+    return 0;
 }
 RTM_EXPORT(pthread_detach);
 
 int pthread_join (pthread_t thread, void **value_ptr)
 {
-	_pthread_data_t* ptd;
-	rt_err_t result;
-
-	if (thread == rt_thread_self())
-	{
-		/* join self */
-		return EDEADLK;
-	}
-
-	ptd = _pthread_get_data(thread);
-	if (ptd->attr.detachstate == PTHREAD_CREATE_DETACHED)
-		return EINVAL; /* join on a detached pthread */
-
-	result = rt_sem_take(ptd->joinable_sem, RT_WAITING_FOREVER);
-	if (result == RT_EOK)
-	{
-		/* get return value */
-		if (value_ptr != RT_NULL) *value_ptr = ptd->return_value;
-
-		/* release resource */
-		pthread_detach(thread);
-	}
-	else return ESRCH;
-	
-	return 0;
+    _pthread_data_t* ptd;
+    rt_err_t result;
+
+    if (thread == rt_thread_self())
+    {
+        /* join self */
+        return EDEADLK;
+    }
+
+    ptd = _pthread_get_data(thread);
+    if (ptd->attr.detachstate == PTHREAD_CREATE_DETACHED)
+        return EINVAL; /* join on a detached pthread */
+
+    result = rt_sem_take(ptd->joinable_sem, RT_WAITING_FOREVER);
+    if (result == RT_EOK)
+    {
+        /* get return value */
+        if (value_ptr != RT_NULL)
+            *value_ptr = ptd->return_value;
+
+        /* release resource */
+        pthread_detach(thread);
+    }
+    else
+        return ESRCH;
+    
+    return 0;
 }
 RTM_EXPORT(pthread_join);
 
-void pthread_exit (void* value)
+void pthread_exit (void *value)
 {
-	_pthread_data_t* ptd;
-	_pthread_cleanup_t* cleanup;
-	extern _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX];
-
-	ptd = _pthread_get_data(rt_thread_self());
-
-	rt_enter_critical();
-	/* disable cancel */
-	ptd->cancelstate = PTHREAD_CANCEL_DISABLE;
-	/* set return value */
-	ptd->return_value = value;
-	rt_exit_critical();
-
-	/* invoke pushed cleanup */
-	while (ptd->cleanup != RT_NULL)
-	{
-		cleanup = ptd->cleanup;
-		ptd->cleanup = cleanup->next;
-
-		cleanup->cleanup_func(cleanup->parameter);
-		/* release this cleanup function */
-		rt_free(cleanup);
-	}
-
-	/* destruct thread local key */
-	if (ptd->tls != RT_NULL)
-	{
-		void* data;
-		rt_uint32_t index;
-		
-		for (index = 0; index < PTHREAD_KEY_MAX; index ++)
-		{
-			if (_thread_keys[index].is_used)
-			{
-				data = ptd->tls[index];
-				if (data)
-					_thread_keys[index].destructor(data);
-			}
-		}
-
-		/* release tls area */
-		rt_free(ptd->tls);
-		ptd->tls = RT_NULL;
-	}
-
-	if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE)
-	{
-		/* release the joinable pthread */
-		rt_sem_release(ptd->joinable_sem);
-	}
-
-	/* detach thread */
-	rt_thread_detach(ptd->tid);
-	/* reschedule thread */
-	rt_schedule();
+    _pthread_data_t *ptd;
+    _pthread_cleanup_t *cleanup;
+    extern _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX];
+
+    ptd = _pthread_get_data(rt_thread_self());
+
+    rt_enter_critical();
+    /* disable cancel */
+    ptd->cancelstate = PTHREAD_CANCEL_DISABLE;
+    /* set return value */
+    ptd->return_value = value;
+    rt_exit_critical();
+
+    /* invoke pushed cleanup */
+    while (ptd->cleanup != RT_NULL)
+    {
+        cleanup = ptd->cleanup;
+        ptd->cleanup = cleanup->next;
+
+        cleanup->cleanup_func(cleanup->parameter);
+        /* release this cleanup function */
+        rt_free(cleanup);
+    }
+
+    /* destruct thread local key */
+    if (ptd->tls != RT_NULL)
+    {
+        void *data;
+        rt_uint32_t index;
+        
+        for (index = 0; index < PTHREAD_KEY_MAX; index ++)
+        {
+            if (_thread_keys[index].is_used)
+            {
+                data = ptd->tls[index];
+                if (data)
+                    _thread_keys[index].destructor(data);
+            }
+        }
+
+        /* release tls area */
+        rt_free(ptd->tls);
+        ptd->tls = RT_NULL;
+    }
+
+    if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE)
+    {
+        /* release the joinable pthread */
+        rt_sem_release(ptd->joinable_sem);
+    }
+
+    /* detach thread */
+    rt_thread_detach(ptd->tid);
+    /* reschedule thread */
+    rt_schedule();
 }
 RTM_EXPORT(pthread_exit);
 
-int pthread_once(pthread_once_t * once_control, void (*init_routine) (void))
+int pthread_once(pthread_once_t *once_control, void (*init_routine) (void))
 {
-	RT_ASSERT(once_control != RT_NULL);
-	RT_ASSERT(init_routine != RT_NULL);
+    RT_ASSERT(once_control != RT_NULL);
+    RT_ASSERT(init_routine != RT_NULL);
 
-	rt_enter_critical();
-	if (!(*once_control))
-	{
-		/* call routine once */
-		*once_control = 1;
-		rt_exit_critical();
+    rt_enter_critical();
+    if (!(*once_control))
+    {
+        /* call routine once */
+        *once_control = 1;
+        rt_exit_critical();
 
-		init_routine();
-	}
-	rt_exit_critical();
+        init_routine();
+    }
+    rt_exit_critical();
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_once);
 
 int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
 {
-	return ENOTSUP;
+    return ENOTSUP;
 }
 RTM_EXPORT(pthread_atfork);
 
 int pthread_kill(pthread_t thread, int sig)
 {
-	return ENOTSUP;
+    return ENOTSUP;
 }
 RTM_EXPORT(pthread_kill);
 
 void pthread_cleanup_pop(int execute)
 {
-	_pthread_data_t* ptd;
-	_pthread_cleanup_t* cleanup;
-
-	/* get posix thread data */
-	ptd = _pthread_get_data(rt_thread_self());
-	RT_ASSERT(ptd != RT_NULL);
-
-	if (execute)
-	{
-		rt_enter_critical();
-		cleanup = ptd->cleanup;
-		if (cleanup)
-			ptd->cleanup = cleanup->next;
-		rt_exit_critical();
-
-		if (cleanup)
-		{
-			cleanup->cleanup_func(cleanup->parameter);
-
-			rt_free(cleanup);
-		}
-	}
+    _pthread_data_t *ptd;
+    _pthread_cleanup_t *cleanup;
+
+    /* get posix thread data */
+    ptd = _pthread_get_data(rt_thread_self());
+    RT_ASSERT(ptd != RT_NULL);
+
+    if (execute)
+    {
+        rt_enter_critical();
+        cleanup = ptd->cleanup;
+        if (cleanup)
+            ptd->cleanup = cleanup->next;
+        rt_exit_critical();
+
+        if (cleanup)
+        {
+            cleanup->cleanup_func(cleanup->parameter);
+
+            rt_free(cleanup);
+        }
+    }
 }
 RTM_EXPORT(pthread_cleanup_pop);
 
 void pthread_cleanup_push(void (*routine)(void*), void *arg)
 {
-	_pthread_data_t* ptd;
-	_pthread_cleanup_t* cleanup;
-
-	/* get posix thread data */
-	ptd = _pthread_get_data(rt_thread_self());
-	RT_ASSERT(ptd != RT_NULL);
-
-	cleanup = (_pthread_cleanup_t*)rt_malloc(sizeof(_pthread_cleanup_t));
-	if (cleanup != RT_NULL)
-	{
-		cleanup->cleanup_func = routine;
-		cleanup->parameter = arg;
-
-		rt_enter_critical();
-		cleanup->next = ptd->cleanup;
-		ptd->cleanup = cleanup;
-		rt_exit_critical();
-	}
+    _pthread_data_t *ptd;
+    _pthread_cleanup_t *cleanup;
+
+    /* get posix thread data */
+    ptd = _pthread_get_data(rt_thread_self());
+    RT_ASSERT(ptd != RT_NULL);
+
+    cleanup = (_pthread_cleanup_t *)rt_malloc(sizeof(_pthread_cleanup_t));
+    if (cleanup != RT_NULL)
+    {
+        cleanup->cleanup_func = routine;
+        cleanup->parameter = arg;
+
+        rt_enter_critical();
+        cleanup->next = ptd->cleanup;
+        ptd->cleanup = cleanup;
+        rt_exit_critical();
+    }
 }
 RTM_EXPORT(pthread_cleanup_push);
 
@@ -394,85 +437,90 @@ RTM_EXPORT(pthread_cleanup_push);
 
 int pthread_setcancelstate(int state, int *oldstate)
 {
-	_pthread_data_t* ptd;
+    _pthread_data_t *ptd;
 
-	/* get posix thread data */
-	ptd = _pthread_get_data(rt_thread_self());
-	RT_ASSERT(ptd != RT_NULL);
+    /* get posix thread data */
+    ptd = _pthread_get_data(rt_thread_self());
+    RT_ASSERT(ptd != RT_NULL);
 
-	if ((state == PTHREAD_CANCEL_ENABLE) || (state == PTHREAD_CANCEL_DISABLE))
-	{
-    	if (oldstate) *oldstate = ptd->cancelstate;
-		ptd->cancelstate = state;
+    if ((state == PTHREAD_CANCEL_ENABLE) || (state == PTHREAD_CANCEL_DISABLE))
+    {
+        if (oldstate)
+            *oldstate = ptd->cancelstate;
+        ptd->cancelstate = state;
 
-		return 0;
-	}
+        return 0;
+    }
 
-	return EINVAL;
+    return EINVAL;
 }
 RTM_EXPORT(pthread_setcancelstate);
 
 int pthread_setcanceltype(int type, int *oldtype)
 {
-	_pthread_data_t* ptd;
+    _pthread_data_t *ptd;
 
-	/* get posix thread data */
-	ptd = _pthread_get_data(rt_thread_self());
-	RT_ASSERT(ptd != RT_NULL);
+    /* get posix thread data */
+    ptd = _pthread_get_data(rt_thread_self());
+    RT_ASSERT(ptd != RT_NULL);
 
-	if ((type != PTHREAD_CANCEL_DEFERRED) && (type != PTHREAD_CANCEL_ASYNCHRONOUS)) 
-		return EINVAL;
+    if ((type != PTHREAD_CANCEL_DEFERRED) && (type != PTHREAD_CANCEL_ASYNCHRONOUS)) 
+        return EINVAL;
 
-	if (oldtype) *oldtype = ptd->canceltype;
-	ptd->canceltype = type;
+    if (oldtype)
+        *oldtype = ptd->canceltype;
+    ptd->canceltype = type;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_setcanceltype);
 
 void pthread_testcancel(void)
 {
-	int cancel=0;
-	_pthread_data_t* ptd;
+    int cancel=0;
+    _pthread_data_t* ptd;
 
-	/* get posix thread data */
-	ptd = _pthread_get_data(rt_thread_self());
-	RT_ASSERT(ptd != RT_NULL);
+    /* get posix thread data */
+    ptd = _pthread_get_data(rt_thread_self());
+    RT_ASSERT(ptd != RT_NULL);
 
-	if (ptd->cancelstate == PTHREAD_CANCEL_ENABLE) cancel = ptd->canceled;
-	if (cancel) pthread_exit((void*)PTHREAD_CANCELED);
+    if (ptd->cancelstate == PTHREAD_CANCEL_ENABLE)
+        cancel = ptd->canceled;
+    if (cancel)
+        pthread_exit((void*)PTHREAD_CANCELED);
 }
 RTM_EXPORT(pthread_testcancel);
 
 int pthread_cancel(pthread_t thread)
 {
-	_pthread_data_t* ptd;
-
-	/* cancel self */
-	if (thread == rt_thread_self()) return 0;
-
-	/* get posix thread data */
-	ptd = _pthread_get_data(thread);
-	RT_ASSERT(ptd != RT_NULL);
-
-	/* set canceled */
-	if (ptd->cancelstate == PTHREAD_CANCEL_ENABLE)
-	{
-		ptd->canceled = 1;
-		if (ptd->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
-		{
-			/*
-			 * to detach thread.
-			 * this thread will be removed from scheduler list
-			 * and because there is a cleanup function in the
-			 * thread (pthread_cleanup), it will move to defunct
-			 * thread list and wait for handling in idle thread.
-			 */
-			rt_thread_detach(thread);
-		}
-	}
-
-	return 0;
+    _pthread_data_t *ptd;
+
+    /* cancel self */
+    if (thread == rt_thread_self())
+        return 0;
+
+    /* get posix thread data */
+    ptd = _pthread_get_data(thread);
+    RT_ASSERT(ptd != RT_NULL);
+
+    /* set canceled */
+    if (ptd->cancelstate == PTHREAD_CANCEL_ENABLE)
+    {
+        ptd->canceled = 1;
+        if (ptd->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
+        {
+            /*
+             * to detach thread.
+             * this thread will be removed from scheduler list
+             * and because there is a cleanup function in the
+             * thread (pthread_cleanup), it will move to defunct
+             * thread list and wait for handling in idle thread.
+             */
+            rt_thread_detach(thread);
+        }
+    }
+
+    return 0;
 }
 RTM_EXPORT(pthread_cancel);
 

+ 88 - 71
components/pthreads/pthread.h

@@ -3,31 +3,42 @@
  * This file is part of RT-Thread RTOS
  * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
+ *  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
  */
+
 #ifndef __PTHREAD_H__
 #define __PTHREAD_H__
 
 #include <rtthread.h>
 #include <posix_types.h>
 
-#define PTHREAD_KEY_MAX				8
+#define PTHREAD_KEY_MAX             8
 
-#define PTHREAD_COND_INITIALIZER	{-1, 0}
-#define PTHREAD_RWLOCK_INITIALIZER	{-1, 0}
-#define PTHREAD_MUTEX_INITIALIZER	{-1, 0}
+#define PTHREAD_COND_INITIALIZER    {-1, 0}
+#define PTHREAD_RWLOCK_INITIALIZER  {-1, 0}
+#define PTHREAD_MUTEX_INITIALIZER   {-1, 0}
 
-#define PTHREAD_CREATE_JOINABLE		0x00
-#define PTHREAD_CREATE_DETACHED		0x01
+#define PTHREAD_CREATE_JOINABLE     0x00
+#define PTHREAD_CREATE_DETACHED     0x01
 
-#define PTHREAD_EXPLICIT_SCHED		0
-#define PTHREAD_INHERIT_SCHED		1
+#define PTHREAD_EXPLICIT_SCHED      0
+#define PTHREAD_INHERIT_SCHED       1
 
 typedef rt_thread_t pthread_t;
 typedef long pthread_condattr_t;
@@ -38,15 +49,17 @@ typedef long pthread_barrierattr_t;
 typedef int pthread_key_t;
 typedef int pthread_once_t;
 
-enum {
-	PTHREAD_CANCEL_ASYNCHRONOUS = 0,
-	PTHREAD_CANCEL_ENABLE,
-	PTHREAD_CANCEL_DEFERRED,
-	PTHREAD_CANCEL_DISABLE,
-	PTHREAD_CANCELED
+enum
+{
+    PTHREAD_CANCEL_ASYNCHRONOUS = 0,
+    PTHREAD_CANCEL_ENABLE,
+    PTHREAD_CANCEL_DEFERRED,
+    PTHREAD_CANCEL_DISABLE,
+    PTHREAD_CANCELED
 };
 
-enum {
+enum
+{
     PTHREAD_MUTEX_NORMAL = 0,
     PTHREAD_MUTEX_RECURSIVE = 1,
     PTHREAD_MUTEX_ERRORCHECK = 2,
@@ -56,72 +69,73 @@ enum {
 };
 
 /* init value for pthread_once_t */
-#define PTHREAD_ONCE_INIT		0
+#define PTHREAD_ONCE_INIT       0
 
-enum {
-	PTHREAD_PRIO_INHERIT =0,
-	PTHREAD_PRIO_NONE,
-	PTHREAD_PRIO_PROTECT,
+enum
+{
+    PTHREAD_PRIO_INHERIT =0,
+    PTHREAD_PRIO_NONE,
+    PTHREAD_PRIO_PROTECT,
 };
 
 #define PTHREAD_PROCESS_PRIVATE  0
 #define PTHREAD_PROCESS_SHARED   1
 
-#define PTHREAD_SCOPE_PROCESS	0
-#define PTHREAD_SCOPE_SYSTEM	1
+#define PTHREAD_SCOPE_PROCESS   0
+#define PTHREAD_SCOPE_SYSTEM    1
 
 struct pthread_attr
 {
-    void* 		stack_base;
-	rt_uint16_t stack_size;		/* stack size of thread */
+    void*       stack_base;
+    rt_uint16_t stack_size;     /* stack size of thread */
 
-	rt_uint8_t priority;		/* priority of thread */
-	rt_uint8_t detachstate;		/* detach state */
-	rt_uint8_t policy;			/* scheduler policy */
-	rt_uint8_t inheritsched;	/* Inherit parent prio/policy */
+    rt_uint8_t priority;        /* priority of thread */
+    rt_uint8_t detachstate;     /* detach state */
+    rt_uint8_t policy;          /* scheduler policy */
+    rt_uint8_t inheritsched;    /* Inherit parent prio/policy */
 };
 typedef struct pthread_attr pthread_attr_t;
 
 struct pthread_mutex
 {
-	pthread_mutexattr_t attr;
-	struct rt_mutex lock;
+    pthread_mutexattr_t attr;
+    struct rt_mutex lock;
 };
 typedef struct pthread_mutex pthread_mutex_t;
 
 struct pthread_cond
 {
-	pthread_condattr_t attr;
-	struct rt_semaphore sem;
+    pthread_condattr_t attr;
+    struct rt_semaphore sem;
 };
 typedef struct pthread_cond pthread_cond_t;
 
 struct pthread_rwlock
 {
-	pthread_rwlockattr_t attr;
+    pthread_rwlockattr_t attr;
 
-	pthread_mutex_t      rw_mutex;			/* basic lock on this struct */
-	pthread_cond_t       rw_condreaders; 	/* for reader threads waiting */
-	pthread_cond_t       rw_condwriters; 	/* for writer threads waiting */
+    pthread_mutex_t      rw_mutex;          /* basic lock on this struct */
+    pthread_cond_t       rw_condreaders;    /* for reader threads waiting */
+    pthread_cond_t       rw_condwriters;    /* for writer threads waiting */
 
-	int rw_nwaitreaders;	/* the number of reader threads waiting */
-	int rw_nwaitwriters;	/* the number of writer threads waiting */
-	int rw_refcount;	/* 0: unlocked, -1: locked by writer, > 0 locked by n readers */
+    int rw_nwaitreaders;    /* the number of reader threads waiting */
+    int rw_nwaitwriters;    /* the number of writer threads waiting */
+    int rw_refcount;    /* 0: unlocked, -1: locked by writer, > 0 locked by n readers */
 };
 typedef struct pthread_rwlock pthread_rwlock_t;
 
 /* spinlock implementation, (ADVANCED REALTIME THREADS)*/
 struct pthread_spinlock
 {
-	int lock;
+    int lock;
 };
 typedef struct pthread_spinlock pthread_spinlock_t;
 
 struct pthread_barrier
 {
-	int count;
-	pthread_cond_t cond;
-	pthread_mutex_t mutex;
+    int count;
+    pthread_cond_t cond;
+    pthread_mutex_t mutex;
 };
 typedef struct pthread_barrier pthread_barrier_t;
 
@@ -131,19 +145,19 @@ int pthread_attr_init(pthread_attr_t *attr);
 
 int pthread_system_init(void);
 int pthread_create (pthread_t *tid, const pthread_attr_t *attr, 
-	void *(*start) (void *), void *arg);
+    void *(*start) (void *), void *arg);
 
 int pthread_detach (pthread_t thread);
 int pthread_join (pthread_t thread, void **value_ptr);
 
 rt_inline int pthread_equal (pthread_t t1, pthread_t t2)
 {
-	return t1 == t2;
+    return t1 == t2;
 }
 
 rt_inline pthread_t pthread_self (void)
 {
-	return rt_thread_self();
+    return rt_thread_self();
 }
 
 void pthread_exit (void *value_ptr);
@@ -182,9 +196,9 @@ int pthread_condattr_init(pthread_condattr_t *attr);
 
 /* ADVANCED REALTIME feature in IEEE Std 1003.1, 2004 Edition */
 int pthread_condattr_getclock(const pthread_condattr_t *attr,
-       clockid_t *clock_id);
+                              clockid_t                *clock_id);
 int pthread_condattr_setclock(pthread_condattr_t *attr,
-       clockid_t clock_id);
+                              clockid_t           clock_id);
 
 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
 int pthread_cond_destroy(pthread_cond_t *cond);
@@ -192,9 +206,9 @@ int pthread_cond_broadcast(pthread_cond_t *cond);
 int pthread_cond_signal(pthread_cond_t *cond);
 
 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
-int pthread_cond_timedwait(pthread_cond_t *cond,
-	pthread_mutex_t * mutex,
-	const struct timespec *abstime);
+int pthread_cond_timedwait(pthread_cond_t        *cond,
+                           pthread_mutex_t       *mutex,
+                           const struct timespec *abstime);
 
 /* pthread rwlock interface */
 int pthread_rwlockattr_init (pthread_rwlockattr_t *attr);
@@ -231,36 +245,39 @@ int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshar
 int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared);
 
 int pthread_barrier_destroy(pthread_barrier_t *barrier);
-int pthread_barrier_init(pthread_barrier_t *barrier,
-       const pthread_barrierattr_t *attr, unsigned count);
+int pthread_barrier_init(pthread_barrier_t           *barrier,
+                         const pthread_barrierattr_t *attr,
+                         unsigned                     count);
 
 int pthread_barrier_wait(pthread_barrier_t *barrier);
 
 /*  Signal Generation and Delivery, P1003.1b-1993, p. 63
     NOTE: P1003.1c/D10, p. 34 adds sigev_notify_function and
           sigev_notify_attributes to the sigevent structure.  */
-union sigval {
-  int    sival_int;    /* Integer signal value */
-  void  *sival_ptr;    /* Pointer signal value */
+union sigval
+{
+    int    sival_int;    /* Integer signal value */
+    void  *sival_ptr;    /* Pointer signal value */
 };
 
-struct sigevent {
-  int              sigev_notify;               /* Notification type */
-  int              sigev_signo;                /* Signal number */
-  union sigval     sigev_value;                /* Signal value */
-  void           (*sigev_notify_function)( union sigval );
+struct sigevent
+{
+    int              sigev_notify;               /* Notification type */
+    int              sigev_signo;                /* Signal number */
+    union sigval     sigev_value;                /* Signal value */
+    void           (*sigev_notify_function)( union sigval );
                                                /* Notification function */
-  pthread_attr_t  *sigev_notify_attributes;    /* Notification Attributes */
+    pthread_attr_t  *sigev_notify_attributes;    /* Notification Attributes */
 };
 
 /* posix clock and timer */
-#define MILLISECOND_PER_SECOND	1000UL
-#define MICROSECOND_PER_SECOND	1000000UL
-#define NANOSECOND_PER_SECOND	1000000000UL
+#define MILLISECOND_PER_SECOND  1000UL
+#define MICROSECOND_PER_SECOND  1000000UL
+#define NANOSECOND_PER_SECOND   1000000000UL
 
-#define MILLISECOND_PER_TICK	(MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND)
-#define MICROSECOND_PER_TICK	(MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND)
-#define NANOSECOND_PER_TICK		(NANOSECOND_PER_SECOND  / RT_TICK_PER_SECOND)
+#define MILLISECOND_PER_TICK    (MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND)
+#define MICROSECOND_PER_TICK    (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND)
+#define NANOSECOND_PER_TICK     (NANOSECOND_PER_SECOND  / RT_TICK_PER_SECOND)
 
 #ifndef CLOCK_REALTIME
 #define CLOCK_REALTIME      0

+ 109 - 69
components/pthreads/pthread_attr.c

@@ -1,162 +1,202 @@
+/*
+ * File      : pthread_attr.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"
 #include "sched.h"
 #include <string.h>
 
-#define DEFAULT_STACK_SIZE	2048
-#define DEFAULT_PRIORITY	(RT_THREAD_PRIORITY_MAX/2 + RT_THREAD_PRIORITY_MAX/4)
+#define DEFAULT_STACK_SIZE  2048
+#define DEFAULT_PRIORITY    (RT_THREAD_PRIORITY_MAX/2 + RT_THREAD_PRIORITY_MAX/4)
 
 const pthread_attr_t pthread_default_attr = 
 {
-	0,							/* stack base */
-	DEFAULT_STACK_SIZE,			/* stack size */
-	DEFAULT_PRIORITY,			/* priority */
-	PTHREAD_CREATE_JOINABLE,	/* detach state */
-	SCHED_FIFO,					/* scheduler policy */
-	PTHREAD_INHERIT_SCHED		/* Inherit parent prio/policy */
+    0,                          /* stack base */
+    DEFAULT_STACK_SIZE,         /* stack size */
+    DEFAULT_PRIORITY,           /* priority */
+    PTHREAD_CREATE_JOINABLE,    /* detach state */
+    SCHED_FIFO,                 /* scheduler policy */
+    PTHREAD_INHERIT_SCHED       /* Inherit parent prio/policy */
 };
 
 int pthread_attr_init(pthread_attr_t *attr)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
 
-	*attr = pthread_default_attr;
+    *attr = pthread_default_attr;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_init);
 
 int pthread_attr_destroy(pthread_attr_t *attr)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
+
+    memset(attr, 0, sizeof(pthread_attr_t));
 
-	memset(attr, 0, sizeof(pthread_attr_t));
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_destroy);
 
-int pthread_attr_setdetachstate(pthread_attr_t * attr, int state)
+int pthread_attr_setdetachstate(pthread_attr_t *attr, int state)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
+
+    if (state != PTHREAD_CREATE_JOINABLE && state != PTHREAD_CREATE_DETACHED)
+        return EINVAL;
 
-	if (state != PTHREAD_CREATE_JOINABLE && state != PTHREAD_CREATE_DETACHED)
-		return EINVAL;
+    attr->detachstate = state;
 
-	attr->detachstate = state;
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_setdetachstate);
 
-int pthread_attr_getdetachstate(pthread_attr_t const * attr, int *state)
+int pthread_attr_getdetachstate(pthread_attr_t const *attr, int *state)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
 
-	*state = (int)attr->detachstate;
+    *state = (int)attr->detachstate;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_getdetachstate);
 
-int pthread_attr_setschedpolicy(pthread_attr_t * attr, int policy)
+int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
 
-	attr->policy = policy;
-	return 0;
+    attr->policy = policy;
+
+    return 0;
 }
 RTM_EXPORT(pthread_attr_setschedpolicy);
 
 int pthread_attr_getschedpolicy(pthread_attr_t const *attr, int *policy)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
+
+    *policy = (int)attr->policy;
 
-	*policy = (int)attr->policy;
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_getschedpolicy);
 
-int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param const *param)
+int pthread_attr_setschedparam(pthread_attr_t           *attr,
+                               struct sched_param const *param)
 {
-	RT_ASSERT(attr != RT_NULL);
-	RT_ASSERT(param != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(param != RT_NULL);
+
+    attr->priority = param->sched_priority;
 
-	attr->priority = param->sched_priority;
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_setschedparam);
 
-int pthread_attr_getschedparam(pthread_attr_t const *attr, struct sched_param *param)
+int pthread_attr_getschedparam(pthread_attr_t const *attr,
+                               struct sched_param   *param)
 {
-	RT_ASSERT(attr != RT_NULL);
-	RT_ASSERT(param != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(param != RT_NULL);
 
-	param->sched_priority = attr->priority;
-	return 0;
+    param->sched_priority = attr->priority;
+
+    return 0;
 }
 RTM_EXPORT(pthread_attr_getschedparam);
 
-int pthread_attr_setstacksize(pthread_attr_t * attr, size_t stack_size)
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
+
+    attr->stack_size = stack_size;
 
-	attr->stack_size = stack_size;
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_setstacksize);
 
-int pthread_attr_getstacksize(pthread_attr_t const * attr, size_t *stack_size)
+int pthread_attr_getstacksize(pthread_attr_t const *attr, size_t *stack_size)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
+
+    *stack_size = attr->stack_size;
 
-	*stack_size = attr->stack_size;
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_getstacksize);
 
-int pthread_attr_setstackaddr(pthread_attr_t * attr, void * stack_addr)
+int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack_addr)
 {
-	RT_ASSERT(attr != RT_NULL);
-	return ENOTSUP;
+    RT_ASSERT(attr != RT_NULL);
+
+    return ENOTSUP;
 }
 RTM_EXPORT(pthread_attr_setstackaddr);
 
-int pthread_attr_getstackaddr(pthread_attr_t const * attr, void ** stack_addr)
+int pthread_attr_getstackaddr(pthread_attr_t const *attr, void **stack_addr)
 {
-	RT_ASSERT(attr != RT_NULL);
-	return ENOTSUP;
+    RT_ASSERT(attr != RT_NULL);
+
+    return ENOTSUP;
 }
 RTM_EXPORT(pthread_attr_getstackaddr);
 
-int pthread_attr_setstack(pthread_attr_t * attr, void *stack_base, size_t stack_size)
+int pthread_attr_setstack(pthread_attr_t *attr,
+                          void           *stack_base,
+                          size_t          stack_size)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
 
-	attr->stack_base = stack_base;
-	attr->stack_size = RT_ALIGN_DOWN(stack_size, RT_ALIGN_SIZE);
+    attr->stack_base = stack_base;
+    attr->stack_size = RT_ALIGN_DOWN(stack_size, RT_ALIGN_SIZE);
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_setstack);
 
-int pthread_attr_getstack(pthread_attr_t const * attr, void **stack_base, size_t *stack_size)
+int pthread_attr_getstack(pthread_attr_t const *attr,
+                          void                **stack_base,
+                          size_t               *stack_size)
 {
-	RT_ASSERT(attr != RT_NULL);
+    RT_ASSERT(attr != RT_NULL);
 
-	*stack_base = attr->stack_base;
-	*stack_size = attr->stack_size;
+    *stack_base = attr->stack_base;
+    *stack_size = attr->stack_size;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_attr_getstack);
 
-int pthread_attr_setguardsize(pthread_attr_t * attr, size_t guard_size)
+int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guard_size)
 {
-	return ENOTSUP;
+    return ENOTSUP;
 }
 
-int pthread_attr_getguardsize(pthread_attr_t const * attr, size_t *guard_size)
+int pthread_attr_getguardsize(pthread_attr_t const *attr, size_t *guard_size)
 {
-	return ENOTSUP;
+    return ENOTSUP;
 }
 RTM_EXPORT(pthread_attr_getguardsize);
 

+ 81 - 42
components/pthreads/pthread_barrier.c

@@ -1,85 +1,124 @@
+/*
+ * File      : pthread_barrier.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 <pthread.h>
 
 int pthread_barrierattr_destroy(pthread_barrierattr_t *attr)
 {
-	if (!attr) return EINVAL;
-	return 0;
+    if (!attr)
+        return EINVAL;
+
+    return 0;
 }
 RTM_EXPORT(pthread_barrierattr_destroy);
 
 int pthread_barrierattr_init(pthread_barrierattr_t *attr)
 {
-	if (!attr) return EINVAL;
-	*attr = PTHREAD_PROCESS_PRIVATE;
+    if (!attr)
+        return EINVAL;
+    *attr = PTHREAD_PROCESS_PRIVATE;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_barrierattr_init);
 
-int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared)
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr,
+                                   int                         *pshared)
 {
-	if (!attr) return EINVAL;
-	*pshared = (int)*attr;
+    if (!attr)
+        return EINVAL;
+    *pshared = (int)*attr;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_barrierattr_getpshared);
 
 int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared)
 {
-	if (!attr) return EINVAL;
-	if (pshared == PTHREAD_PROCESS_PRIVATE) attr = PTHREAD_PROCESS_PRIVATE;
+    if (!attr)
+        return EINVAL;
+    if (pshared == PTHREAD_PROCESS_PRIVATE)
+        attr = PTHREAD_PROCESS_PRIVATE;
 
-	return EINVAL;
+    return EINVAL;
 }
 RTM_EXPORT(pthread_barrierattr_setpshared);
 
 int pthread_barrier_destroy(pthread_barrier_t *barrier)
 {
-	rt_err_t result;
+    rt_err_t result;
 
-	if (!barrier) return EINVAL;
+    if (!barrier)
+        return EINVAL;
 
-	result = pthread_cond_destroy(&(barrier->cond));
+    result = pthread_cond_destroy(&(barrier->cond));
 
-	return result;
+    return result;
 }
 RTM_EXPORT(pthread_barrier_destroy);
 
-int pthread_barrier_init(pthread_barrier_t *barrier,
-       const pthread_barrierattr_t *attr, unsigned count)
+int pthread_barrier_init(pthread_barrier_t           *barrier,
+                         const pthread_barrierattr_t *attr,
+                         unsigned                     count)
 {
-	if (!barrier) return EINVAL;
-	if (attr &&(*attr != PTHREAD_PROCESS_PRIVATE)) return EINVAL;
+    if (!barrier)
+        return EINVAL;
+    if (attr && (*attr != PTHREAD_PROCESS_PRIVATE))
+        return EINVAL;
 
-	barrier->count = count;
-	pthread_cond_init(&(barrier->cond), NULL);
-	pthread_mutex_init(&(barrier->mutex), NULL);
+    barrier->count = count;
+    pthread_cond_init(&(barrier->cond), NULL);
+    pthread_mutex_init(&(barrier->mutex), NULL);
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_barrier_init);
 
 int pthread_barrier_wait(pthread_barrier_t *barrier)
 {
-	rt_err_t result;
-	if (!barrier) return EINVAL;
-
-	result = pthread_mutex_lock(&(barrier->mutex));
-	if (result != 0) return EINVAL;
-
-	if (barrier->count == 0) result = EINVAL;
-	else
-	{
-		barrier->count -= 1;
-		if (barrier->count == 0) /* broadcast condition */
-			pthread_cond_broadcast(&(barrier->cond));
-		else
-			pthread_cond_wait(&(barrier->cond), &(barrier->mutex));
-	}
-
-	pthread_mutex_unlock(&(barrier->mutex));
-	return result;
+    rt_err_t result;
+    if (!barrier)
+        return EINVAL;
+
+    result = pthread_mutex_lock(&(barrier->mutex));
+    if (result != 0)
+        return EINVAL;
+
+    if (barrier->count == 0)
+        result = EINVAL;
+    else
+    {
+        barrier->count -= 1;
+        if (barrier->count == 0) /* broadcast condition */
+            pthread_cond_broadcast(&(barrier->cond));
+        else
+            pthread_cond_wait(&(barrier->cond), &(barrier->mutex));
+    }
+
+    pthread_mutex_unlock(&(barrier->mutex));
+
+    return result;
 }
 RTM_EXPORT(pthread_barrier_wait);
 

+ 153 - 107
components/pthreads/pthread_cond.c

@@ -1,193 +1,239 @@
+/*
+ * File      : pthread_cond.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 <pthread.h>
 #include "pthread_internal.h"
 
 int pthread_condattr_destroy(pthread_condattr_t *attr)
 {
-	if (!attr) return EINVAL;
+    if (!attr)
+        return EINVAL;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_condattr_destroy);
 
 int pthread_condattr_init(pthread_condattr_t *attr)
 {
-	if (!attr) return EINVAL;
-	*attr = PTHREAD_PROCESS_PRIVATE;
+    if (!attr)
+        return EINVAL;
+    *attr = PTHREAD_PROCESS_PRIVATE;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_condattr_init);
 
 int pthread_condattr_getclock(const pthread_condattr_t *attr,
-       clockid_t *clock_id)
+                              clockid_t                *clock_id)
 {
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_condattr_getclock);
 
 int pthread_condattr_setclock(pthread_condattr_t *attr,
-       clockid_t clock_id)
+                              clockid_t           clock_id)
 {
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_condattr_setclock);
 
 int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared)
 {
-	if (!attr || !pshared) return EINVAL;
+    if (!attr || !pshared)
+        return EINVAL;
+
+    *pshared = PTHREAD_PROCESS_PRIVATE;
 
-	*pshared = PTHREAD_PROCESS_PRIVATE;
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_condattr_getpshared);
 
 int pthread_condattr_setpshared(pthread_condattr_t*attr, int pshared)
 {
-	if ((pshared != PTHREAD_PROCESS_PRIVATE) && (pshared != PTHREAD_PROCESS_SHARED))
-    	return EINVAL;
+    if ((pshared != PTHREAD_PROCESS_PRIVATE) &&
+        (pshared != PTHREAD_PROCESS_SHARED))
+    {
+        return EINVAL;
+    }
 
-	if (pshared != PTHREAD_PROCESS_PRIVATE)
-    	return ENOSYS;
+    if (pshared != PTHREAD_PROCESS_PRIVATE)
+        return ENOSYS;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_condattr_setpshared);
 
 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
 {
-	rt_err_t result;
-	char cond_name[RT_NAME_MAX];
-	static rt_uint16_t cond_num = 0;
+    rt_err_t result;
+    char cond_name[RT_NAME_MAX];
+    static rt_uint16_t cond_num = 0;
 
-	/* parameter check */
-	if (cond == RT_NULL) return EINVAL;
-	if ((attr != RT_NULL) && (*attr != PTHREAD_PROCESS_PRIVATE)) return EINVAL;
+    /* parameter check */
+    if (cond == RT_NULL)
+        return EINVAL;
+    if ((attr != RT_NULL) && (*attr != PTHREAD_PROCESS_PRIVATE))
+        return EINVAL;
 
-	rt_snprintf(cond_name, sizeof(cond_name),
-			"cond%02d", cond_num++);
+    rt_snprintf(cond_name, sizeof(cond_name), "cond%02d", cond_num++);
 
-	cond->attr = *attr;
-	result = rt_sem_init(&cond->sem, cond_name, 0, RT_IPC_FLAG_FIFO);
-	if (result != RT_EOK) return EINVAL;
+    cond->attr = *attr;
+    result = rt_sem_init(&cond->sem, cond_name, 0, RT_IPC_FLAG_FIFO);
+    if (result != RT_EOK)
+        return EINVAL;
 
-	/* detach the object from system object container */
-	rt_object_detach(&(cond->sem.parent.parent));
+    /* detach the object from system object container */
+    rt_object_detach(&(cond->sem.parent.parent));
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_cond_init);
 
 int pthread_cond_destroy(pthread_cond_t *cond)
 {
-	rt_err_t result;
-	if (cond == RT_NULL) return EINVAL;
-	if (cond->attr == -1) return 0; /* which is not initialized */
+    rt_err_t result;
+    if (cond == RT_NULL)
+        return EINVAL;
+    if (cond->attr == -1)
+        return 0; /* which is not initialized */
 
-	result = rt_sem_trytake(&(cond->sem));
-	if (result != RT_EOK) return EBUSY;
+    result = rt_sem_trytake(&(cond->sem));
+    if (result != RT_EOK)
+        return EBUSY;
 
-	/* clean condition */
-	rt_memset(cond, 0, sizeof(pthread_cond_t));
-	cond->attr = -1;
+    /* clean condition */
+    rt_memset(cond, 0, sizeof(pthread_cond_t));
+    cond->attr = -1;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_cond_destroy);
 
 int pthread_cond_broadcast(pthread_cond_t *cond)
 {
-	rt_err_t result;
-	if (cond->attr == -1)
-		pthread_cond_init(cond, RT_NULL);
-
-	rt_enter_critical();
-	while (1)
-	{
-		/* try to take condition semaphore */
-		result = rt_sem_trytake(&(cond->sem));
-		if (result == -RT_ETIMEOUT)
-		{
-			/* it's timeout, release this semaphore */
-			rt_sem_release(&(cond->sem));
-		}
-		else if (result == RT_EOK)
-		{
-			/* has taken this semaphore, release it */
-			rt_sem_release(&(cond->sem));
-			break;
-		}
-		else
-		{
-			rt_exit_critical();
-			return EINVAL;
-		}
-	}
-	rt_exit_critical();
-
-	return 0;
+    rt_err_t result;
+    if (cond->attr == -1)
+        pthread_cond_init(cond, RT_NULL);
+
+    rt_enter_critical();
+    while (1)
+    {
+        /* try to take condition semaphore */
+        result = rt_sem_trytake(&(cond->sem));
+        if (result == -RT_ETIMEOUT)
+        {
+            /* it's timeout, release this semaphore */
+            rt_sem_release(&(cond->sem));
+        }
+        else if (result == RT_EOK)
+        {
+            /* has taken this semaphore, release it */
+            rt_sem_release(&(cond->sem));
+            break;
+        }
+        else
+        {
+            rt_exit_critical();
+
+            return EINVAL;
+        }
+    }
+    rt_exit_critical();
+
+    return 0;
 }
 RTM_EXPORT(pthread_cond_broadcast);
 
 int pthread_cond_signal(pthread_cond_t *cond)
 {
-	rt_err_t result;
+    rt_err_t result;
 
-	if (cond->attr == -1)
-		pthread_cond_init(cond, RT_NULL);
+    if (cond->attr == -1)
+        pthread_cond_init(cond, RT_NULL);
 
-	result = rt_sem_release(&(cond->sem));
-	if (result == RT_EOK) return 0;
+    result = rt_sem_release(&(cond->sem));
+    if (result == RT_EOK)
+        return 0;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_cond_signal);
 
-rt_err_t _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
-		rt_int32_t timeout)
+rt_err_t _pthread_cond_timedwait(pthread_cond_t  *cond,
+                                 pthread_mutex_t *mutex,
+                                 rt_int32_t       timeout)
 {
-	rt_err_t result;
-
-	if (!cond || !mutex) return -RT_ERROR;
-	/* check whether initialized */
-	if (cond->attr == -1) pthread_cond_init(cond, RT_NULL);
-
-	/* The mutex was not owned by the current thread at the time of the call. */
-	if (mutex->lock.owner != pthread_self()) return -RT_ERROR;
-	/* unlock a mutex failed */
-	if (pthread_mutex_unlock(mutex) != 0)
-		return -RT_ERROR;
-
-	result = rt_sem_take(&(cond->sem), timeout);
-	/* lock mutex again */
-	pthread_mutex_lock(mutex);
-	return result;
+    rt_err_t result;
+
+    if (!cond || !mutex)
+        return -RT_ERROR;
+    /* check whether initialized */
+    if (cond->attr == -1)
+        pthread_cond_init(cond, RT_NULL);
+
+    /* The mutex was not owned by the current thread at the time of the call. */
+    if (mutex->lock.owner != pthread_self())
+        return -RT_ERROR;
+    /* unlock a mutex failed */
+    if (pthread_mutex_unlock(mutex) != 0)
+        return -RT_ERROR;
+
+    result = rt_sem_take(&(cond->sem), timeout);
+    /* lock mutex again */
+    pthread_mutex_lock(mutex);
+
+    return result;
 }
 RTM_EXPORT(_pthread_cond_timedwait);
 
 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
 {
-	rt_err_t result;
+    rt_err_t result;
 
-	result = _pthread_cond_timedwait(cond, mutex, RT_WAITING_FOREVER);
-	if (result == RT_EOK) return 0;
+    result = _pthread_cond_timedwait(cond, mutex, RT_WAITING_FOREVER);
+    if (result == RT_EOK)
+        return 0;
 
-	return EINVAL;
+    return EINVAL;
 }
 RTM_EXPORT(pthread_cond_wait);
 
-int pthread_cond_timedwait(pthread_cond_t *cond,
-	pthread_mutex_t * mutex,
-	const struct timespec *abstime)
+int pthread_cond_timedwait(pthread_cond_t        *cond,
+                           pthread_mutex_t       *mutex,
+                           const struct timespec *abstime)
 {
-	int timeout;
-	rt_err_t result;
+    int timeout;
+    rt_err_t result;
 
-	timeout = clock_time_to_tick(abstime);
-	result = _pthread_cond_timedwait(cond, mutex, timeout);
-	if (result == RT_EOK) return 0;
-	if (result == -RT_ETIMEOUT) return ETIMEDOUT;
+    timeout = clock_time_to_tick(abstime);
+    result = _pthread_cond_timedwait(cond, mutex, timeout);
+    if (result == RT_EOK)
+        return 0;
+    if (result == -RT_ETIMEOUT)
+        return ETIMEDOUT;
 
-	return EINVAL;
+    return EINVAL;
 }
 RTM_EXPORT(pthread_cond_timedwait);
 

+ 52 - 28
components/pthreads/pthread_internal.h

@@ -1,3 +1,27 @@
+/*
+ * File      : pthread_internal.h
+ * 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
+ */
+
 #ifndef __PTHREAD_INTERNAL_H__
 #define __PTHREAD_INTERNAL_H__
 
@@ -6,56 +30,56 @@
 
 struct _pthread_cleanup
 {
-	void (*cleanup_func)(void* parameter);
-	void* parameter;
+    void (*cleanup_func)(void *parameter);
+    void *parameter;
 
-	struct _pthread_cleanup* next;
+    struct _pthread_cleanup *next;
 };
 typedef struct _pthread_cleanup _pthread_cleanup_t;
 
 struct _pthread_key_data
 {
-	int is_used;
-	void (*destructor)(void* parameter);
+    int is_used;
+    void (*destructor)(void *parameter);
 };
 typedef struct _pthread_key_data _pthread_key_data_t;
 
-#define PTHREAD_MAGIC	0x70746873
+#define PTHREAD_MAGIC   0x70746873
 struct _pthread_data
 {
-	rt_uint32_t magic;
-	pthread_attr_t attr;
-	rt_thread_t tid;
+    rt_uint32_t magic;
+    pthread_attr_t attr;
+    rt_thread_t tid;
 
-	void* (*thread_entry)(void* parameter);
-	void* thread_parameter;
+    void* (*thread_entry)(void *parameter);
+    void *thread_parameter;
 
-	/* return value */
-	void* return_value;
+    /* return value */
+    void *return_value;
 
-	/* semaphore for joinable thread */
-	rt_sem_t joinable_sem;
+    /* semaphore for joinable thread */
+    rt_sem_t joinable_sem;
 
-	/* cancel state and type */
-	rt_uint8_t cancelstate;
-	volatile rt_uint8_t canceltype;
-	volatile rt_uint8_t canceled;
+    /* cancel state and type */
+    rt_uint8_t cancelstate;
+    volatile rt_uint8_t canceltype;
+    volatile rt_uint8_t canceled;
 
-	_pthread_cleanup_t* cleanup;
-	void** tls; /* thread-local storage area */
+    _pthread_cleanup_t *cleanup;
+    void** tls; /* thread-local storage area */
 };
 typedef struct _pthread_data _pthread_data_t;
 
-rt_inline _pthread_data_t* _pthread_get_data(pthread_t thread)
+rt_inline _pthread_data_t *_pthread_get_data(pthread_t thread)
 {
-	_pthread_data_t* ptd;
-	RT_ASSERT(thread != RT_NULL);
+    _pthread_data_t *ptd;
+    RT_ASSERT(thread != RT_NULL);
 
-	ptd = (_pthread_data_t*)thread->user_data;
-	RT_ASSERT(ptd != RT_NULL);
-	RT_ASSERT(ptd->magic == PTHREAD_MAGIC);
+    ptd = (_pthread_data_t *)thread->user_data;
+    RT_ASSERT(ptd != RT_NULL);
+    RT_ASSERT(ptd->magic == PTHREAD_MAGIC);
 
-	return ptd;
+    return ptd;
 }
 
 int clock_time_to_tick(const struct timespec *time);

+ 153 - 108
components/pthreads/pthread_mutex.c

@@ -1,3 +1,27 @@
+/*
+ * 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"
 
@@ -8,51 +32,54 @@ 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;
-	}
+    if (attr)
+    {
+        *attr = pthread_default_mutexattr;
 
-	return EINVAL;
+        return 0;
+    }
+
+    return EINVAL;
 }
 RTM_EXPORT(pthread_mutexattr_init);
 
 int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
 {
-	if (attr)
-	{
-	 	*attr = -1;
-		return 0;
-	}
+    if (attr)
+    {
+        *attr = -1;
 
-	return EINVAL;
+        return 0;
+    }
+
+    return EINVAL;
 }
 RTM_EXPORT(pthread_mutexattr_destroy);
 
 int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
 {
-	if (attr && type)
-	{
+    if (attr && type)
+    {
         int  atype = (*attr & MUTEXATTR_TYPE_MASK);
 
-		if (atype >= PTHREAD_MUTEX_NORMAL && atype <= PTHREAD_MUTEX_ERRORCHECK)
-		{
-			*type = atype;
-			return 0;
-		}
-	}
+        if (atype >= PTHREAD_MUTEX_NORMAL && atype <= PTHREAD_MUTEX_ERRORCHECK)
+        {
+            *type = atype;
 
-	return EINVAL;
+            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 )
-	{
+    if (attr && type >= PTHREAD_MUTEX_NORMAL && type <= PTHREAD_MUTEX_ERRORCHECK)
+    {
         *attr = (*attr & ~MUTEXATTR_TYPE_MASK) | type;
+
         return 0;
     }
 
@@ -60,12 +87,13 @@ int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
 }
 RTM_EXPORT(pthread_mutexattr_settype);
 
-int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int  pshared)
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)
 {
-    if (!attr) return EINVAL;
+    if (!attr)
+        return EINVAL;
 
     switch (pshared)
-	{
+    {
     case PTHREAD_PROCESS_PRIVATE:
         *attr &= ~MUTEXATTR_SHARED_MASK;
         return 0;
@@ -81,7 +109,8 @@ RTM_EXPORT(pthread_mutexattr_setpshared);
 
 int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared)
 {
-    if (!attr || !pshared) return EINVAL;
+    if (!attr || !pshared)
+        return EINVAL;
 
     *pshared = (*attr & MUTEXATTR_SHARED_MASK) ? PTHREAD_PROCESS_SHARED
                                                : PTHREAD_PROCESS_PRIVATE;
@@ -91,116 +120,132 @@ 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;
+    rt_err_t result;
+    char name[RT_NAME_MAX];
+    static rt_uint16_t pthread_mutex_number = 0;
 
-	if (!mutex) return EINVAL;
+    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;
+    /* 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;
+    /* 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));
+    /* detach the object from system object container */
+    rt_object_detach(&(mutex->lock.parent.parent));
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_mutex_init);
 
 int pthread_mutex_destroy(pthread_mutex_t *mutex)
 {
-	if (!mutex || mutex->attr == -1) return EINVAL;
+    if (!mutex || mutex->attr == -1)
+        return EINVAL;
 
-	/* it's busy */
-	if (mutex->lock.owner != RT_NULL) return EBUSY;
+    /* it's busy */
+    if (mutex->lock.owner != RT_NULL)
+        return EBUSY;
 
-	rt_memset(mutex, 0, sizeof(pthread_mutex_t));
-	mutex->attr = -1;
+    rt_memset(mutex, 0, sizeof(pthread_mutex_t));
+    mutex->attr = -1;
 
-	return 0;
+    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;
+    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;
+    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);
-	}
+    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;
+    result = rt_mutex_take(&(mutex->lock), 0);
+    if (result == RT_EOK)
+        return 0;
 
-	return EBUSY;
+    return EBUSY;
 }
 RTM_EXPORT(pthread_mutex_trylock);
 

+ 287 - 220
components/pthreads/pthread_rwlock.c

@@ -1,287 +1,354 @@
+/*
+ * File      : pthread_rwlock.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 <pthread.h>
 
-int pthread_rwlockattr_init (pthread_rwlockattr_t * attr)
+int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
 {
-	if (!attr) return EINVAL;
-	*attr = PTHREAD_PROCESS_PRIVATE;
+    if (!attr)
+        return EINVAL;
+    *attr = PTHREAD_PROCESS_PRIVATE;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_rwlockattr_init);
 
-int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr)
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
 {
-	if (!attr) return EINVAL;
+    if (!attr)
+        return EINVAL;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_rwlockattr_destroy);
 
-int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, int *pshared)
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr,
+                                  int                        *pshared)
 {
-	if (!attr || !pshared) return EINVAL;
+    if (!attr || !pshared)
+        return EINVAL;
+
+    *pshared = PTHREAD_PROCESS_PRIVATE;
 
-	*pshared = PTHREAD_PROCESS_PRIVATE;
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_rwlockattr_getpshared);
 
-int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared)
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared)
 {
-	if (!attr || pshared != PTHREAD_PROCESS_PRIVATE) return EINVAL;
+    if (!attr || pshared != PTHREAD_PROCESS_PRIVATE)
+        return EINVAL;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_rwlockattr_setpshared);
 
-int pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t * attr)
+int pthread_rwlock_init(pthread_rwlock_t           *rwlock,
+                        const pthread_rwlockattr_t *attr)
 {
-	if (!rwlock) return EINVAL;
-
-	rwlock->attr = PTHREAD_PROCESS_PRIVATE;
-	pthread_mutex_init(&(rwlock->rw_mutex), NULL);
-	pthread_cond_init(&(rwlock->rw_condreaders), NULL);
-	pthread_cond_init(&(rwlock->rw_condwriters), NULL);
-	
-	rwlock->rw_nwaitwriters = 0;
-	rwlock->rw_nwaitreaders = 0;
-	rwlock->rw_refcount = 0;
-
-	return 0;
+    if (!rwlock)
+        return EINVAL;
+
+    rwlock->attr = PTHREAD_PROCESS_PRIVATE;
+    pthread_mutex_init(&(rwlock->rw_mutex), NULL);
+    pthread_cond_init(&(rwlock->rw_condreaders), NULL);
+    pthread_cond_init(&(rwlock->rw_condwriters), NULL);
+    
+    rwlock->rw_nwaitwriters = 0;
+    rwlock->rw_nwaitreaders = 0;
+    rwlock->rw_refcount = 0;
+
+    return 0;
 }
 RTM_EXPORT(pthread_rwlock_init);
 
 int pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
 {
-	int result;
-
-	if (!rwlock) return EINVAL;
-	if (rwlock->attr == -1) return 0; /* rwlock is not initialized */
-
-	if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
-		return(result);
-
-	if (rwlock->rw_refcount != 0 ||
-		rwlock->rw_nwaitreaders != 0 || rwlock->rw_nwaitwriters != 0)
-	{
-		result = EBUSY;
-		return(EBUSY);
-	}
-	else
-	{
-		/* check whether busy */
-		result = rt_sem_trytake(&(rwlock->rw_condreaders.sem));
-		if (result == RT_EOK)
-		{
-			result = rt_sem_trytake(&(rwlock->rw_condwriters.sem));
-			if (result == RT_EOK)
-			{
-				rt_sem_release(&(rwlock->rw_condreaders.sem));
-				rt_sem_release(&(rwlock->rw_condwriters.sem));
-
-				pthread_cond_destroy(&rwlock->rw_condreaders);
-				pthread_cond_destroy(&rwlock->rw_condwriters);
-			}
-			else
-			{
-				rt_sem_release(&(rwlock->rw_condreaders.sem));
-				result = EBUSY;
-			}
-		}
-		else result = EBUSY;
-	}
-
-	pthread_mutex_unlock(&rwlock->rw_mutex);
-	if (result == 0) pthread_mutex_destroy(&rwlock->rw_mutex);
-	
-	return result;
+    int result;
+
+    if (!rwlock)
+        return EINVAL;
+    if (rwlock->attr == -1)
+        return 0; /* rwlock is not initialized */
+
+    if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+        return(result);
+
+    if (rwlock->rw_refcount != 0 ||
+        rwlock->rw_nwaitreaders != 0 ||
+        rwlock->rw_nwaitwriters != 0)
+    {
+        result = EBUSY;
+
+        return(EBUSY);
+    }
+    else
+    {
+        /* check whether busy */
+        result = rt_sem_trytake(&(rwlock->rw_condreaders.sem));
+        if (result == RT_EOK)
+        {
+            result = rt_sem_trytake(&(rwlock->rw_condwriters.sem));
+            if (result == RT_EOK)
+            {
+                rt_sem_release(&(rwlock->rw_condreaders.sem));
+                rt_sem_release(&(rwlock->rw_condwriters.sem));
+
+                pthread_cond_destroy(&rwlock->rw_condreaders);
+                pthread_cond_destroy(&rwlock->rw_condwriters);
+            }
+            else
+            {
+                rt_sem_release(&(rwlock->rw_condreaders.sem));
+                result = EBUSY;
+            }
+        }
+        else
+            result = EBUSY;
+    }
+
+    pthread_mutex_unlock(&rwlock->rw_mutex);
+    if (result == 0)
+        pthread_mutex_destroy(&rwlock->rw_mutex);
+    
+    return result;
 }
 RTM_EXPORT(pthread_rwlock_destroy);
 
-int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
+int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
 {
-	int result;
-
-	if (!rwlock) return EINVAL;
-	if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
-
-	if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
-		return(result);
-
-	/* give preference to waiting writers */
-	while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
-	{
-		rwlock->rw_nwaitreaders++;
-		/* rw_mutex will be released when waiting for rw_condreaders */
-		result = pthread_cond_wait(&rwlock->rw_condreaders, &rwlock->rw_mutex);
-		/* rw_mutex should have been taken again when returned from waiting */
-		rwlock->rw_nwaitreaders--;
-		if (result != 0) /* wait error */
-			break;
-	}
-
-	/* another reader has a read lock */
-	if (result == 0) rwlock->rw_refcount++;
-
-	pthread_mutex_unlock(&rwlock->rw_mutex);
-	return (result);
+    int result;
+
+    if (!rwlock)
+        return EINVAL;
+    if (rwlock->attr == -1)
+        pthread_rwlock_init(rwlock, NULL);
+
+    if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+        return(result);
+
+    /* give preference to waiting writers */
+    while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
+    {
+        rwlock->rw_nwaitreaders++;
+        /* rw_mutex will be released when waiting for rw_condreaders */
+        result = pthread_cond_wait(&rwlock->rw_condreaders, &rwlock->rw_mutex);
+        /* rw_mutex should have been taken again when returned from waiting */
+        rwlock->rw_nwaitreaders--;
+        if (result != 0) /* wait error */
+            break;
+    }
+
+    /* another reader has a read lock */
+    if (result == 0)
+        rwlock->rw_refcount++;
+
+    pthread_mutex_unlock(&rwlock->rw_mutex);
+
+    return (result);
 }
 RTM_EXPORT(pthread_rwlock_rdlock);
 
-int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
 {
-	int result;
+    int result;
 
-	if (!rwlock) return EINVAL;
-	if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
+    if (!rwlock)
+        return EINVAL;
+    if (rwlock->attr == -1)
+        pthread_rwlock_init(rwlock, NULL);
 
-	if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
-		return(result);
+    if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+        return(result);
 
-	if (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
-		result = EBUSY;                 /* held by a writer or waiting writers */
-	else
-		rwlock->rw_refcount++;          /* increment count of reader locks */
+    if (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
+        result = EBUSY;                 /* held by a writer or waiting writers */
+    else
+        rwlock->rw_refcount++;          /* increment count of reader locks */
 
-	pthread_mutex_unlock(&rwlock->rw_mutex);
-	return(result);
+    pthread_mutex_unlock(&rwlock->rw_mutex);
+
+    return(result);
 }
 RTM_EXPORT(pthread_rwlock_tryrdlock);
 
-int pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock, const struct timespec *abstime)
+int pthread_rwlock_timedrdlock(pthread_rwlock_t      *rwlock,
+                               const struct timespec *abstime)
 {
-	int result;
-
-	if (!rwlock) return EINVAL;
-	if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
-
-	if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
-		return(result);
-
-	/* give preference to waiting writers */
-	while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
-	{
-		rwlock->rw_nwaitreaders++;
-		/* rw_mutex will be released when waiting for rw_condreaders */
-		result = pthread_cond_timedwait(&rwlock->rw_condreaders, &rwlock->rw_mutex, abstime);
-		/* rw_mutex should have been taken again when returned from waiting */
-		rwlock->rw_nwaitreaders--;
-		if (result != 0)
-			break;
-	}
-
-	/* another reader has a read lock */
-	if (result == 0) rwlock->rw_refcount++;
-
-	pthread_mutex_unlock(&rwlock->rw_mutex);
-	return (result);
+    int result;
+
+    if (!rwlock)
+        return EINVAL;
+    if (rwlock->attr == -1)
+        pthread_rwlock_init(rwlock, NULL);
+
+    if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+        return(result);
+
+    /* give preference to waiting writers */
+    while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
+    {
+        rwlock->rw_nwaitreaders++;
+        /* rw_mutex will be released when waiting for rw_condreaders */
+        result = pthread_cond_timedwait(&rwlock->rw_condreaders, &rwlock->rw_mutex, abstime);
+        /* rw_mutex should have been taken again when returned from waiting */
+        rwlock->rw_nwaitreaders--;
+        if (result != 0)
+            break;
+    }
+
+    /* another reader has a read lock */
+    if (result == 0)
+        rwlock->rw_refcount++;
+
+    pthread_mutex_unlock(&rwlock->rw_mutex);
+
+    return (result);
 }
 RTM_EXPORT(pthread_rwlock_timedrdlock);
 
-int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, const struct timespec *abstime)
+int pthread_rwlock_timedwrlock(pthread_rwlock_t      *rwlock,
+                               const struct timespec *abstime)
 {
-	int result;
-
-	if (!rwlock) return EINVAL;
-	if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
-
-	if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
-		return(result);
-
-	while (rwlock->rw_refcount != 0)
-	{
-		rwlock->rw_nwaitwriters++;
-		/* rw_mutex will be released when waiting for rw_condwriters */
-		result = pthread_cond_timedwait(&rwlock->rw_condwriters, &rwlock->rw_mutex, abstime);
-		/* rw_mutex should have been taken again when returned from waiting */
-		rwlock->rw_nwaitwriters--;
-		
-		if (result != 0) break;
-	}
-
-	if (result == 0) rwlock->rw_refcount = -1;
-
-	pthread_mutex_unlock(&rwlock->rw_mutex);
-	return(result);
+    int result;
+
+    if (!rwlock)
+        return EINVAL;
+    if (rwlock->attr == -1)
+        pthread_rwlock_init(rwlock, NULL);
+
+    if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+        return(result);
+
+    while (rwlock->rw_refcount != 0)
+    {
+        rwlock->rw_nwaitwriters++;
+        /* rw_mutex will be released when waiting for rw_condwriters */
+        result = pthread_cond_timedwait(&rwlock->rw_condwriters, &rwlock->rw_mutex, abstime);
+        /* rw_mutex should have been taken again when returned from waiting */
+        rwlock->rw_nwaitwriters--;
+        
+        if (result != 0)
+            break;
+    }
+
+    if (result == 0)
+        rwlock->rw_refcount = -1;
+
+    pthread_mutex_unlock(&rwlock->rw_mutex);
+
+    return(result);
 }
 RTM_EXPORT(pthread_rwlock_timedwrlock);
 
-int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
 {
-	int result;
+    int result;
+
+    if (!rwlock)
+        return EINVAL;
+    if (rwlock->attr == -1)
+        pthread_rwlock_init(rwlock, NULL);
 
-	if (!rwlock) return EINVAL;
-	if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
+    if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+        return(result);
 
-	if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
-		return(result);
+    if (rwlock->rw_refcount != 0)
+        result = EBUSY;                 /* held by either writer or reader(s) */
+    else
+        rwlock->rw_refcount = -1;       /* available, indicate a writer has it */
 
-	if (rwlock->rw_refcount != 0)
-		result = EBUSY;                 /* held by either writer or reader(s) */
-	else
-		rwlock->rw_refcount = -1;   	/* available, indicate a writer has it */
+    pthread_mutex_unlock(&rwlock->rw_mutex);
 
-	pthread_mutex_unlock(&rwlock->rw_mutex);
-	return(result);
+    return(result);
 }
 RTM_EXPORT(pthread_rwlock_trywrlock);
 
-int pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
 {
-	int result;
-
-	if (!rwlock) return EINVAL;
-	if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
-
-	if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
-		return(result);
-
-	if (rwlock->rw_refcount > 0)
-		rwlock->rw_refcount--;              /* releasing a reader */
-	else if (rwlock->rw_refcount == -1)
-		rwlock->rw_refcount = 0;            /* releasing a writer */
-
-	/* give preference to waiting writers over waiting readers */
-	if (rwlock->rw_nwaitwriters > 0)
-	{
-		if (rwlock->rw_refcount == 0)
-			result = pthread_cond_signal(&rwlock->rw_condwriters);
-	}
-	else if (rwlock->rw_nwaitreaders > 0)
-	{
-		result = pthread_cond_broadcast(&rwlock->rw_condreaders);
-	}
-
-	pthread_mutex_unlock(&rwlock->rw_mutex);
-	return(result);
+    int result;
+
+    if (!rwlock)
+        return EINVAL;
+    if (rwlock->attr == -1)
+        pthread_rwlock_init(rwlock, NULL);
+
+    if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+        return(result);
+
+    if (rwlock->rw_refcount > 0)
+        rwlock->rw_refcount--;              /* releasing a reader */
+    else if (rwlock->rw_refcount == -1)
+        rwlock->rw_refcount = 0;            /* releasing a writer */
+
+    /* give preference to waiting writers over waiting readers */
+    if (rwlock->rw_nwaitwriters > 0)
+    {
+        if (rwlock->rw_refcount == 0)
+            result = pthread_cond_signal(&rwlock->rw_condwriters);
+    }
+    else if (rwlock->rw_nwaitreaders > 0)
+    {
+        result = pthread_cond_broadcast(&rwlock->rw_condreaders);
+    }
+
+    pthread_mutex_unlock(&rwlock->rw_mutex);
+
+    return(result);
 }
 RTM_EXPORT(pthread_rwlock_unlock);
 
-int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
+int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
 {
-	int result;
-
-	if (!rwlock) return EINVAL;
-	if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
-
-	if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
-		return(result);
-
-	while (rwlock->rw_refcount != 0)
-	{
-		rwlock->rw_nwaitwriters++;
-		/* rw_mutex will be released when waiting for rw_condwriters */
-		result = pthread_cond_wait(&rwlock->rw_condwriters, &rwlock->rw_mutex);
-		/* rw_mutex should have been taken again when returned from waiting */
-		rwlock->rw_nwaitwriters--;
-		
-		if (result != 0) break;
-	}
-
-	if (result == 0) rwlock->rw_refcount = -1;
-
-	pthread_mutex_unlock(&rwlock->rw_mutex);
-	return(result);
+    int result;
+
+    if (!rwlock)
+        return EINVAL;
+    if (rwlock->attr == -1)
+        pthread_rwlock_init(rwlock, NULL);
+
+    if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+        return(result);
+
+    while (rwlock->rw_refcount != 0)
+    {
+        rwlock->rw_nwaitwriters++;
+        /* rw_mutex will be released when waiting for rw_condwriters */
+        result = pthread_cond_wait(&rwlock->rw_condwriters, &rwlock->rw_mutex);
+        /* rw_mutex should have been taken again when returned from waiting */
+        rwlock->rw_nwaitwriters--;
+        
+        if (result != 0)
+            break;
+    }
+
+    if (result == 0)
+        rwlock->rw_refcount = -1;
+
+    pthread_mutex_unlock(&rwlock->rw_mutex);
+
+    return(result);
 }
 RTM_EXPORT(pthread_rwlock_wrlock);
 

+ 54 - 22
components/pthreads/pthread_spin.c

@@ -1,51 +1,83 @@
+/*
+ * File      : pthread_spin.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 <pthread.h>
 
 int pthread_spin_init (pthread_spinlock_t *lock, int pshared)
 {
-	if (!lock) return EINVAL;
+    if (!lock)
+        return EINVAL;
+
+    lock->lock = 0;
 
-	lock->lock = 0;
-	return 0;
+    return 0;
 }
 
 int pthread_spin_destroy (pthread_spinlock_t *lock)
 {
-	if (!lock) return EINVAL;
+    if (!lock)
+        return EINVAL;
 
-	return 0;
+    return 0;
 }
 
 int pthread_spin_lock (pthread_spinlock_t *lock)
 {
-	if (!lock) return EINVAL;
+    if (!lock)
+        return EINVAL;
 
-	while (!(lock->lock))
-	{
-		lock->lock = 1;
-	}
+    while (!(lock->lock))
+    {
+        lock->lock = 1;
+    }
 
-	return 0;
+    return 0;
 }
 
 int pthread_spin_trylock (pthread_spinlock_t *lock)
 {
-	if (!lock) return EINVAL;
+    if (!lock)
+        return EINVAL;
+
+    if (!(lock->lock))
+    {
+        lock->lock = 1;
 
-	if (!(lock->lock))
-	{
-		lock->lock = 1;
-		return 0;
-	}
+        return 0;
+    }
 
-	return EBUSY;
+    return EBUSY;
 }
 
 int pthread_spin_unlock (pthread_spinlock_t *lock)
 {
-	if (!lock) return EINVAL;
-	if (!(lock->lock)) return EPERM;
+    if (!lock)
+        return EINVAL;
+    if (!(lock->lock))
+        return EPERM;
 
-	lock->lock = 0;
+    lock->lock = 0;
 
-	return 0;
+    return 0;
 }

+ 72 - 43
components/pthreads/pthread_tls.c

@@ -1,3 +1,27 @@
+/*
+ * File      : pthread_tls.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 <pthread.h>
 #include "pthread_internal.h"
 
@@ -5,82 +29,87 @@ _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX];
 
 void pthread_key_system_init()
 {
-	rt_memset(&_thread_keys[0], 0, sizeof(_thread_keys));
+    rt_memset(&_thread_keys[0], 0, sizeof(_thread_keys));
 }
 
 void *pthread_getspecific(pthread_key_t key)
 {
-	struct _pthread_data* ptd;
+    struct _pthread_data* ptd;
 
-	ptd = _pthread_get_data(rt_thread_self());
-	RT_ASSERT(ptd != NULL);
+    ptd = _pthread_get_data(rt_thread_self());
+    RT_ASSERT(ptd != NULL);
 
-	if (ptd->tls == NULL) return NULL;
+    if (ptd->tls == NULL)
+        return NULL;
 
-	if ((key < PTHREAD_KEY_MAX) && (_thread_keys[key].is_used))
-		return ptd->tls[key];
+    if ((key < PTHREAD_KEY_MAX) && (_thread_keys[key].is_used))
+        return ptd->tls[key];
 
-	return NULL;
+    return NULL;
 }
 RTM_EXPORT(pthread_getspecific);
 
 int pthread_setspecific(pthread_key_t key, const void *value)
 {
-	struct _pthread_data* ptd;
+    struct _pthread_data* ptd;
+
+    ptd = _pthread_get_data(rt_thread_self());
+    RT_ASSERT(ptd != NULL);
 
-	ptd = _pthread_get_data(rt_thread_self());
-	RT_ASSERT(ptd != NULL);
+    /* check tls area */
+    if (ptd->tls == NULL)
+    {
+        ptd->tls = (void**)rt_malloc(sizeof(void*) * PTHREAD_KEY_MAX);
+    }
 
-	/* check tls area */
-	if (ptd->tls == NULL)
-	{
-		ptd->tls = (void**)rt_malloc(sizeof(void*) * PTHREAD_KEY_MAX);
-	}
+    if ((key < PTHREAD_KEY_MAX) && _thread_keys[key].is_used)
+    {
+        ptd->tls[key] = (void *)value;
 
-	if ((key < PTHREAD_KEY_MAX) && _thread_keys[key].is_used)
-	{
-		ptd->tls[key] = (void *)value;
-		return 0;
-	}
+        return 0;
+    }
 
-	return EINVAL;
+    return EINVAL;
 }
 RTM_EXPORT(pthread_setspecific);
 
 int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
 {
-	rt_uint32_t index;
+    rt_uint32_t index;
+
+    rt_enter_critical();
+    for (index = 0; index < PTHREAD_KEY_MAX; index ++)
+    {
+        if (_thread_keys[index].is_used == 0)
+        {
+            _thread_keys[index].is_used = 1;
+            _thread_keys[index].destructor = destructor;
+
+            *key = index;
 
-	rt_enter_critical();
-	for (index = 0; index < PTHREAD_KEY_MAX; index ++)
-	{
-		if (_thread_keys[index].is_used == 0)
-		{
-			_thread_keys[index].is_used = 1;
-			_thread_keys[index].destructor = destructor;
+            rt_exit_critical();
 
-			*key = index;
+            return 0;
+        }
+    }
 
-			rt_exit_critical();
-			return 0;
-		}
-	}
+    rt_exit_critical();
 
-	rt_exit_critical();
-	return EAGAIN;
+    return EAGAIN;
 }
 RTM_EXPORT(pthread_key_create);
 
 int pthread_key_delete(pthread_key_t key)
 {
-	if (key >= PTHREAD_KEY_MAX) return EINVAL;
+    if (key >= PTHREAD_KEY_MAX)
+        return EINVAL;
 
-	rt_enter_critical();
-	_thread_keys[key].is_used = 0;
-	_thread_keys[key].destructor = 0;
-	rt_exit_critical();
+    rt_enter_critical();
+    _thread_keys[key].is_used = 0;
+    _thread_keys[key].destructor = 0;
+    rt_exit_critical();
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(pthread_key_delete);
 

+ 33 - 9
components/pthreads/sched.c

@@ -1,32 +1,56 @@
+/*
+ * File      : sched.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
+ */
+
 #include <sched.h>
 
 int sched_yield(void)
 {
-	rt_thread_yield();
-	return 0;
+    rt_thread_yield();
+
+    return 0;
 }
 RTM_EXPORT(sched_yield);
 
 int sched_get_priority_min(int policy)
 {
-	if (policy != SCHED_FIFO && policy != SCHED_RR)
-		return EINVAL;
+    if (policy != SCHED_FIFO && policy != SCHED_RR)
+        return EINVAL;
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(sched_get_priority_min);
 
 int sched_get_priority_max(int policy)
 {
-	if (policy != SCHED_FIFO && policy != SCHED_RR)
-		return EINVAL;
+    if (policy != SCHED_FIFO && policy != SCHED_RR)
+        return EINVAL;
 
-	return RT_THREAD_PRIORITY_MAX - 1;
+    return RT_THREAD_PRIORITY_MAX - 1;
 }
 RTM_EXPORT(sched_get_priority_max);
 
 int sched_setscheduler(pid_t pid, int policy)
 {
-	return ENOTSUP;
+    return ENOTSUP;
 }
 RTM_EXPORT(sched_setscheduler);

+ 29 - 6
components/pthreads/sched.h

@@ -1,3 +1,26 @@
+/*
+ * File      : sched.h
+ * 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
+ */
+
 #ifndef __SCHED_H__
 #define __SCHED_H__
 
@@ -7,16 +30,16 @@
 /* Thread scheduling policies */
 enum
 {
-	SCHED_OTHER = 0,
-	SCHED_FIFO,
-	SCHED_RR,
-	SCHED_MIN = SCHED_OTHER,
-	SCHED_MAX = SCHED_RR
+    SCHED_OTHER = 0,
+    SCHED_FIFO,
+    SCHED_RR,
+    SCHED_MIN = SCHED_OTHER,
+    SCHED_MAX = SCHED_RR
 };
 
 struct sched_param
 {
-	int sched_priority;
+    int sched_priority;
 };
 
 #ifdef __cplusplus

+ 272 - 222
components/pthreads/semaphore.c

@@ -1,85 +1,111 @@
+/*
+ * File      : semaphore.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 "semaphore.h"
 #include "pthread_internal.h"
 
-static sem_t* posix_sem_list = RT_NULL;
+static sem_t *posix_sem_list = RT_NULL;
 static struct rt_semaphore posix_sem_lock;
 void posix_sem_system_init()
 {
-	rt_sem_init(&posix_sem_lock, "psem", 1, RT_IPC_FLAG_FIFO);
+    rt_sem_init(&posix_sem_lock, "psem", 1, RT_IPC_FLAG_FIFO);
 }
 
 rt_inline void posix_sem_insert(sem_t *psem)
 {
-	psem->next = posix_sem_list;
-	posix_sem_list = psem;
+    psem->next = posix_sem_list;
+    posix_sem_list = psem;
 }
 
 static void posix_sem_delete(sem_t *psem)
 {
-	sem_t *iter;
-	if (posix_sem_list == psem)
-	{
-		posix_sem_list = psem->next;
-
-		rt_sem_delete(psem->sem);
-		rt_free(psem);
-
-		return;
-	}
-	for (iter = posix_sem_list; iter->next != RT_NULL; iter = iter->next)
-	{
-		if (iter->next == psem)
-		{
-			/* delete this mq */
-			if (psem->next != RT_NULL)
-				iter->next = psem->next;
-			else
-				iter->next = RT_NULL;
-
-			/* delete RT-Thread mqueue */
-			rt_sem_delete(psem->sem);
-			rt_free(psem);
-			return ;
-		}
-	}
+    sem_t *iter;
+    if (posix_sem_list == psem)
+    {
+        posix_sem_list = psem->next;
+
+        rt_sem_delete(psem->sem);
+        rt_free(psem);
+
+        return;
+    }
+    for (iter = posix_sem_list; iter->next != RT_NULL; iter = iter->next)
+    {
+        if (iter->next == psem)
+        {
+            /* delete this mq */
+            if (psem->next != RT_NULL)
+                iter->next = psem->next;
+            else
+                iter->next = RT_NULL;
+
+            /* delete RT-Thread mqueue */
+            rt_sem_delete(psem->sem);
+            rt_free(psem);
+
+            return ;
+        }
+    }
 }
 
 static sem_t *posix_sem_find(const char* name)
 {
-	sem_t *iter;
-	rt_object_t object;
-
-	for (iter = posix_sem_list; iter != RT_NULL; iter = iter->next)
-	{
-		object = (rt_object_t)&(iter->sem);
-
-		if (strncmp(object->name, name, RT_NAME_MAX) == 0)
-		{
-			return iter;
-		}
-	}
-	
-	return RT_NULL;
+    sem_t *iter;
+    rt_object_t object;
+
+    for (iter = posix_sem_list; iter != RT_NULL; iter = iter->next)
+    {
+        object = (rt_object_t)&(iter->sem);
+
+        if (strncmp(object->name, name, RT_NAME_MAX) == 0)
+        {
+            return iter;
+        }
+    }
+    
+    return RT_NULL;
 }
 
 int sem_close(sem_t *sem)
 {
-	if (sem == RT_NULL)
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+    if (sem == RT_NULL)
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
 
     /* lock posix semaphore list */
     rt_sem_take(&posix_sem_lock, RT_WAITING_FOREVER);
     sem->refcount --;
     if (sem->refcount == 0)
     {
-    	/* delete from posix semaphore list */
-    	if (sem->unlinked)
-    		posix_sem_delete(sem);
-    	sem = RT_NULL;
+        /* delete from posix semaphore list */
+        if (sem->unlinked)
+            posix_sem_delete(sem);
+        sem = RT_NULL;
     }
     rt_sem_release(&posix_sem_lock);
 
@@ -89,13 +115,14 @@ RTM_EXPORT(sem_close);
 
 int sem_destroy(sem_t *sem)
 {
-	rt_err_t result;
+    rt_err_t result;
+
+    if ((!sem) || !(sem->unamed))
+    {
+        rt_set_errno(EINVAL);
 
-	if ((!sem) || !(sem->unamed))
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+        return -1;
+    }
 
     /* lock posix semaphore list */
     rt_sem_take(&posix_sem_lock, RT_WAITING_FOREVER);
@@ -104,11 +131,12 @@ int sem_destroy(sem_t *sem)
     {
         rt_sem_release(&posix_sem_lock);
         rt_set_errno(EBUSY);
-    	return -1;
+
+        return -1;
     }
 
     /* destroy an unamed posix semaphore */
-   	posix_sem_delete(sem);
+    posix_sem_delete(sem);
     rt_sem_release(&posix_sem_lock);
 
     return 0;
@@ -117,234 +145,256 @@ RTM_EXPORT(sem_destroy);
 
 int sem_unlink(const char *name)
 {
-	sem_t *psem;
+    sem_t *psem;
 
     /* lock posix semaphore list */
     rt_sem_take(&posix_sem_lock, RT_WAITING_FOREVER);
     psem = posix_sem_find(name);
     if (psem != RT_NULL)
     {
-    	psem->unlinked = 1;
-    	if (psem->refcount == 0)
-    	{
-    		/* remove this semaphore */
-    		posix_sem_delete(psem);
-    	}
+        psem->unlinked = 1;
+        if (psem->refcount == 0)
+        {
+            /* remove this semaphore */
+            posix_sem_delete(psem);
+        }
         rt_sem_release(&posix_sem_lock);
+
         return 0;
     }
     rt_sem_release(&posix_sem_lock);
 
     /* no this entry */
     rt_set_errno(ENOENT);
+
     return -1;
 }
 RTM_EXPORT(sem_unlink);
 
 int sem_getvalue(sem_t *sem, int *sval)
 {
-	if (!sem || !sval)
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
-	*sval = sem->sem->value;
-	return 0;
+    if (!sem || !sval)
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
+    *sval = sem->sem->value;
+
+    return 0;
 }
 RTM_EXPORT(sem_getvalue);
 
 int sem_init(sem_t *sem, int pshared, unsigned int value)
 {
-	char name[RT_NAME_MAX];
-	static rt_uint16_t psem_number = 0;
-
-	if (sem == RT_NULL)
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
-
-	rt_snprintf(name, sizeof(name), "psem%02d", psem_number++);
-	sem->sem = rt_sem_create(name, value, RT_IPC_FLAG_FIFO);
-	if (sem == RT_NULL)
-	{
-		rt_set_errno(ENOMEM);
-		return -1;
-	}
-
-	/* initialize posix semaphore */
-	sem->refcount = 1;
-	sem->unlinked = 0;
-	sem->unamed = 1;
+    char name[RT_NAME_MAX];
+    static rt_uint16_t psem_number = 0;
+
+    if (sem == RT_NULL)
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
+
+    rt_snprintf(name, sizeof(name), "psem%02d", psem_number++);
+    sem->sem = rt_sem_create(name, value, RT_IPC_FLAG_FIFO);
+    if (sem == RT_NULL)
+    {
+        rt_set_errno(ENOMEM);
+
+        return -1;
+    }
+
+    /* initialize posix semaphore */
+    sem->refcount = 1;
+    sem->unlinked = 0;
+    sem->unamed = 1;
     /* lock posix semaphore list */
     rt_sem_take(&posix_sem_lock, RT_WAITING_FOREVER);
     posix_sem_insert(sem);
     rt_sem_release(&posix_sem_lock);
 
-	return 0;
+    return 0;
 }
 RTM_EXPORT(sem_init);
 
 sem_t *sem_open(const char *name, int oflag, ...)
 {
-	sem_t* sem;
-	va_list arg;
-	mode_t mode;
-	unsigned int value;
+    sem_t* sem;
+    va_list arg;
+    mode_t mode;
+    unsigned int value;
 
     sem = RT_NULL;
 
     /* lock posix semaphore list */
     rt_sem_take(&posix_sem_lock, RT_WAITING_FOREVER);
-	if (oflag & O_CREAT)
-	{
-		va_start(arg, oflag);
-		mode = (mode_t) va_arg( arg, unsigned int); mode = mode;
-		value = va_arg( arg, unsigned int);
-		va_end(arg);
-
-	    if (oflag & O_EXCL)
-	    {
-	    	if (posix_sem_find(name) != RT_NULL)
-	    	{
-	    		rt_set_errno(EEXIST);
-	    		goto __return;
-	    	}
-	    }
-	    sem = (sem_t*) rt_malloc (sizeof(struct posix_sem));
-	    if (sem == RT_NULL)
-	    {
-	    	rt_set_errno(ENFILE);
-	    	goto __return;
-	    }
-
-	    /* create RT-Thread semaphore */
-	    sem->sem = rt_sem_create(name, value, RT_IPC_FLAG_FIFO);
-		if (sem->sem == RT_NULL) /* create failed */
-		{
-			rt_set_errno(ENFILE);
-			goto __return;
-		}
-		/* initialize reference count */
-		sem->refcount = 1;
-		sem->unlinked = 0;
-		sem->unamed = 0;
-
-		/* insert semaphore to posix semaphore list */
-		posix_sem_insert(sem);
-	}
-	else
-	{
-		/* find semaphore */
-		sem = posix_sem_find(name);
-		if (sem != RT_NULL)
-		{
-			sem->refcount ++; /* increase reference count */
-		}
-		else
-		{
-			rt_set_errno(ENOENT);
-			goto __return;
-		}
-	}
-	rt_sem_release(&posix_sem_lock);
-	return sem;
+    if (oflag & O_CREAT)
+    {
+        va_start(arg, oflag);
+        mode = (mode_t) va_arg( arg, unsigned int); mode = mode;
+        value = va_arg( arg, unsigned int);
+        va_end(arg);
+
+        if (oflag & O_EXCL)
+        {
+            if (posix_sem_find(name) != RT_NULL)
+            {
+                rt_set_errno(EEXIST);
+                goto __return;
+            }
+        }
+        sem = (sem_t*) rt_malloc (sizeof(struct posix_sem));
+        if (sem == RT_NULL)
+        {
+            rt_set_errno(ENFILE);
+            goto __return;
+        }
+
+        /* create RT-Thread semaphore */
+        sem->sem = rt_sem_create(name, value, RT_IPC_FLAG_FIFO);
+        if (sem->sem == RT_NULL) /* create failed */
+        {
+            rt_set_errno(ENFILE);
+            goto __return;
+        }
+        /* initialize reference count */
+        sem->refcount = 1;
+        sem->unlinked = 0;
+        sem->unamed = 0;
+
+        /* insert semaphore to posix semaphore list */
+        posix_sem_insert(sem);
+    }
+    else
+    {
+        /* find semaphore */
+        sem = posix_sem_find(name);
+        if (sem != RT_NULL)
+        {
+            sem->refcount ++; /* increase reference count */
+        }
+        else
+        {
+            rt_set_errno(ENOENT);
+            goto __return;
+        }
+    }
+    rt_sem_release(&posix_sem_lock);
+
+    return sem;
 
 __return:
-	/* release lock */
-	rt_sem_release(&posix_sem_lock);
-
-	/* release allocated memory */
-	if (sem != RT_NULL)
-	{
-		/* delete RT-Thread semaphore */
-		if (sem->sem != RT_NULL)
-			rt_sem_delete(sem->sem);
-		rt_free(sem);
-	}
-	return RT_NULL;
+    /* release lock */
+    rt_sem_release(&posix_sem_lock);
+
+    /* release allocated memory */
+    if (sem != RT_NULL)
+    {
+        /* delete RT-Thread semaphore */
+        if (sem->sem != RT_NULL)
+            rt_sem_delete(sem->sem);
+        rt_free(sem);
+    }
+
+    return RT_NULL;
 }
 RTM_EXPORT(sem_open);
 
 int sem_post(sem_t *sem)
 {
-	rt_err_t result;
+    rt_err_t result;
+
+    if (!sem)
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
 
-	if (!sem)
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+    result = rt_sem_release(sem->sem);
+    if (result == RT_EOK)
+        return 0;
 
-	result = rt_sem_release(sem->sem);
-	if (result == RT_EOK) return 0;
+    rt_set_errno(EINVAL);
 
-	rt_set_errno(EINVAL);
-	return -1;
+    return -1;
 }
 RTM_EXPORT(sem_post);
 
 int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
 {
-	rt_err_t result;
-	rt_int32_t tick;
-
-	if (!sem || !abs_timeout) return EINVAL;
-
-	/* calculate os tick */
-	tick = clock_time_to_tick(abs_timeout);
-	
-	result = rt_sem_take(sem->sem, tick);
-	if (result == -RT_ETIMEOUT)
-	{
-		rt_set_errno(ETIMEDOUT);
-		return -1;
-	}
-	if (result == RT_EOK) return 0;
-
-	rt_set_errno(EINTR);
-	return -1;
+    rt_err_t result;
+    rt_int32_t tick;
+
+    if (!sem || !abs_timeout)
+        return EINVAL;
+
+    /* calculate os tick */
+    tick = clock_time_to_tick(abs_timeout);
+    
+    result = rt_sem_take(sem->sem, tick);
+    if (result == -RT_ETIMEOUT)
+    {
+        rt_set_errno(ETIMEDOUT);
+
+        return -1;
+    }
+    if (result == RT_EOK)
+        return 0;
+
+    rt_set_errno(EINTR);
+
+    return -1;
 }
 RTM_EXPORT(sem_timedwait);
 
 int sem_trywait(sem_t *sem)
 {
-	rt_err_t result;
-
-	if (!sem)
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
-
-	result = rt_sem_take(sem->sem, RT_WAITING_FOREVER);
-	if (result == -RT_ETIMEOUT)
-	{
-		rt_set_errno(EAGAIN);
-		return -1;
-	}
-	if (result == RT_EOK) return 0;
-
-	rt_set_errno(EINTR);
-	return -1;
+    rt_err_t result;
+
+    if (!sem)
+    {
+        rt_set_errno(EINVAL);
+
+        return -1;
+    }
+
+    result = rt_sem_take(sem->sem, RT_WAITING_FOREVER);
+    if (result == -RT_ETIMEOUT)
+    {
+        rt_set_errno(EAGAIN);
+
+        return -1;
+    }
+    if (result == RT_EOK)
+        return 0;
+
+    rt_set_errno(EINTR);
+
+    return -1;
 }
 RTM_EXPORT(sem_trywait);
 
 int sem_wait(sem_t *sem)
 {
-	rt_err_t result;
+    rt_err_t result;
 
-	if (!sem)
-	{
-		rt_set_errno(EINVAL);
-		return -1;
-	}
+    if (!sem)
+    {
+        rt_set_errno(EINVAL);
 
-	result = rt_sem_take(sem->sem, RT_WAITING_FOREVER);
-	if (result == RT_EOK) return 0;
+        return -1;
+    }
 
-	rt_set_errno(EINTR);
-	return -1;
+    result = rt_sem_take(sem->sem, RT_WAITING_FOREVER);
+    if (result == RT_EOK)
+        return 0;
+
+    rt_set_errno(EINTR);
+
+    return -1;
 }
 RTM_EXPORT(sem_wait);
 

+ 32 - 8
components/pthreads/semaphore.h

@@ -1,3 +1,27 @@
+/*
+ * File      : semaphore.h
+ * 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
+ */
+
 #ifndef __POSIX_SEMAPHORE_H__
 #define __POSIX_SEMAPHORE_H__
 
@@ -6,16 +30,16 @@
 
 struct posix_sem
 {
-	/* reference count and unlinked */
-	rt_uint16_t refcount;
-	rt_uint8_t unlinked;
-	rt_uint8_t unamed;
+    /* reference count and unlinked */
+    rt_uint16_t refcount;
+    rt_uint8_t unlinked;
+    rt_uint8_t unamed;
 
-	/* RT-Thread semaphore */
-	rt_sem_t sem;
+    /* RT-Thread semaphore */
+    rt_sem_t sem;
 
-	/* next posix semaphore */
-	struct posix_sem* next;
+    /* next posix semaphore */
+    struct posix_sem* next;
 };
 typedef struct posix_sem sem_t;