提交 54228a05 编写于 作者: B bernard.xiong

porting pthread to ARMCC compiler;

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1286 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 397efc12
#include <rtthread.h>
#include <time.h>
#include <errno.h>
#include "libc.h"
int clock_getres(clockid_t clock_id, struct timespec *res)
{
if ((clock_id != CLOCK_REALTIME) || (res == RT_NULL))
{
rt_set_errno(EINVAL);
return -1;
}
res->tv_sec = 0;
res->tv_nsec = NANOSECOND_PER_TICK;
return 0;
}
int clock_gettime(clockid_t clock_id, struct timespec *tp)
{
if ((clock_id != CLOCK_REALTIME) || (tp == RT_NULL))
{
rt_set_errno(EINVAL);
return -1;
}
libc_get_time(tp);
return 0;
}
int clock_settime(clockid_t clock_id, const struct timespec *tp)
{
if ((clock_id != CLOCK_REALTIME) || (tp == RT_NULL))
{
rt_set_errno(EINVAL);
return -1;
}
libc_set_time(tp);
return 0;
}
......@@ -5,95 +5,6 @@
#include <sys/time.h>
#include "libc.h"
struct timeval _timevalue;
static void libc_system_time_init()
{
time_t time;
rt_tick_t tick;
rt_device_t device;
time = 0;
device = rt_device_find("rtc");
if (device != RT_NULL)
{
/* get realtime seconds */
rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
}
/* get tick */
tick = rt_tick_get();
_timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
_timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1;
}
int libc_get_time(struct timespec *time)
{
rt_tick_t tick;
RT_ASSERT(time != RT_NULL);
/* get tick */
tick = rt_tick_get();
time->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND;
time->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * NANOSECOND_PER_TICK) * 1000;
return 0;
}
int libc_set_time(const struct timespec *time)
{
int second;
rt_tick_t tick;
rt_device_t device;
second = time->tv_sec;
device = rt_device_find("rtc");
if (device != RT_NULL)
{
/* get realtime seconds */
rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second);
}
else return -1;
/* get tick */
tick = rt_tick_get();
/* 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;
return 0;
}
int libc_time_to_tick(const struct timespec *time)
{
int tick;
int microsecond, second;
RT_ASSERT(time != RT_NULL);
tick = RT_WAITING_FOREVER;
if (time != NULL)
{
if ((time->tv_nsec/1000 - _timevalue.tv_usec) < 0)
{
microsecond = (1000000UL + time->tv_nsec/1000) - _timevalue.tv_usec;
second = time->tv_sec - 1;
}
else
{
microsecond = time->tv_nsec/1000 - _timevalue.tv_usec;
second = time->tv_sec;
}
tick = second * RT_TICK_PER_SECOND + microsecond * RT_TICK_PER_SECOND / MICROSECOND_PER_SECOND;
if (tick < 0) tick = 0;
}
return tick;
}
void libc_system_init(const char* tty_name)
{
int fd;
......@@ -115,8 +26,6 @@ void libc_system_init(const char* tty_name)
putenv("PATH=/");
putenv("HOME=/");
/* initialize system time */
libc_system_time_init();
#ifdef RT_USING_PTHREADS
pthread_system_init();
#endif
......
#include <rtthread.h>
#include <pthread.h>
struct timeval _timevalue;
void clock_time_system_init()
{
time_t time;
rt_tick_t tick;
rt_device_t device;
time = 0;
device = rt_device_find("rtc");
if (device != RT_NULL)
{
/* get realtime seconds */
rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
}
/* get tick */
tick = rt_tick_get();
_timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
_timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1;
}
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 clock_getres (clockid_t clockid, struct timespec *res)
{
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;
return 0;
}
int clock_gettime (clockid_t clockid, struct timespec *tp)
{
rt_tick_t tick;
if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL))
{
rt_set_errno(EINVAL);
return -1;
}
/* 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;
}
int clock_settime (clockid_t clockid, const struct timespec *tp)
{
int second;
rt_tick_t tick;
rt_device_t device;
if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL))
{
rt_set_errno(EINVAL);
return -1;
}
/* get second */
second = tp->tv_sec;
/* get tick */
tick = rt_tick_get();
/* 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 */
device = rt_device_find("rtc");
if (device != RT_NULL)
{
/* set realtime seconds */
rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second);
}
else return -1;
return 0;
}
#include "mqueue.h"
#include "pthread_internal.h"
#include <stdarg.h>
#include <errno.h>
#ifdef __GNUC__
#include <sys/fcntl.h>
#endif
static mqd_t posix_mq_list = RT_NULL;
static struct rt_semaphore posix_mq_lock;
void posix_mq_system_init()
......@@ -105,7 +99,7 @@ mqd_t mq_open(const char *name, int oflag, ...)
if (oflag & O_CREAT)
{
va_start(arg, oflag);
mode = (mode_t) va_arg(arg, unsigned int);
mode = (mode_t) va_arg(arg, unsigned int); mode = mode;
attr = (struct mq_attr *) va_arg(arg, struct mq_attr *);
va_end(arg);
......@@ -221,7 +215,7 @@ ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
return -1;
}
tick = libc_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;
......
......@@ -2,9 +2,6 @@
#define __MQUEUE_H__
#include <rtthread.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <pthread.h>
struct mqdes
......
#ifndef __POSIX_TYPES_H__
#define __POSIX_TYPES_H__
#include <rtthread.h>
/* compatible in different compiler and C runtime library */
#ifdef RT_USING_NEWLIB
/* normarlly, GNU GCC will use newlib as C runtime library */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <stdarg.h>
#else
#ifdef __CC_ARM /* ARM Compiler */
#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. */
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
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 */
#ifdef RT_USING_DFS
#include <dfs_posix.h>
#else
typedef rt_uint16_t mode_t;
#define O_RDONLY 0000000
#define O_WRONLY 0000001
#define O_RDWR 0000002
#define O_ACCMODE 0000003
#define O_CREAT 0000100
#define O_EXCL 0000200
#define O_TRUNC 0001000
#define O_APPEND 0002000
#define O_DIRECTORY 0200000
#endif
#elif defined (__IAR_SYSTEMS_ICC__) /* IAR Compiler */
#elif defined (__GNUC__) /* GNU GCC Compiler, with minilibc */
#endif
#endif
#endif
......@@ -4,6 +4,9 @@
int pthread_system_init(void)
{
/* initialize clock and time */
clock_time_system_init();
/* initialize key area */
pthread_key_system_init();
/* initialize posix mqueue */
......@@ -211,13 +214,14 @@ int pthread_join (pthread_t thread, void **value_ptr)
pthread_detach(thread);
}
else return ESRCH;
return 0;
}
void pthread_exit (void* value)
{
_pthread_data_t* ptd;
_pthread_cleanup_t* cleanup;
_pthread_key_data_t* key;
extern _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX];
ptd = _pthread_get_data(rt_thread_self());
......@@ -457,4 +461,3 @@ int pthread_cancel(pthread_t thread)
return 0;
}
......@@ -15,8 +15,7 @@
#define __PTHREAD_H__
#include <rtthread.h>
#include <errno.h>
#include <sys/types.h>
#include <posix_types.h>
#define PTHREAD_KEY_MAX 8
......@@ -254,5 +253,20 @@ struct sigevent {
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_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 CLOCK_REALTIME 0
int clock_getres (clockid_t clockid, struct timespec *res);
int clock_gettime (clockid_t clockid, struct timespec *tp);
int clock_settime (clockid_t clockid, const struct timespec *tp);
#endif
......@@ -44,7 +44,6 @@ int pthread_barrier_destroy(pthread_barrier_t *barrier)
int pthread_barrier_init(pthread_barrier_t *barrier,
const pthread_barrierattr_t *attr, unsigned count)
{
rt_err_t result;
if (!barrier) return EINVAL;
if (attr &&(*attr != PTHREAD_PROCESS_PRIVATE)) return EINVAL;
......
#include <pthread.h>
#include "pthread_internal.h"
int pthread_condattr_destroy(pthread_condattr_t *attr)
{
......@@ -49,7 +50,7 @@ int pthread_condattr_setpshared(pthread_condattr_t*attr, int pshared)
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
{
rt_err_t result;
rt_uint8_t cond_name[RT_NAME_MAX];
char cond_name[RT_NAME_MAX];
static rt_uint16_t cond_num = 0;
/* parameter check */
......@@ -169,7 +170,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond,
int timeout;
rt_err_t result;
timeout = libc_time_to_tick(abstime);
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;
......
......@@ -58,8 +58,10 @@ rt_inline _pthread_data_t* _pthread_get_data(pthread_t thread)
return ptd;
}
extern int libc_time_to_tick(const struct timespec *time);
int clock_time_to_tick(const struct timespec *time);
void clock_time_system_init(void);
void posix_mq_system_init(void);
void posix_sem_system_init(void);
void pthread_key_system_init(void);
#endif
......@@ -172,6 +172,8 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex)
result = rt_mutex_release(&(mutex->lock));
if (result == RT_EOK) return 0;
return EINVAL;
}
int pthread_mutex_trylock(pthread_mutex_t *mutex)
......
......@@ -2,8 +2,7 @@
#define __SCHED_H__
#include <rtthread.h>
#include <sys/types.h>
#include <errno.h>
#include <pthread.h>
/* Thread scheduling policies */
enum
......
#include <errno.h>
#include <sys/fcntl.h>
#include <rtthread.h>
#include "semaphore.h"
#include "pthread_internal.h"
static sem_t* posix_sem_list = RT_NULL;
static struct rt_semaphore posix_sem_lock;
......@@ -60,7 +58,9 @@ static sem_t *posix_sem_find(const char* name)
{
return iter;
}
}
}
return RT_NULL;
}
int sem_close(sem_t *sem)
......@@ -151,7 +151,6 @@ int sem_getvalue(sem_t *sem, int *sval)
int sem_init(sem_t *sem, int pshared, unsigned int value)
{
rt_err_t result;
char name[RT_NAME_MAX];
static rt_uint16_t psem_number = 0;
......@@ -195,7 +194,7 @@ sem_t *sem_open(const char *name, int oflag, ...)
if (oflag & O_CREAT)
{
va_start(arg, oflag);
mode = (mode_t) va_arg( arg, unsigned int);
mode = (mode_t) va_arg( arg, unsigned int); mode = mode;
value = va_arg( arg, unsigned int);
va_end(arg);
......@@ -286,7 +285,7 @@ int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
if (!sem || !abs_timeout) return EINVAL;
/* calculate os tick */
tick = libc_time_to_tick(abs_timeout);
tick = clock_time_to_tick(abs_timeout);
result = rt_sem_take(sem->sem, tick);
if (result == -RT_ETIMEOUT)
......
......@@ -2,7 +2,7 @@
#define __POSIX_SEMAPHORE_H__
#include <rtthread.h>
#include <sys/time.h>
#include <pthread.h>
struct posix_sem
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册