Commit a825ee4c authored by Gilles Chanteperdrix's avatar Gilles Chanteperdrix

Posix skin update

git-svn-id: svn+ssh://svn.gna.org/svn/xenomai/trunk@473 c6d672ea-8702-0410-b560-f74c916a59fe
parent b44e3f89
2006-01-26 Gilles Chanteperdrix <gilles.chanteperdrix@laposte.net>
* ksrc/nucleus/heap.c (xnheap_init_shared, xnheap_destroy_shared):
Implementation for simulator.
* ksrc/skins/posix/timer.c (timer_settime): Set owner in
timer_settime instead of timer_create.
* ksrc/skins/posix/thread.c (pthread_join): Destroy thread when
joining a canceled thread. Return EPERM when joining a running
thread from the root thread.
* ksrc/skins/posix/demos/satch.c: Use shared memory.
* ksrc/skins/posix/shm.c: Shared memory services.
2006-01-19 Gilles Chanteperdrix <gilles.chanteperdrix@laposte.net>
* Makefile.am: Re-run prepare-kernel only when maintainer mode is
......
......@@ -20449,22 +20449,18 @@ case "$host" in
i*86*-*)
XENO_TARGET_ARCH=i386
XENO_LINUX_ARCH=i386
arch_have_sim=y
;;
powerpc-*|ppc-*)
XENO_TARGET_ARCH=powerpc
XENO_LINUX_ARCH=ppc
arch_have_sim=y
;;
powerpc64-*|ppc64-*)
XENO_TARGET_ARCH=powerpc
XENO_LINUX_ARCH=ppc64
arch_have_sim=y
;;
ia64-*)
XENO_TARGET_ARCH=ia64
XENO_LINUX_ARCH=ia64
arch_have_sim=y
;;
bfin-*|bfinnommu-*|blackfin-*)
XENO_TARGET_ARCH=blackfin
......@@ -20477,6 +20473,7 @@ echo "$as_me: error: Shared libraries unsupported -- reconfigure passing --disab
;;
arm-*)
XENO_TARGET_ARCH=arm
XENO_LINUX_ARCH=arm
;;
*) echo ""
echo "*******************************************"
......@@ -21541,7 +21538,7 @@ base=asm-generic
ac_config_links="$ac_config_links src/include/$base/xenomai:include/$base"
ac_config_files="$ac_config_files Makefile config/Makefile scripts/Makefile scripts/xeno-config scripts/xeno-load scripts/xeno-test src/Makefile src/nucleus/Makefile src/skins/Makefile src/skins/uvm/Makefile src/skins/posix/Makefile src/skins/native/Makefile src/skins/psos+/Makefile src/skins/uitron/Makefile src/skins/vrtx/Makefile src/skins/vxworks/Makefile src/skins/rtdm/Makefile src/skins/rtai/Makefile src/include/Makefile src/testsuite/Makefile src/testsuite/latency/Makefile src/testsuite/switch/Makefile include/Makefile include/asm-generic/Makefile include/asm-blackfin/Makefile include/asm-i386/Makefile include/asm-powerpc/Makefile include/asm-ia64/Makefile include/asm-arm/Makefile include/asm-uvm/Makefile include/asm-sim/Makefile include/native/Makefile include/nucleus/Makefile include/posix/Makefile include/psos+/Makefile include/rtai/Makefile include/rtdm/Makefile include/uitron/Makefile include/vrtx/Makefile include/vxworks/Makefile"
ac_config_files="$ac_config_files Makefile config/Makefile scripts/Makefile scripts/xeno-config scripts/xeno-load scripts/xeno-test src/Makefile src/nucleus/Makefile src/skins/Makefile src/skins/uvm/Makefile src/skins/posix/Makefile src/skins/posix/sys/Makefile src/skins/native/Makefile src/skins/psos+/Makefile src/skins/uitron/Makefile src/skins/vrtx/Makefile src/skins/vxworks/Makefile src/skins/rtdm/Makefile src/skins/rtai/Makefile src/include/Makefile src/testsuite/Makefile src/testsuite/latency/Makefile src/testsuite/switch/Makefile include/Makefile include/asm-generic/Makefile include/asm-blackfin/Makefile include/asm-i386/Makefile include/asm-powerpc/Makefile include/asm-ia64/Makefile include/asm-arm/Makefile include/asm-uvm/Makefile include/asm-sim/Makefile include/native/Makefile include/nucleus/Makefile include/posix/Makefile include/psos+/Makefile include/rtai/Makefile include/rtdm/Makefile include/uitron/Makefile include/vrtx/Makefile include/vxworks/Makefile"
if test \! x$XENO_MAYBE_DOCDIR = x; then
......@@ -22166,6 +22163,7 @@ do
"src/skins/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/skins/Makefile" ;;
"src/skins/uvm/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/skins/uvm/Makefile" ;;
"src/skins/posix/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/skins/posix/Makefile" ;;
"src/skins/posix/sys/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/skins/posix/sys/Makefile" ;;
"src/skins/native/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/skins/native/Makefile" ;;
"src/skins/psos+/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/skins/psos+/Makefile" ;;
"src/skins/uitron/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/skins/uitron/Makefile" ;;
......
......@@ -546,6 +546,7 @@ AC_CONFIG_FILES([ \
src/skins/Makefile \
src/skins/uvm/Makefile \
src/skins/posix/Makefile \
src/skins/posix/sys/Makefile \
src/skins/native/Makefile \
src/skins/psos+/Makefile \
src/skins/uitron/Makefile \
......
......@@ -746,6 +746,37 @@ while(0)
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
#endif /* !PAGE_ALIGN */
/* Simulator has only one root thread, so Linux semaphores are only faked. */
struct semaphore {
unsigned count;
};
#define sema_init(s, v) ((s)->count = (v))
#define down(s) ({ \
while (!(s)->count) /* deadlock */ \
; \
--(s)->count; \
})
#define down_interruptible(s) (down(s),0)
#define up(s) (++(s)->count)
/* Copied from linux/err.h */
#define IS_ERR_VALUE(x) ((x) > (unsigned long)-1000L)
static inline void *ERR_PTR(long error)
{
return (void *) error;
}
static inline long PTR_ERR(const void *ptr)
{
return (long) ptr;
}
static inline long IS_ERR(const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}
/* Pre-set config switches. */
#define CONFIG_XENO_HW_PERIODIC_TIMER 1
......
......@@ -630,6 +630,42 @@ int mq_unlink(const char *name);
END_C_DECLS
/* Shared memory. */
/* Protections are chosen from these bits, OR'd together. The
implementation does not necessarily support PROT_EXEC or PROT_WRITE
without PROT_READ. The only guarantees are that no writing will be
allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
#define PROT_READ 0x1 /* Page can be read. */
#define PROT_WRITE 0x2 /* Page can be written. */
#define PROT_EXEC 0x4 /* Page can be executed. */
#define PROT_NONE 0x0 /* Page can not be accessed. */
/* Sharing types (must choose one and only one of these). */
#define MAP_SHARED 0x01 /* Share changes. */
#define MAP_FAILED ((void *) -1)
BEGIN_C_DECLS
int shm_open(const char *name, int oflag, mode_t mode);
int shm_unlink(const char *name);
int ftruncate(int fildes, off_t length);
void *mmap(void *addr, size_t len, int prot, int flags,
int fildes, off_t off);
int munmap(void *addr, size_t len);
int close(int fildes);
END_C_DECLS
#endif /* __KERNEL__ || __XENO_SIM__ */
#endif /* !_XENO_SKIN_POSIX_H */
......@@ -76,6 +76,14 @@
#define __pse51_sem_unlink 50
#define __pse51_sem_timedwait 51
#define __pse51_mq_notify 52
#define __pse51_shm_open 53
#define __pse51_shm_unlink 54
#define __pse51_shm_close 55
#define __pse51_ftruncate 56
#define __pse51_mmap_prologue 57
#define __pse51_mmap_epilogue 58
#define __pse51_munmap_prologue 59
#define __pse51_munmap_epilogue 60
#ifdef __KERNEL__
......
......@@ -99,7 +99,10 @@ static void init_extent (xnheap_t *heap,
extent->freelist = extent->membase;
}
/*!
/*
*/
/*!
* \fn xnheap_init(xnheap_t *heap,void *heapaddr,u_long heapsize,u_long pagesize)
* \brief Initialize a memory heap.
*
......@@ -1118,7 +1121,7 @@ int xnheap_init_shared (xnheap_t *heap,
if (!heapbase)
return -ENOMEM;
err = xnheap_init(heap,heapbase,heapsize,PAGE_SIZE);
if (err)
......@@ -1164,7 +1167,36 @@ int xnheap_destroy_shared (xnheap_t *heap)
EXPORT_SYMBOL(xnheap_init_shared);
EXPORT_SYMBOL(xnheap_destroy_shared);
#endif /* __KERNEL__ && CONFIG_XENO_OPT_PERVASIVE */
#elif defined(__XENO_SIM__)
int xnheap_init_shared (xnheap_t *heap,
u_long heapsize,
int memflags)
{
void *heapbase;
int err;
heapsize = PAGE_ALIGN(heapsize);
heapbase = xnarch_sysalloc(heapsize);
err = xnheap_init(heap, heapbase, heapsize, PAGE_SIZE);
if (err)
xnarch_sysfree(heapbase, heapsize);
return err;
}
static void free_extent(xnheap_t *heap, void *extent, u_long size, void *cookie)
{
xnarch_sysfree(extent, size);
}
int xnheap_destroy_shared(xnheap_t *heap)
{
xnheap_destroy(heap, free_extent, NULL);
}
#endif /* __XENO_SIM__ */
/*@}*/
......
......@@ -4,8 +4,9 @@ ifeq ($(PATCHLEVEL),6)
obj-$(CONFIG_XENO_SKIN_POSIX) += xeno_posix.o
xeno_posix-y := sched.o thread_attr.o thread.o mutex_attr.o mutex.o cond_attr.o cond.o sem.o \
cancel.o once.o signal.o tsd.o clock.o timer.o registry.o mq.o module.o
xeno_posix-y := sched.o thread_attr.o thread.o mutex_attr.o mutex.o \
cond_attr.o cond.o sem.o cancel.o once.o signal.o tsd.o \
clock.o timer.o registry.o mq.o shm.o module.o
xeno_posix-$(CONFIG_XENO_OPT_PERVASIVE) += syscall.o intr.o
......@@ -23,7 +24,7 @@ list-multi := xeno_posix.o
xeno_posix-objs := sched.o thread_attr.o thread.o mutex_attr.o mutex.o \
cond_attr.o cond.o sem.o cancel.o once.o signal.o tsd.o \
clock.o timer.o registry.o mq.o module.o
clock.o timer.o registry.o mq.o shm.o module.o
opt_objs-y :=
opt_objs-$(CONFIG_XENO_OPT_PERVASIVE) += syscall.o intr.o
......
obj-m += kshm_satch.o
kshm_satch-y := satch.o
EXTRA_CFLAGS += -DPRODUCER -I$(TOPDIR)/include/xenomai
......@@ -18,6 +18,7 @@ accuracy_rt.o: CPPFLAGS=-DSPERIOD=100
accuracy.o: CPPFLAGS+=-DSPERIOD=2000
satch_rt.o: CPPFLAGS=-DCONSUMER
# To use this makefile with xeno-config not located in PATH, type :
# make XENO_CONFIG=/path/to/xeno-config
......@@ -43,4 +44,3 @@ all: $(bin_PROGRAMS) $(lib_LIBRARIES)
clean:
$(RM) $(bin_PROGRAMS) $(lib_LIBRARIES) *.o
This diff is collapsed.
......@@ -39,6 +39,7 @@
#define PSE51_INTR_MAGIC PSE51_MAGIC(0B)
#define PSE51_NAMED_SEM_MAGIC PSE51_MAGIC(0C)
#define PSE51_TIMER_MAGIC PSE51_MAGIC(0D)
#define PSE51_SHM_MAGIC PSE51_MAGIC(0E)
#define PSE51_MIN_PRIORITY XNCORE_LOW_PRIO
#define PSE51_MAX_PRIORITY XNCORE_HIGH_PRIO
......
......@@ -31,6 +31,7 @@
#include <posix/intr.h>
#include <posix/timer.h>
#include <posix/registry.h>
#include <posix/shm.h>
MODULE_DESCRIPTION("POSIX/PSE51 interface");
MODULE_AUTHOR("gilles.chanteperdrix@laposte.net");
......@@ -53,6 +54,7 @@ static void pse51_shutdown(int xtype)
{
xnpod_stop_timer();
pse51_shm_pkg_cleanup();
pse51_thread_pkg_cleanup();
pse51_timer_pkg_cleanup();
pse51_tsd_pkg_cleanup();
......@@ -133,6 +135,7 @@ int SKIN_INIT(posix)
pse51_intr_pkg_init();
#endif /* __KERNEL__ && CONFIG_XENO_OPT_PERVASIVE */
pse51_timer_pkg_init();
pse51_shm_pkg_init();
pse51_thread_pkg_init(module_param_value(time_slice_arg));
......
......@@ -98,6 +98,9 @@ static int pse51_mq_init(pse51_mq_t *mq, const struct mq_attr *attr)
unsigned i, msgsize, memsize;
char *mem;
if (xnpod_asynch_p() || !xnpod_root_p())
return EPERM;
if(!attr->mq_maxmsg)
return EINVAL;
......@@ -666,24 +669,30 @@ int mq_close(mqd_t fd)
spl_t s;
int err;
if (xnpod_asynch_p() || !xnpod_root_p())
{
err = EPERM;
goto error;
}
xnlock_get_irqsave(&nklock, s);
err = pse51_desc_get(&desc, fd, PSE51_MQ_MAGIC);
if(err)
goto error;
goto err_unlock;
mq = node2mq(pse51_desc_node(desc));
err = pse51_desc_destroy(desc);
if(err)
goto error;
goto err_unlock;
err = pse51_node_put(&mq->nodebase);
if(err)
goto error;
goto err_unlock;
if(pse51_node_removed_p(&mq->nodebase))
{
......@@ -697,8 +706,9 @@ int mq_close(mqd_t fd)
return 0;
error:
err_unlock:
xnlock_put_irqrestore(&nklock, s);
error:
thread_set_errno(err);
return -1;
}
......@@ -710,6 +720,12 @@ int mq_unlink(const char *name)
spl_t s;
int err;
if (xnpod_asynch_p() || !xnpod_root_p())
{
err = EPERM;
goto error;
}
xnlock_get_irqsave(&nklock, s);
err = pse51_node_remove(&node, name, PSE51_MQ_MAGIC);
......@@ -727,6 +743,7 @@ int mq_unlink(const char *name)
if(err)
{
error:
thread_set_errno(err);
return -1;
}
......@@ -753,11 +770,8 @@ void pse51_mq_pkg_cleanup(void)
mq->nodebase.name);
#endif /* CONFIG_XENO_OPT_DEBUG */
pse51_node_remove(&node, mq->nodebase.name, PSE51_MQ_MAGIC);
if(node == &mq->nodebase)
{
pse51_mq_destroy(mq);
xnfree(mq);
}
pse51_mq_destroy(mq);
xnfree(mq);
}
}
......
This diff is collapsed.
#ifndef MMAN_H
#define MMAN_H
#include <asm/mman.h> /* PROT_* bits. */
#include <xenomai/nucleus/queue.h>
typedef xnqueue_t pse51_assocq_t;
extern pse51_assocq_t pse51_umaps; /* List of user-space mappings. */
extern pse51_assocq_t pse51_ufds; /* List of user-space descriptors. */
#define pse51_assocq_init(q) (initq(q))
void pse51_assocq_destroy(pse51_assocq_t *q, void (*destroy)(u_long kobj));
int pse51_assoc_create(pse51_assocq_t *q, u_long kobj, int pid, u_long uobj);
int pse51_assoc_lookup(pse51_assocq_t *q,
u_long *kobj,
int pid,
u_long uobj,
int destroy);
int pse51_xnheap_get(xnheap_t **pheap, void *addr);
int pse51_shm_pkg_init(void);
void pse51_shm_pkg_cleanup(void);
#endif /* MMAN_H */
......@@ -30,6 +30,7 @@
#include <posix/intr.h>
#include <posix/registry.h> /* For PSE51_MAXNAME. */
#include <posix/sem.h>
#include <posix/shm.h>
static int __muxid;
......@@ -1043,7 +1044,7 @@ int __mq_unlink (struct task_struct *curr, struct pt_regs *regs)
sizeof(name));
if (len <= 0)
return -EFAULT;
if (len >= sizeof(name))
return -ENAMETOOLONG;
......@@ -1609,6 +1610,259 @@ int __timer_getoverrun (struct task_struct *curr, struct pt_regs *regs)
return rc >= 0 ? rc : -thread_get_errno();
}
/* shm_open(name, oflag, mode, pid, ufd) */
int __shm_open (struct task_struct *curr, struct pt_regs *regs)
{
int ufd, kfd, oflag, err;
char name[PSE51_MAXNAME];
unsigned len;
mode_t mode;
pid_t pid;
len = __xn_strncpy_from_user(curr,
name,
(const char __user *)__xn_reg_arg1(regs),
sizeof(name));
if (len <= 0)
return -EFAULT;
if (len >= sizeof(name))
return -ENAMETOOLONG;
oflag = (int) __xn_reg_arg2(regs);
mode = (mode_t) __xn_reg_arg3(regs);
kfd = shm_open(name, oflag, mode);
if (kfd == -1)
return -thread_get_errno();
pid = (pid_t) __xn_reg_arg4(regs);
ufd = (int) __xn_reg_arg5(regs);
err = pse51_assoc_create(&pse51_ufds, (u_long) kfd, pid, (u_long) ufd);
/* pse51_assoc_create returning an error means that the same pid and user
file descriptor are already registered. That is impossible. */
BUG_ON(err);
return 0;
}
/* shm_unlink(name) */
int __shm_unlink (struct task_struct *curr, struct pt_regs *regs)
{
char name[PSE51_MAXNAME];
unsigned len;
int err;
len = __xn_strncpy_from_user(curr,
name,
(const char __user *)__xn_reg_arg1(regs),
sizeof(name));
if (len <= 0)
return -EFAULT;
if (len >= sizeof(name))
return -ENAMETOOLONG;
err = shm_unlink(name);
return !err ? 0 : -thread_get_errno();
}
/* shm_close(pid, ufd) */
int __shm_close (struct task_struct *curr, struct pt_regs *regs)
{
unsigned long kfd;
int ufd, err;
pid_t pid;
pid = (pid_t) __xn_reg_arg1(regs);
ufd = (int) __xn_reg_arg2(regs);
err = pse51_assoc_lookup(&pse51_ufds, &kfd, pid, (u_long) ufd, 1);
if (err)
return err;
err = close(kfd);
return !err ? 0 : -thread_get_errno();
}
/* ftruncate(pid, ufd, len) */
int __ftruncate (struct task_struct *curr, struct pt_regs *regs)
{
unsigned long kfd;
int ufd, err;
pid_t pid;
off_t len;
pid = (pid_t) __xn_reg_arg1(regs);
ufd = (int) __xn_reg_arg2(regs);
len = (off_t) __xn_reg_arg3(regs);
err = pse51_assoc_lookup(&pse51_ufds, &kfd, pid, (u_long) ufd, 0);
if (err)
return err;
err = ftruncate(kfd, len);
return !err ? 0 : -thread_get_errno();
}
typedef struct {
void *kaddr;
unsigned long len;
xnheap_t *ioctl_cookie;
unsigned long heapsize;
unsigned long offset;
} pse51_umap_t;
/* mmap_prologue(len, pid, ufd, off, pse51_umap_t *umap) */
int __mmap_prologue (struct task_struct *curr, struct pt_regs *regs)
{
unsigned long kfd;
pse51_umap_t umap;
int ufd, err;
size_t len;
pid_t pid;
off_t off;
len = (size_t) __xn_reg_arg1(regs);
pid = (pid_t) __xn_reg_arg2(regs);
ufd = (int) __xn_reg_arg3(regs);
off = (off_t) __xn_reg_arg4(regs);
if(!__xn_access_ok(curr,VERIFY_WRITE,__xn_reg_arg5(regs),sizeof(umap)))
return -EFAULT;
err = pse51_assoc_lookup(&pse51_ufds, &kfd, pid, (u_long) ufd, 0);
if (err)
return err;
/* We do not care for the real flags and protection, this mapping is a
placeholder. */
umap.kaddr = mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,kfd,off);
if (umap.kaddr == MAP_FAILED)
return -thread_get_errno();
if ((err = pse51_xnheap_get(&umap.ioctl_cookie, umap.kaddr)))
{
munmap(umap.kaddr, len);
return err;
}
umap.len = len;
umap.heapsize = xnheap_size(umap.ioctl_cookie);
umap.offset = xnheap_shared_offset(umap.ioctl_cookie, umap.kaddr);
__xn_copy_to_user(curr,
(void __user *)__xn_reg_arg5(regs),
&umap,
sizeof(umap));
return 0;
}
/* mmap_epilogue(pid, uaddr, u_long *ioctl_cookie) */
int __mmap_epilogue (struct task_struct *curr, struct pt_regs *regs)
{
pse51_umap_t umap;
void *uaddr;
pid_t pid;
int err;
pid = (pid_t) __xn_reg_arg1(regs);
uaddr = (void *) __xn_reg_arg2(regs);
if(!__xn_access_ok(curr,VERIFY_READ,__xn_reg_arg3(regs),sizeof(umap)))
return -EFAULT;
__xn_copy_from_user(curr,
&umap,
(void __user *)__xn_reg_arg3(regs),
sizeof(umap));
if (uaddr == MAP_FAILED)
{
munmap(umap.kaddr, umap.len);
return 0;
}
err = pse51_assoc_create(&pse51_umaps,
(u_long) umap.kaddr,
pid,
(u_long) uaddr);
BUG_ON(err);
return 0;
}
/* munmap_prologue(pid, uaddr, len, &unmap) */
int __munmap_prologue (struct task_struct *curr, struct pt_regs *regs)
{
struct {
unsigned long mapsize;
unsigned long offset;
} uunmap;
unsigned long uaddr;
xnheap_t *heap;
void *kaddr;
size_t len;
pid_t pid;
int err;
pid = (pid_t) __xn_reg_arg1(regs);
uaddr = (unsigned long) __xn_reg_arg2(regs);
len = (size_t) __xn_reg_arg3(regs);
if (!__xn_access_ok(curr,VERIFY_WRITE,__xn_reg_arg4(regs),sizeof(uunmap)))
return -EFAULT;
err = pse51_assoc_lookup(&pse51_umaps, (u_long *) &kaddr, pid, uaddr, 0);
if (err)
return err;
err = pse51_xnheap_get(&heap, kaddr);
if (err)
return err;
uunmap.mapsize = xnheap_size(heap);
uunmap.offset = xnheap_shared_offset(heap, kaddr);
__xn_copy_to_user(curr,
(void __user *)__xn_reg_arg4(regs),
&uunmap,
sizeof(uunmap));
return 0;
}
/* munmap_epilogue(pid, uaddr, len) */
int __munmap_epilogue (struct task_struct *curr, struct pt_regs *regs)
{
unsigned long uaddr;
void *kaddr;
size_t len;
pid_t pid;
int err;
pid = (pid_t) __xn_reg_arg1(regs);
uaddr = (unsigned long) __xn_reg_arg2(regs);
len = (size_t) __xn_reg_arg3(regs);
err = pse51_assoc_lookup(&pse51_umaps, (u_long *) &kaddr, pid, uaddr, 1);
if (err)
return err;
err = munmap(kaddr, len);
return !err ? 0 : -thread_get_errno();
}
#if 0
int __itimer_set (struct task_struct *curr, struct pt_regs *regs)
{
......@@ -1738,11 +1992,19 @@ static xnsysent_t __systab[] = {
[__pse51_intr_detach] = { &__intr_detach, __xn_exec_any },
[__pse51_intr_wait] = { &__intr_wait, __xn_exec_primary },
[__pse51_intr_control] = { &__intr_control, __xn_exec_any },
[__pse51_timer_create] = { &__timer_create, __xn_exec_primary },
[__pse51_timer_create] = { &__timer_create, __xn_exec_any },
[__pse51_timer_delete] = { &__timer_delete, __xn_exec_any },
[__pse51_timer_settime] = { &__timer_settime, __xn_exec_any },
[__pse51_timer_settime] = { &__timer_settime, __xn_exec_primary },
[__pse51_timer_gettime] = { &__timer_gettime, __xn_exec_any },