Jan Kiszka wrote:
Hopefully the last round, addressing remarks brought up on the last
posting. The changes are:
[Patches 7-9]
- define xnsynch_owner_check as xnsynch-implementation-independent way
to check provided and current synch owner match (reduces #ifdefs)
[Patches 6 and 9]
- push lockcnt changes to native mutexes into separate patch (patch
[Patch 2]
- switch creation of xeno_current_key etc. from pthread_once to a
constructor
- translate pthread_getspecific == NULL into XN_NO_HANDLE
(funnily, this shrinks the code on x86-64)
[Patch 13]
- detect SMP feature inconsistency between kernel and userland
(but keep SMP off by default for now)
Note that this series (as well as the latter) depends on the VRTX fix of
Philippe which is not yet merged into SVN trunk.
Jan
PS: Hope this series is compatible with more mail clients /wrt
commenting on the inlined patches.
Again forgot to attach the testbench we derived from Gilles' unit test.
It currently depends on my infamous inquire patches. Compile with
-D__POSIX_SKIN__ and the usual wrapping for the posix skin, or against
the native lib otherwise.
Jan
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
/*
* Functional testing of the mutex implementation for native posix skins.
*
* Copyright (C) Gilles Chanteperdrix [EMAIL PROTECTED],
* Marion Deveaud [EMAIL PROTECTED],
* Jan Kiszka [EMAIL PROTECTED]
*
* Released under the terms of GPLv2.
*/
#include stdio.h
#include string.h
#include stdlib.h
#include unistd.h
#include errno.h
#include stdarg.h
#include sys/mman.h
#include pthread.h
#include native/timer.h
#ifdef __POSIX_SKIN__
#include posix/syscall.h
#else /* __NATIVE_SKIN__ */
#include native/task.h
#include native/mutex.h
#include native/sem.h
#include native/cond.h
#endif
#define MUTEX_CREATE 1
#define MUTEX_LOCK 2
#define MUTEX_TRYLOCK 3
#define MUTEX_UNLOCK 4
#define MUTEX_DESTROY 5
#define COND_CREATE 6
#define COND_SIGNAL 7
#define COND_WAIT 8
#define COND_DESTROY 9
#define THREAD_DETACH 10
#define THREAD_CREATE 11
#define NS_PER_MS 100
#ifdef __POSIX_SKIN__
typedef pthread_mutex_t mutex_t;
typedef pthread_t thread_t;
typedef pthread_cond_t cond_t;
#else /* __NATIVE_SKIN__ */
typedef RT_MUTEX mutex_t;
typedef RT_TASK thread_t;
typedef RT_COND cond_t;
#endif /* __NATIVE_SKIN__ */
void ms_sleep(int time)
{
#ifdef __POSIX_SKIN__
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = time*NS_PER_MS;
nanosleep(ts, NULL);
#else /* __NATIVE_SKIN__ */
rt_task_sleep(time*NS_PER_MS);
#endif /* __NATIVE_SKIN__ */
}
void check_current_prio(int expected_prio)
{
int current_prio;
#ifdef __POSIX_SKIN__
# ifdef __pse51_get_current_prio
extern unsigned __pse51_muxid;
XENOMAI_SKINCALL1(__pse51_muxid, __pse51_get_current_prio, current_prio);
# else /* !__pse51_get_current_prio */
current_prio = expected_prio;
# endif /* !__pse51_get_current_prio */
#else /* __NATIVE_SKIN__ */
int ret;
RT_TASK_INFO task_info;
if ((ret = rt_task_inquire(NULL, task_info)) 0) {
fprintf(stderr, Task inquire: %i (%s)\n, -ret, strerror(-ret));
exit(EXIT_FAILURE);
}
current_prio = task_info.cprio;
#endif /* __NATIVE_SKIN__ */
if (current_prio != expected_prio) {
fprintf(stderr, current prio (%d) != expected prio (%d)\n,
current_prio, expected_prio);
exit(EXIT_FAILURE);
}
}
void check_current_mode(int expected_primary_mode)
{
int current_in_primary, ret;
#ifdef __POSIX_SKIN__
pthread_info_t thread_info;
if ((ret = pthread_inquire_np(pthread_self(), thread_info)) 0) {
fprintf(stderr, Thread inquire: %i (%s)\n, ret, strerror(ret));
exit(EXIT_FAILURE);
}
current_in_primary = !!(thread_info.status PTHREAD_PRIMARY);
#else /* __NATIVE_SKIN__ */
RT_TASK_INFO task_info;
if ((ret = rt_task_inquire(NULL, task_info)) 0) {
fprintf(stderr, Task inquire: %i (%s)\n, -ret, strerror(-ret));
exit(EXIT_FAILURE);
}
current_in_primary = !!(task_info.status T_PRIMARY);
#endif /* __NATIVE_SKIN__ */
if (current_in_primary != expected_primary_mode) {
fprintf(stderr, current mode (%d) != expected mode (%d)\n,
current_in_primary, expected_primary_mode);
exit(EXIT_FAILURE);
}
}
void yield(void)
{
#ifdef __POSIX_SKIN__
sched_yield();
#else /* __NATIVE_SKIN__ */
rt_task_yield();
#endif /* __NATIVE_SKIN__ */
}
int dispatch(const char *service_name, int service_type, int check, ...)
{
thread_t *thread;
cond_t *cond;
void *handler;
va_list ap;
int status;
#ifdef __POSIX_SKIN__
struct sched_param param;
pthread_attr_t threadattr;
pthread_mutexattr_t mutexattr;
pthread_mutex_t *mutex;
#else /* __NATIVE_SKIN__ */
int prio;
#endif /* __NATIVE_SKIN__ */
va_start(ap, check);
switch (service_type) {
case MUTEX_CREATE:
#ifdef __POSIX_SKIN__
mutex = va_arg(ap, pthread_mutex_t *);
pthread_mutexattr_init(mutexattr);
if (va_arg(ap, int) != 0)
pthread_mutexattr_setprotocol(mutexattr,