[Xenomai-git] Philippe Gerum : copperplate/heapobj-pshared: introduce allocation bitmap
Module: xenomai-3 Branch: wip/gpio Commit: 75558b54e4efe3cc73b0cb040e489dd8615fb730 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=75558b54e4efe3cc73b0cb040e489dd8615fb730 Author: Philippe Gerum Date: Fri Jun 3 10:00:38 2016 +0200 copperplate/heapobj-pshared: introduce allocation bitmap Using a free list for maintaining pages leads to pathological execution times when releasing blocks obtained from huge heaps (i.e. hundreds of megabytes). Rework the core to use an allocation bitmap instead. --- lib/copperplate/heapobj-pshared.c | 424 + lib/copperplate/internal.h| 18 +- 2 files changed, 259 insertions(+), 183 deletions(-) diff --git a/lib/copperplate/heapobj-pshared.c b/lib/copperplate/heapobj-pshared.c index 8c5dac6..bd9ea47 100644 --- a/lib/copperplate/heapobj-pshared.c +++ b/lib/copperplate/heapobj-pshared.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -43,15 +44,7 @@ #include "xenomai/init.h" #include "internal.h" -#define HOBJ_PAGE_SHIFT9 /* 2^9 => 512 bytes */ -#define HOBJ_PAGE_SIZE (1U << HOBJ_PAGE_SHIFT) -#define HOBJ_PAGE_MASK (~(HOBJ_PAGE_SIZE-1)) -#define HOBJ_PAGE_ALIGN(addr) (((addr)+HOBJ_PAGE_SIZE-1)&HOBJ_PAGE_MASK) - -#define HOBJ_MINALIGNSZ (1U << 4) /* i.e. 16 bytes */ -#define HOBJ_MAXEXTSZ (1U << 31) /* i.e. 2Gb */ - -enum { +enum { /* FIXME: page_free redundant with bitmap */ page_free =0, page_cont =1, page_list =2 @@ -66,8 +59,9 @@ struct shared_extent { struct holder link; memoff_t membase; /* Base offset of page array */ memoff_t memlim;/* Offset limit of page array */ - memoff_t freelist; /* Head of free page list */ - struct page_entry pagemap[1]; /* Start of page map */ + memoff_t bitmap;/* Offset of allocation bitmap */ + int bitwords; /* 32bit words in bitmap */ + struct page_entry pagemap[0]; /* Start of page map */ }; /* @@ -117,24 +111,38 @@ static inline size_t __align_to(size_t size, size_t al) return ((size+al-1)&(~(al-1))); } -static inline size_t get_pagemap_size(size_t h) +static inline size_t get_pagemap_size(size_t h, + memoff_t *bmapoff, int *bmapwords) { + int nrpages = h >> HOBJ_PAGE_SHIFT, bitmapw; + size_t pagemapsz; + /* * Return the size of the meta data required to map 'h' bytes * of user memory in pages of HOBJ_PAGE_SIZE bytes. The meta * data includes the length of the extent descriptor, plus the -* length of the page mapping array. 'h' must be a multiple of -* HOBJ_PAGE_SIZE on entry. +* length of the page mapping array followed by the allocation +* bitmap. 'h' must be a multiple of HOBJ_PAGE_SIZE on entry. */ assert((h & ~HOBJ_PAGE_MASK) == 0); - return __align_to((h >> HOBJ_PAGE_SHIFT) * sizeof(struct page_entry) - + sizeof(struct shared_extent), HOBJ_MINALIGNSZ); + pagemapsz = __align_to(nrpages * sizeof(struct page_entry), + sizeof(uint32_t)); + bitmapw =__align_to(nrpages, 32) / 32; + if (bmapoff) + *bmapoff = offsetof(struct shared_extent, pagemap) + pagemapsz; + if (bmapwords) + *bmapwords = bitmapw; + + return __align_to(pagemapsz + + sizeof(struct shared_extent) + + bitmapw * sizeof(uint32_t), + HOBJ_MINALIGNSZ); } static void init_extent(void *base, struct shared_extent *extent) { - caddr_t freepage; - int n, lastpgnum; + int lastpgnum; + uint32_t *p; __holder_init_nocheck(base, &extent->link); @@ -146,20 +154,18 @@ static void init_extent(void *base, struct shared_extent *extent) */ assert(lastpgnum >= 1); - /* Mark each page as free in the page map. */ - for (n = 0, freepage = __shref(base, extent->membase); -n < lastpgnum; n++, freepage += HOBJ_PAGE_SIZE) { - *((memoff_t *)freepage) = __shoff(base, freepage) + HOBJ_PAGE_SIZE; - extent->pagemap[n].type = page_free; - extent->pagemap[n].bcount = 0; - } - - *((memoff_t *)freepage) = 0; - extent->pagemap[lastpgnum].type = page_free; - extent->pagemap[lastpgnum].bcount = 0; + /* Mark all pages as free in the page map. */ + memset(extent->pagemap, 0, lastpgnum * sizeof(struct page_entry)); - /* The first page starts the free list of a new extent. */ - extent->freelist = extent->membase; + /* Clear the allocation bitmap. */ + p = __shref(base, extent->bitmap); + memset(p, 0, extent->bitwords * sizeof(uint32_t)); + /* +* Mark the unused trailing bits (due to alignment
[Xenomai-git] Philippe Gerum : copperplate/heapobj-pshared: unlink main heap file on exit if no registry
Module: xenomai-3 Branch: wip/gpio Commit: 83d7bfb0ee18db3709c709022039674307610965 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=83d7bfb0ee18db3709c709022039674307610965 Author: Philippe Gerum Date: Mon Jun 6 20:34:10 2016 +0200 copperplate/heapobj-pshared: unlink main heap file on exit if no registry sysregd removes the shared heap upon exit of the last process attached to the session. When registry support is disabled, make sure the backing file is unlinked upon exit of the main process. --- lib/copperplate/heapobj-pshared.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/lib/copperplate/heapobj-pshared.c b/lib/copperplate/heapobj-pshared.c index bd9ea47..f4c6f37 100644 --- a/lib/copperplate/heapobj-pshared.c +++ b/lib/copperplate/heapobj-pshared.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -678,6 +679,19 @@ out: return ret; } +#ifndef CONFIG_XENO_REGISTRY +static void unlink_main_heap(void) +{ + /* +* Only the master process run this when there is no registry +* support (i.e. the one which has initialized the main shared +* heap for the session). When the registry is enabled, +* sysregd does the housekeeping. +*/ + shm_unlink(main_pool.fsname); +} +#endif + static int create_main_heap(pid_t *cnode_r) { const char *session = __copperplate_setup_data.session_label; @@ -770,6 +784,10 @@ reset: ret = fchown(fd, geteuid(), getegid()); (void)ret; init: +#ifndef CONFIG_XENO_REGISTRY + atexit(unlink_main_heap); +#endif + ret = ftruncate(fd, 0); /* Clear all previous contents if any. */ if (__bterrno(ret)) goto unlink_fail; ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : testsuite/gpiotest: add GPIO test suite
Module: xenomai-3 Branch: wip/gpio Commit: 898532ac4952edc99093c530002483e8a7fa9e27 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=898532ac4952edc99093c530002483e8a7fa9e27 Author: Philippe Gerum Date: Wed Jun 1 15:59:27 2016 +0200 testsuite/gpiotest: add GPIO test suite --- testsuite/Makefile.am |2 + testsuite/gpiotest/Makefile.am | 19 testsuite/gpiotest/gpiotest.c | 188 3 files changed, 209 insertions(+) diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index e83e6cb..c345472 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -4,12 +4,14 @@ SUBDIRS = latency smokey if XENO_COBALT SUBDIRS += \ clocktest \ + gpiotest\ switchtest \ xeno-test endif DIST_SUBDIRS = \ clocktest \ + gpiotest\ latency \ smokey \ switchtest \ diff --git a/testsuite/gpiotest/Makefile.am b/testsuite/gpiotest/Makefile.am new file mode 100644 index 000..b01427b --- /dev/null +++ b/testsuite/gpiotest/Makefile.am @@ -0,0 +1,19 @@ +testdir = @XENO_TEST_DIR@ + +CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) + +test_PROGRAMS = gpiotest + +gpiotest_SOURCES = gpiotest.c + +gpiotest_CPPFLAGS =\ + $(XENO_USER_CFLAGS) \ + -I$(top_srcdir)/include + +gpiotest_LDFLAGS = @XENO_AUTOINIT_LDFLAGS@ $(XENO_POSIX_WRAPPERS) + +gpiotest_LDADD = \ + ../../lib/smokey/libsmokey.la \ + ../../lib/@XENO_CORE_LIB@ \ +@XENO_USER_LDADD@ \ + -lpthread -lrt diff --git a/testsuite/gpiotest/gpiotest.c b/testsuite/gpiotest/gpiotest.c new file mode 100644 index 000..838f498 --- /dev/null +++ b/testsuite/gpiotest/gpiotest.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2016 Philippe Gerum . + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +smokey_test_plugin(interrupt, + SMOKEY_ARGLIST( + SMOKEY_STRING(device), + ), + "Wait for interrupts from a GPIO pin.\n" + "\tdevice=." +); + +smokey_test_plugin(read_value, + SMOKEY_ARGLIST( + SMOKEY_STRING(device), + ), + "Read GPIO value.\n" + "\tdevice=." +); + +smokey_test_plugin(write_value, + SMOKEY_ARGLIST( + SMOKEY_STRING(device), + ), + "Write GPIO value.\n" + "\tdevice=." +); + +static int run_interrupt(struct smokey_test *t, int argc, char *const argv[]) +{ + const char *device = NULL; + int fd, ret; + fd_set set; + + smokey_parse_args(t, argc, argv); + + if (!SMOKEY_ARG_ISSET(interrupt, device)) { + warning("missing device= specification"); + return -EINVAL; + } + + device = SMOKEY_ARG_STRING(interrupt, device); + fd = open(device, O_RDWR); + if (fd < 0) { + ret = -errno; + warning("cannot open device %s [%s]", + device, symerror(ret)); + return ret; + } + + ret = ioctl(fd, GPIO_RTIOC_IRQEN); + if (ret) { + ret = -errno; + warning("GPIO_RTIOC_IRQEN failed on %s [%s]", + device, symerror(ret)); + return ret; + } + + FD_ZERO(&set); + FD_SET(fd, &set); + + for (;;) { + ret = select(fd + 1, &set, NULL, NULL, NULL); + if (ret < 0) { + ret = -errno; + warning("failed listening to %s [%s]", + device, symerror(ret)); + } + printf("kick %d!\n", ret); + } + + close(fd); + + return 0; +} + +static int run_read_value(struct smokey_test *t, int argc, char *const argv[]) +{ + const char *device = NULL; + int fd, ret, value = -1; + + smokey_parse_args(t, argc, argv); + + if (!SMOKEY_ARG_ISSET(read_value, device)) { + warning("missing device= specification"); + return -EINVAL; +
[Xenomai-git] Philippe Gerum : boilerplate: provide count-leading/trailing-bits ops
Module: xenomai-3 Branch: wip/gpio Commit: 5defc2afa24f72d8fc138582a1f4e51c21eeb2a5 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=5defc2afa24f72d8fc138582a1f4e51c21eeb2a5 Author: Philippe Gerum Date: Tue Jun 7 10:10:17 2016 +0200 boilerplate: provide count-leading/trailing-bits ops --- include/boilerplate/compiler.h | 48 1 file changed, 48 insertions(+) diff --git a/include/boilerplate/compiler.h b/include/boilerplate/compiler.h index e558f73..0509e33 100644 --- a/include/boilerplate/compiler.h +++ b/include/boilerplate/compiler.h @@ -58,4 +58,52 @@ #define __deprecated __attribute__((__deprecated__)) #endif +#ifdef __cplusplus +extern "C" { +#endif + +void __invalid_operand_size(void); + +#define ctz(__v) \ + ({ \ + int __ret; \ + if (!__v) \ + __ret = sizeof(__v) * 8;\ + else\ + switch (sizeof(__v)) { \ + case sizeof(int): \ + __ret = __builtin_ctz((unsigned int)__v); \ + break; \ + case sizeof(long long): \ + __ret = __builtin_ctzll(__v); \ + break; \ + default:\ + __invalid_operand_size(); \ + } \ + __ret; \ + }) + +#define clz(__v) \ + ({ \ + int __ret; \ + if (!__v) \ + __ret = sizeof(__v) * 8;\ + else\ + switch (sizeof(__v)) { \ + case sizeof(int): \ + __ret = __builtin_clz((unsigned int)__v); \ + break; \ + case sizeof(long long): \ + __ret = __builtin_clzll(__v); \ + break; \ + default:\ + __invalid_operand_size(); \ + } \ + __ret; \ + }) + +#ifdef __cplusplus +} +#endif + #endif /* _BOILERPLATE_COMPILER_H */ ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : drivers/gpio: introduce real-time GPIO support
Module: xenomai-3 Branch: wip/gpio Commit: 35bfc666cf7ed7cd9bcbf395695b2ebf3b2eb735 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=35bfc666cf7ed7cd9bcbf395695b2ebf3b2eb735 Author: Philippe Gerum Date: Wed May 25 10:54:22 2016 +0200 drivers/gpio: introduce real-time GPIO support --- configure.ac |1 + include/rtdm/Makefile.am |1 + include/rtdm/gpio.h| 24 +++ include/rtdm/uapi/Makefile.am |1 + include/rtdm/uapi/gpio.h | 28 +++ include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile|2 +- kernel/drivers/gpio/Kconfig| 25 +++ kernel/drivers/gpio/Makefile |7 + kernel/drivers/gpio/gpio-bcm2708.c | 39 kernel/drivers/gpio/gpio-core.c| 349 kernel/drivers/gpio/gpio-core.h| 48 + kernel/drivers/gpio/gpio-mxc.c | 67 +++ 14 files changed, 593 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 8bbeeef..88022a6 100644 --- a/configure.ac +++ b/configure.ac @@ -878,6 +878,7 @@ AC_CONFIG_FILES([ \ testsuite/Makefile \ testsuite/latency/Makefile \ testsuite/switchtest/Makefile \ + testsuite/gpiotest/Makefile \ testsuite/smokey/Makefile \ testsuite/smokey/arith/Makefile \ testsuite/smokey/sched-quota/Makefile \ diff --git a/include/rtdm/Makefile.am b/include/rtdm/Makefile.am index a4e6ff8..ad2c342 100644 --- a/include/rtdm/Makefile.am +++ b/include/rtdm/Makefile.am @@ -4,6 +4,7 @@ includesub_HEADERS =\ analogy.h \ autotune.h \ can.h \ + gpio.h \ ipc.h \ rtdm.h \ serial.h\ diff --git a/include/rtdm/gpio.h b/include/rtdm/gpio.h new file mode 100644 index 000..c61f229 --- /dev/null +++ b/include/rtdm/gpio.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2016 Philippe Gerum + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef _RTDM_GPIO_H +#define _RTDM_GPIO_H + +#include +#include + +#endif /* !_RTDM_GPIO_H */ diff --git a/include/rtdm/uapi/Makefile.am b/include/rtdm/uapi/Makefile.am index 7cff6c2..d53f10c 100644 --- a/include/rtdm/uapi/Makefile.am +++ b/include/rtdm/uapi/Makefile.am @@ -4,6 +4,7 @@ includesub_HEADERS =\ analogy.h \ autotune.h \ can.h \ + gpio.h \ ipc.h \ rtdm.h \ serial.h\ diff --git a/include/rtdm/uapi/gpio.h b/include/rtdm/uapi/gpio.h new file mode 100644 index 000..b0d4899 --- /dev/null +++ b/include/rtdm/uapi/gpio.h @@ -0,0 +1,28 @@ +/** + * @note Copyright (C) 2016 Philippe Gerum + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _RTDM_UAPI_GPIO_H +#define _RTDM_UAPI_GPIO_H + +#include + +#define GPIO_RTIOC_DIR_OUT _IOW(RTDM_CLASS_GPIO, 0, int) +#define GPIO_RTIOC_DIR_IN _IO(RTDM_CLASS_GPIO, 1) +#define GPIO_RTIOC_IRQEN _IO(RTDM_CLASS_GPIO, 2) +#define GPIO_RTIOC_IRQDIS _IO(RTDM_CLASS_GPIO, 3) + +#endif /* !_RTDM_UAPI_GPIO_H */ diff --git a/include/rtdm/uapi/rtdm.h b/include/rtdm/uapi/rtdm.h index eed3b36..c49378c 100644 --- a/include/rtdm/uapi/rtdm.h +++ b/include/rtdm/uapi/rtdm.h @@ -79,6 +79,7 @@ typedef int64_t nanosecs_rel_t; #define RTDM_CLASS_COBALT 8 #define RTDM_CLASS_UDD 9 #define RTDM_CLASS_MEMORY 10 +#define RTDM_CLASS_GPIO
[Xenomai-git] Philippe Gerum : boilerplate: provide count-leading/trailing-bits ops
Module: xenomai-3 Branch: stable-3.0.x Commit: 5defc2afa24f72d8fc138582a1f4e51c21eeb2a5 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=5defc2afa24f72d8fc138582a1f4e51c21eeb2a5 Author: Philippe Gerum Date: Tue Jun 7 10:10:17 2016 +0200 boilerplate: provide count-leading/trailing-bits ops --- include/boilerplate/compiler.h | 48 1 file changed, 48 insertions(+) diff --git a/include/boilerplate/compiler.h b/include/boilerplate/compiler.h index e558f73..0509e33 100644 --- a/include/boilerplate/compiler.h +++ b/include/boilerplate/compiler.h @@ -58,4 +58,52 @@ #define __deprecated __attribute__((__deprecated__)) #endif +#ifdef __cplusplus +extern "C" { +#endif + +void __invalid_operand_size(void); + +#define ctz(__v) \ + ({ \ + int __ret; \ + if (!__v) \ + __ret = sizeof(__v) * 8;\ + else\ + switch (sizeof(__v)) { \ + case sizeof(int): \ + __ret = __builtin_ctz((unsigned int)__v); \ + break; \ + case sizeof(long long): \ + __ret = __builtin_ctzll(__v); \ + break; \ + default:\ + __invalid_operand_size(); \ + } \ + __ret; \ + }) + +#define clz(__v) \ + ({ \ + int __ret; \ + if (!__v) \ + __ret = sizeof(__v) * 8;\ + else\ + switch (sizeof(__v)) { \ + case sizeof(int): \ + __ret = __builtin_clz((unsigned int)__v); \ + break; \ + case sizeof(long long): \ + __ret = __builtin_clzll(__v); \ + break; \ + default:\ + __invalid_operand_size(); \ + } \ + __ret; \ + }) + +#ifdef __cplusplus +} +#endif + #endif /* _BOILERPLATE_COMPILER_H */ ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : copperplate/heapobj-pshared: introduce allocation bitmap
Module: xenomai-3 Branch: stable-3.0.x Commit: 75558b54e4efe3cc73b0cb040e489dd8615fb730 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=75558b54e4efe3cc73b0cb040e489dd8615fb730 Author: Philippe Gerum Date: Fri Jun 3 10:00:38 2016 +0200 copperplate/heapobj-pshared: introduce allocation bitmap Using a free list for maintaining pages leads to pathological execution times when releasing blocks obtained from huge heaps (i.e. hundreds of megabytes). Rework the core to use an allocation bitmap instead. --- lib/copperplate/heapobj-pshared.c | 424 + lib/copperplate/internal.h| 18 +- 2 files changed, 259 insertions(+), 183 deletions(-) diff --git a/lib/copperplate/heapobj-pshared.c b/lib/copperplate/heapobj-pshared.c index 8c5dac6..bd9ea47 100644 --- a/lib/copperplate/heapobj-pshared.c +++ b/lib/copperplate/heapobj-pshared.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -43,15 +44,7 @@ #include "xenomai/init.h" #include "internal.h" -#define HOBJ_PAGE_SHIFT9 /* 2^9 => 512 bytes */ -#define HOBJ_PAGE_SIZE (1U << HOBJ_PAGE_SHIFT) -#define HOBJ_PAGE_MASK (~(HOBJ_PAGE_SIZE-1)) -#define HOBJ_PAGE_ALIGN(addr) (((addr)+HOBJ_PAGE_SIZE-1)&HOBJ_PAGE_MASK) - -#define HOBJ_MINALIGNSZ (1U << 4) /* i.e. 16 bytes */ -#define HOBJ_MAXEXTSZ (1U << 31) /* i.e. 2Gb */ - -enum { +enum { /* FIXME: page_free redundant with bitmap */ page_free =0, page_cont =1, page_list =2 @@ -66,8 +59,9 @@ struct shared_extent { struct holder link; memoff_t membase; /* Base offset of page array */ memoff_t memlim;/* Offset limit of page array */ - memoff_t freelist; /* Head of free page list */ - struct page_entry pagemap[1]; /* Start of page map */ + memoff_t bitmap;/* Offset of allocation bitmap */ + int bitwords; /* 32bit words in bitmap */ + struct page_entry pagemap[0]; /* Start of page map */ }; /* @@ -117,24 +111,38 @@ static inline size_t __align_to(size_t size, size_t al) return ((size+al-1)&(~(al-1))); } -static inline size_t get_pagemap_size(size_t h) +static inline size_t get_pagemap_size(size_t h, + memoff_t *bmapoff, int *bmapwords) { + int nrpages = h >> HOBJ_PAGE_SHIFT, bitmapw; + size_t pagemapsz; + /* * Return the size of the meta data required to map 'h' bytes * of user memory in pages of HOBJ_PAGE_SIZE bytes. The meta * data includes the length of the extent descriptor, plus the -* length of the page mapping array. 'h' must be a multiple of -* HOBJ_PAGE_SIZE on entry. +* length of the page mapping array followed by the allocation +* bitmap. 'h' must be a multiple of HOBJ_PAGE_SIZE on entry. */ assert((h & ~HOBJ_PAGE_MASK) == 0); - return __align_to((h >> HOBJ_PAGE_SHIFT) * sizeof(struct page_entry) - + sizeof(struct shared_extent), HOBJ_MINALIGNSZ); + pagemapsz = __align_to(nrpages * sizeof(struct page_entry), + sizeof(uint32_t)); + bitmapw =__align_to(nrpages, 32) / 32; + if (bmapoff) + *bmapoff = offsetof(struct shared_extent, pagemap) + pagemapsz; + if (bmapwords) + *bmapwords = bitmapw; + + return __align_to(pagemapsz + + sizeof(struct shared_extent) + + bitmapw * sizeof(uint32_t), + HOBJ_MINALIGNSZ); } static void init_extent(void *base, struct shared_extent *extent) { - caddr_t freepage; - int n, lastpgnum; + int lastpgnum; + uint32_t *p; __holder_init_nocheck(base, &extent->link); @@ -146,20 +154,18 @@ static void init_extent(void *base, struct shared_extent *extent) */ assert(lastpgnum >= 1); - /* Mark each page as free in the page map. */ - for (n = 0, freepage = __shref(base, extent->membase); -n < lastpgnum; n++, freepage += HOBJ_PAGE_SIZE) { - *((memoff_t *)freepage) = __shoff(base, freepage) + HOBJ_PAGE_SIZE; - extent->pagemap[n].type = page_free; - extent->pagemap[n].bcount = 0; - } - - *((memoff_t *)freepage) = 0; - extent->pagemap[lastpgnum].type = page_free; - extent->pagemap[lastpgnum].bcount = 0; + /* Mark all pages as free in the page map. */ + memset(extent->pagemap, 0, lastpgnum * sizeof(struct page_entry)); - /* The first page starts the free list of a new extent. */ - extent->freelist = extent->membase; + /* Clear the allocation bitmap. */ + p = __shref(base, extent->bitmap); + memset(p, 0, extent->bitwords * sizeof(uint32_t)); + /* +* Mark the unused trailing bits (due to align
[Xenomai-git] Philippe Gerum : copperplate/heapobj-pshared: unlink main heap file on exit if no registry
Module: xenomai-3 Branch: stable-3.0.x Commit: 83d7bfb0ee18db3709c709022039674307610965 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=83d7bfb0ee18db3709c709022039674307610965 Author: Philippe Gerum Date: Mon Jun 6 20:34:10 2016 +0200 copperplate/heapobj-pshared: unlink main heap file on exit if no registry sysregd removes the shared heap upon exit of the last process attached to the session. When registry support is disabled, make sure the backing file is unlinked upon exit of the main process. --- lib/copperplate/heapobj-pshared.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/lib/copperplate/heapobj-pshared.c b/lib/copperplate/heapobj-pshared.c index bd9ea47..f4c6f37 100644 --- a/lib/copperplate/heapobj-pshared.c +++ b/lib/copperplate/heapobj-pshared.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -678,6 +679,19 @@ out: return ret; } +#ifndef CONFIG_XENO_REGISTRY +static void unlink_main_heap(void) +{ + /* +* Only the master process run this when there is no registry +* support (i.e. the one which has initialized the main shared +* heap for the session). When the registry is enabled, +* sysregd does the housekeeping. +*/ + shm_unlink(main_pool.fsname); +} +#endif + static int create_main_heap(pid_t *cnode_r) { const char *session = __copperplate_setup_data.session_label; @@ -770,6 +784,10 @@ reset: ret = fchown(fd, geteuid(), getegid()); (void)ret; init: +#ifndef CONFIG_XENO_REGISTRY + atexit(unlink_main_heap); +#endif + ret = ftruncate(fd, 0); /* Clear all previous contents if any. */ if (__bterrno(ret)) goto unlink_fail; ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : include/trank: add missing C bindings
Module: xenomai-3 Branch: wip/gpio Commit: 8f157264893087e27ca4a51f29894897645a319c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=8f157264893087e27ca4a51f29894897645a319c Author: Philippe Gerum Date: Thu Jun 2 16:17:54 2016 +0200 include/trank: add missing C bindings --- include/trank/posix/pthread.h |8 include/trank/rtdk.h |8 include/trank/trank.h |8 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/trank/posix/pthread.h b/include/trank/posix/pthread.h index 25e581d..a7364c5 100644 --- a/include/trank/posix/pthread.h +++ b/include/trank/posix/pthread.h @@ -21,6 +21,10 @@ #ifndef _XENOMAI_TRANK_POSIX_PTHREAD_H #define _XENOMAI_TRANK_POSIX_PTHREAD_H +#ifdef __cplusplus +extern "C" { +#endif + /** * Set the mode of the current thread (compatibility service) * @@ -76,10 +80,6 @@ static inline int pthread_set_name_np(pthread_t thread, return pthread_setname_np(thread, name); } -#ifdef __cplusplus -extern "C" { -#endif - int pthread_make_periodic_np(pthread_t thread, struct timespec *starttp, struct timespec *periodtp); diff --git a/include/trank/rtdk.h b/include/trank/rtdk.h index 6030785..e8bb6d1 100644 --- a/include/trank/rtdk.h +++ b/include/trank/rtdk.h @@ -20,6 +20,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + static inline void rt_print_auto_init(int enable) { /* stdio support is automatically enabled by libcobalt. */ @@ -27,4 +31,8 @@ static inline void rt_print_auto_init(int enable) static inline void rt_print_cleanup(void) { } +#ifdef __cplusplus +} +#endif + #endif /* _XENOMAI_TRANK_RTDK_H */ diff --git a/include/trank/trank.h b/include/trank/trank.h index 2477d45..cc68837 100644 --- a/include/trank/trank.h +++ b/include/trank/trank.h @@ -22,8 +22,16 @@ #ifdef __XENO_COMPAT__ +#ifdef __cplusplus +extern "C" { +#endif + void warning(const char *fmt, ...); +#ifdef __cplusplus +} +#endif + #define trank_warning(__fmt, __args...)\ warning("%s: " __fmt, __func__, ##__args) ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Jan Kiszka : cobalt/kernel: Fix infinite loops on thread cleanup
Module: xenomai-3 Branch: wip/gpio Commit: 35c0893e3e91ae33d2e12572638f7f38a21c9542 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=35c0893e3e91ae33d2e12572638f7f38a21c9542 Author: Jan Kiszka Date: Sat May 21 00:03:24 2016 +0200 cobalt/kernel: Fix infinite loops on thread cleanup Due to flipped parameters of list_for_each_entry_safe, cobalt_signal_flush caused eventual infinite loops. Signed-off-by: Jan Kiszka --- kernel/cobalt/posix/signal.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cobalt/posix/signal.c b/kernel/cobalt/posix/signal.c index a3ec756..4822fda 100644 --- a/kernel/cobalt/posix/signal.c +++ b/kernel/cobalt/posix/signal.c @@ -194,7 +194,7 @@ void cobalt_signal_flush(struct cobalt_thread *thread) * detect this fact when deleting their respective * owners. */ - list_for_each_entry_safe(tmp, sigp, sigq, next) + list_for_each_entry_safe(sigp, tmp, sigq, next) list_del_init(&sigp->next); } ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : drivers/ipc/xddp: fix select() support for the real-time endpoint
Module: xenomai-3 Branch: wip/gpio Commit: fd828bf38f2c7ba5140cbbf1ae932a5e184f823f URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=fd828bf38f2c7ba5140cbbf1ae932a5e184f823f Author: Philippe Gerum Date: Thu Jun 2 14:55:25 2016 +0200 drivers/ipc/xddp: fix select() support for the real-time endpoint --- kernel/drivers/ipc/xddp.c | 26 -- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/kernel/drivers/ipc/xddp.c b/kernel/drivers/ipc/xddp.c index a528061..c91aa02 100644 --- a/kernel/drivers/ipc/xddp.c +++ b/kernel/drivers/ipc/xddp.c @@ -184,14 +184,18 @@ static int __xddp_input_handler(struct xnpipe_mh *mh, int retval, void *skarg) / { struct xddp_socket *sk = skarg; - if (sk->monitor == NULL) - return retval; + if (sk->monitor) { + if (retval == 0) + /* Callee may alter the return value passed to userland. */ + retval = sk->monitor(sk->fd, XDDP_EVTIN, xnpipe_m_size(mh)); + else if (retval == -EPIPE && mh == NULL) + sk->monitor(sk->fd, XDDP_EVTDOWN, 0); + } - if (retval == 0) - /* Callee may alter the return value passed to userland. */ - retval = sk->monitor(sk->fd, XDDP_EVTIN, xnpipe_m_size(mh)); - else if (retval == -EPIPE && mh == NULL) - sk->monitor(sk->fd, XDDP_EVTDOWN, 0); + if (retval == 0 && + (__xnpipe_pollstate(sk->minor) & POLLIN) != 0 && + xnselect_signal(&sk->priv->recv_block, POLLIN)) + xnsched_run(); return retval; } @@ -577,13 +581,7 @@ nostream: rtdm_fd_unlock(rfd); return ret; } - done: - cobalt_atomic_enter(s); - if ((__xnpipe_pollstate(rsk->minor) & POLLIN) != 0 && - xnselect_signal(&rsk->priv->recv_block, POLLIN)) - xnsched_run(); - cobalt_atomic_leave(s); - +done: rtdm_fd_unlock(rfd); return len; ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : cobalt/rtdm: allow up to 1024 minors per driver
Module: xenomai-3 Branch: wip/gpio Commit: 3e90650a417f57916a6520c97382dba47f6ed01f URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=3e90650a417f57916a6520c97382dba47f6ed01f Author: Philippe Gerum Date: Wed Jun 1 10:53:28 2016 +0200 cobalt/rtdm: allow up to 1024 minors per driver --- include/cobalt/kernel/rtdm/driver.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 1354d9a..42f0b73 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -94,7 +94,7 @@ enum rtdm_selecttype; /** @} Device Flags */ /** Maximum number of named devices per driver. */ -#define RTDM_MAX_MINOR 256 +#define RTDM_MAX_MINOR 1024 /** @} rtdm_device_register */ ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Jan Kiszka : cobalt/rtdm: Also initialized driver refcount for protocol devices
Module: xenomai-3 Branch: wip/gpio Commit: 7fa3633957cee1a7d1cc8b2704858992e9c49821 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=7fa3633957cee1a7d1cc8b2704858992e9c49821 Author: Jan Kiszka Date: Fri May 27 11:35:26 2016 +0200 cobalt/rtdm: Also initialized driver refcount for protocol devices Was only done for named devices, thus leaving protocol devices in limbo state after rtdm_dev_unregister. Signed-off-by: Jan Kiszka --- kernel/cobalt/rtdm/device.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c index 8c54890..3e6a46b 100644 --- a/kernel/cobalt/rtdm/device.c +++ b/kernel/cobalt/rtdm/device.c @@ -303,10 +303,10 @@ static int register_driver(struct rtdm_driver *drv) goto fail_cdev; drv->named.major = MAJOR(rdev); - atomic_set(&drv->refcount, 1); bitmap_zero(drv->minor_map, RTDM_MAX_MINOR); done: + atomic_set(&drv->refcount, 1); drv->nb_statechange.notifier_call = state_change_notifier; drv->nb_statechange.priority = 0; cobalt_add_state_chain(&drv->nb_statechange); ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : cobalt/rtdm: add base minor setting for named drivers
Module: xenomai-3 Branch: wip/gpio Commit: b697eb6b36b1b3dabe25b50a0217b24753670806 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=b697eb6b36b1b3dabe25b50a0217b24753670806 Author: Philippe Gerum Date: Wed Jun 1 11:18:22 2016 +0200 cobalt/rtdm: add base minor setting for named drivers Some character/named drivers may want to set a non-zero base minor for indexing their devices (e.g. GPIO banks). To this end, the new .base_minor field can be set in device driver descriptors. Most in-tree driver descriptors reside in static memory which guarantees that such field is zero when unspecified. CAUTION: existing out of tree drivers have to initialize .base_minor explicitly if the descriptor does not reside on clean memory. --- include/cobalt/kernel/rtdm/driver.h |2 ++ kernel/cobalt/rtdm/device.c | 19 +-- kernel/drivers/udd/udd.c|1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 42f0b73..bcf6e54 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -280,6 +280,8 @@ struct rtdm_driver { * allocate a chrdev region for named devices. */ int device_count; + /** Base minor for named devices. */ + int base_minor; /** Reserved area */ struct { union { diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c index 3e6a46b..6c6299f 100644 --- a/kernel/cobalt/rtdm/device.c +++ b/kernel/cobalt/rtdm/device.c @@ -283,17 +283,23 @@ static int register_driver(struct rtdm_driver *drv) return -EINVAL; } - if (drv->device_count <= 0) + if (drv->device_count <= 0 || + drv->device_count >= RTDM_MAX_MINOR) + return -EINVAL; + + if (drv->base_minor < 0 || + drv->base_minor >= RTDM_MAX_MINOR) return -EINVAL; if ((drv->device_flags & RTDM_NAMED_DEVICE) == 0) goto done; - ret = alloc_chrdev_region(&rdev, 0, drv->device_count, + ret = alloc_chrdev_region(&rdev, drv->base_minor, drv->device_count, drv->profile_info.name); if (ret) { - printk(XENO_WARNING "cannot allocate chrdev region %s[0..%d]\n", - drv->profile_info.name, drv->device_count - 1); + printk(XENO_WARNING "cannot allocate chrdev region %s[%d..%d]\n", + drv->profile_info.name, drv->base_minor, + drv->base_minor + drv->device_count - 1); return ret; } @@ -333,7 +339,7 @@ static void unregister_driver(struct rtdm_driver *drv) if (drv->device_flags & RTDM_NAMED_DEVICE) { cdev_del(&drv->named.cdev); - unregister_chrdev_region(MKDEV(drv->named.major, 0), + unregister_chrdev_region(MKDEV(drv->named.major, drv->base_minor), drv->device_count); } } @@ -402,7 +408,8 @@ int rtdm_dev_register(struct rtdm_device *dev) if (drv->device_flags & RTDM_NAMED_DEVICE) { if (drv->device_flags & RTDM_FIXED_MINOR) { minor = dev->minor; - if (minor < 0 || minor >= drv->device_count) { + if (minor < 0 || + minor >= drv->base_minor + drv->device_count) { ret = -ENXIO; goto fail; } diff --git a/kernel/drivers/udd/udd.c b/kernel/drivers/udd/udd.c index 6f12235..e14ff0b 100644 --- a/kernel/drivers/udd/udd.c +++ b/kernel/drivers/udd/udd.c @@ -290,6 +290,7 @@ static inline int register_mapper(struct udd_device *udd) RTDM_SUBCLASS_GENERIC, 0); drv->device_flags = RTDM_NAMED_DEVICE|RTDM_FIXED_MINOR; drv->device_count = UDD_NR_MAPS; + drv->base_minor = 0; drv->ops = (struct rtdm_fd_ops){ .open = mapper_open, .close = mapper_close, ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : testsuite/xeno-test-run: requesting /bin/sh is enough
Module: xenomai-3 Branch: wip/gpio Commit: 84c80c5cc135a2cce046a4039a4658d659c3cefe URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=84c80c5cc135a2cce046a4039a4658d659c3cefe Author: Philippe Gerum Date: Tue Jun 7 18:17:48 2016 +0200 testsuite/xeno-test-run: requesting /bin/sh is enough --- testsuite/xeno-test/xeno-test-run-wrapper |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/xeno-test/xeno-test-run-wrapper b/testsuite/xeno-test/xeno-test-run-wrapper index e4d5aa8..24698bb 100644 --- a/testsuite/xeno-test/xeno-test-run-wrapper +++ b/testsuite/xeno-test/xeno-test-run-wrapper @@ -1,4 +1,4 @@ -#! /bin/bash +#! /bin/sh XENO_TEST_IN="/tmp/xeno-test-in-$$" XENO_TEST_OUT="/tmp/xeno-test-out-$$" ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : drivers/gpio: introduce real-time GPIO support
Module: xenomai-3 Branch: wip/gpio Commit: 2bba7740be7ce51755b6b7a3dd0a1fae3a79476d URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=2bba7740be7ce51755b6b7a3dd0a1fae3a79476d Author: Philippe Gerum Date: Wed May 25 10:54:22 2016 +0200 drivers/gpio: introduce real-time GPIO support --- configure.ac |1 + include/rtdm/Makefile.am |1 + include/rtdm/gpio.h| 24 +++ include/rtdm/uapi/Makefile.am |1 + include/rtdm/uapi/gpio.h | 28 +++ include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile|2 +- kernel/drivers/gpio/Kconfig| 25 +++ kernel/drivers/gpio/Makefile |7 + kernel/drivers/gpio/gpio-bcm2708.c | 39 kernel/drivers/gpio/gpio-core.c| 349 kernel/drivers/gpio/gpio-core.h| 48 + kernel/drivers/gpio/gpio-mxc.c | 67 +++ 14 files changed, 593 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 8bbeeef..88022a6 100644 --- a/configure.ac +++ b/configure.ac @@ -878,6 +878,7 @@ AC_CONFIG_FILES([ \ testsuite/Makefile \ testsuite/latency/Makefile \ testsuite/switchtest/Makefile \ + testsuite/gpiotest/Makefile \ testsuite/smokey/Makefile \ testsuite/smokey/arith/Makefile \ testsuite/smokey/sched-quota/Makefile \ diff --git a/include/rtdm/Makefile.am b/include/rtdm/Makefile.am index a4e6ff8..ad2c342 100644 --- a/include/rtdm/Makefile.am +++ b/include/rtdm/Makefile.am @@ -4,6 +4,7 @@ includesub_HEADERS =\ analogy.h \ autotune.h \ can.h \ + gpio.h \ ipc.h \ rtdm.h \ serial.h\ diff --git a/include/rtdm/gpio.h b/include/rtdm/gpio.h new file mode 100644 index 000..c61f229 --- /dev/null +++ b/include/rtdm/gpio.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2016 Philippe Gerum + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef _RTDM_GPIO_H +#define _RTDM_GPIO_H + +#include +#include + +#endif /* !_RTDM_GPIO_H */ diff --git a/include/rtdm/uapi/Makefile.am b/include/rtdm/uapi/Makefile.am index 7cff6c2..d53f10c 100644 --- a/include/rtdm/uapi/Makefile.am +++ b/include/rtdm/uapi/Makefile.am @@ -4,6 +4,7 @@ includesub_HEADERS =\ analogy.h \ autotune.h \ can.h \ + gpio.h \ ipc.h \ rtdm.h \ serial.h\ diff --git a/include/rtdm/uapi/gpio.h b/include/rtdm/uapi/gpio.h new file mode 100644 index 000..b0d4899 --- /dev/null +++ b/include/rtdm/uapi/gpio.h @@ -0,0 +1,28 @@ +/** + * @note Copyright (C) 2016 Philippe Gerum + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _RTDM_UAPI_GPIO_H +#define _RTDM_UAPI_GPIO_H + +#include + +#define GPIO_RTIOC_DIR_OUT _IOW(RTDM_CLASS_GPIO, 0, int) +#define GPIO_RTIOC_DIR_IN _IO(RTDM_CLASS_GPIO, 1) +#define GPIO_RTIOC_IRQEN _IO(RTDM_CLASS_GPIO, 2) +#define GPIO_RTIOC_IRQDIS _IO(RTDM_CLASS_GPIO, 3) + +#endif /* !_RTDM_UAPI_GPIO_H */ diff --git a/include/rtdm/uapi/rtdm.h b/include/rtdm/uapi/rtdm.h index eed3b36..c49378c 100644 --- a/include/rtdm/uapi/rtdm.h +++ b/include/rtdm/uapi/rtdm.h @@ -79,6 +79,7 @@ typedef int64_t nanosecs_rel_t; #define RTDM_CLASS_COBALT 8 #define RTDM_CLASS_UDD 9 #define RTDM_CLASS_MEMORY 10 +#define RTDM_CLASS_GPIO
[Xenomai-git] Philippe Gerum : testsuite/gpiotest: add GPIO test suite
Module: xenomai-3 Branch: wip/gpio Commit: a2851a6eb9b8e774d8907cf53a5effeea244cc3a URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=a2851a6eb9b8e774d8907cf53a5effeea244cc3a Author: Philippe Gerum Date: Wed Jun 1 15:59:27 2016 +0200 testsuite/gpiotest: add GPIO test suite --- testsuite/Makefile.am |2 + testsuite/gpiotest/Makefile.am | 19 testsuite/gpiotest/gpiotest.c | 188 3 files changed, 209 insertions(+) diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index e83e6cb..c345472 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -4,12 +4,14 @@ SUBDIRS = latency smokey if XENO_COBALT SUBDIRS += \ clocktest \ + gpiotest\ switchtest \ xeno-test endif DIST_SUBDIRS = \ clocktest \ + gpiotest\ latency \ smokey \ switchtest \ diff --git a/testsuite/gpiotest/Makefile.am b/testsuite/gpiotest/Makefile.am new file mode 100644 index 000..b01427b --- /dev/null +++ b/testsuite/gpiotest/Makefile.am @@ -0,0 +1,19 @@ +testdir = @XENO_TEST_DIR@ + +CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) + +test_PROGRAMS = gpiotest + +gpiotest_SOURCES = gpiotest.c + +gpiotest_CPPFLAGS =\ + $(XENO_USER_CFLAGS) \ + -I$(top_srcdir)/include + +gpiotest_LDFLAGS = @XENO_AUTOINIT_LDFLAGS@ $(XENO_POSIX_WRAPPERS) + +gpiotest_LDADD = \ + ../../lib/smokey/libsmokey.la \ + ../../lib/@XENO_CORE_LIB@ \ +@XENO_USER_LDADD@ \ + -lpthread -lrt diff --git a/testsuite/gpiotest/gpiotest.c b/testsuite/gpiotest/gpiotest.c new file mode 100644 index 000..838f498 --- /dev/null +++ b/testsuite/gpiotest/gpiotest.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2016 Philippe Gerum . + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +smokey_test_plugin(interrupt, + SMOKEY_ARGLIST( + SMOKEY_STRING(device), + ), + "Wait for interrupts from a GPIO pin.\n" + "\tdevice=." +); + +smokey_test_plugin(read_value, + SMOKEY_ARGLIST( + SMOKEY_STRING(device), + ), + "Read GPIO value.\n" + "\tdevice=." +); + +smokey_test_plugin(write_value, + SMOKEY_ARGLIST( + SMOKEY_STRING(device), + ), + "Write GPIO value.\n" + "\tdevice=." +); + +static int run_interrupt(struct smokey_test *t, int argc, char *const argv[]) +{ + const char *device = NULL; + int fd, ret; + fd_set set; + + smokey_parse_args(t, argc, argv); + + if (!SMOKEY_ARG_ISSET(interrupt, device)) { + warning("missing device= specification"); + return -EINVAL; + } + + device = SMOKEY_ARG_STRING(interrupt, device); + fd = open(device, O_RDWR); + if (fd < 0) { + ret = -errno; + warning("cannot open device %s [%s]", + device, symerror(ret)); + return ret; + } + + ret = ioctl(fd, GPIO_RTIOC_IRQEN); + if (ret) { + ret = -errno; + warning("GPIO_RTIOC_IRQEN failed on %s [%s]", + device, symerror(ret)); + return ret; + } + + FD_ZERO(&set); + FD_SET(fd, &set); + + for (;;) { + ret = select(fd + 1, &set, NULL, NULL, NULL); + if (ret < 0) { + ret = -errno; + warning("failed listening to %s [%s]", + device, symerror(ret)); + } + printf("kick %d!\n", ret); + } + + close(fd); + + return 0; +} + +static int run_read_value(struct smokey_test *t, int argc, char *const argv[]) +{ + const char *device = NULL; + int fd, ret, value = -1; + + smokey_parse_args(t, argc, argv); + + if (!SMOKEY_ARG_ISSET(read_value, device)) { + warning("missing device= specification"); + return -EINVAL; +
[Xenomai-git] Jan Kiszka : cobalt/rtdm: Fix driver reference counting
Module: xenomai-3 Branch: wip/gpio Commit: 2af3ab42d7a38f93e56ae714a446ce7c8d66bfc8 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=2af3ab42d7a38f93e56ae714a446ce7c8d66bfc8 Author: Jan Kiszka Date: Fri May 27 08:32:41 2016 +0200 cobalt/rtdm: Fix driver reference counting The rtdm smokey test triggered a BUG due to rtdm_dev_unregister not taking the reference counter of a driver into account. Fix this by moving the check into unregister_driver directly. Signed-off-by: Jan Kiszka --- kernel/cobalt/rtdm/device.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c index aa62169..8c54890 100644 --- a/kernel/cobalt/rtdm/device.c +++ b/kernel/cobalt/rtdm/device.c @@ -324,6 +324,9 @@ static void unregister_driver(struct rtdm_driver *drv) { XENO_BUG_ON(COBALT, drv->profile_info.magic != RTDM_CLASS_MAGIC); + if (!atomic_dec_and_test(&drv->refcount)) + return; + cobalt_remove_state_chain(&drv->nb_statechange); drv->profile_info.magic = ~RTDM_CLASS_MAGIC; @@ -477,8 +480,7 @@ fail: if (kdev) device_destroy(kdev_class, rdev); - if (atomic_dec_and_test(&drv->refcount)) - unregister_driver(drv); + unregister_driver(drv); mutex_unlock(®ister_lock); ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : cobalt/rtdm: add base minor setting for named drivers
Module: xenomai-3 Branch: stable-3.0.x Commit: b697eb6b36b1b3dabe25b50a0217b24753670806 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=b697eb6b36b1b3dabe25b50a0217b24753670806 Author: Philippe Gerum Date: Wed Jun 1 11:18:22 2016 +0200 cobalt/rtdm: add base minor setting for named drivers Some character/named drivers may want to set a non-zero base minor for indexing their devices (e.g. GPIO banks). To this end, the new .base_minor field can be set in device driver descriptors. Most in-tree driver descriptors reside in static memory which guarantees that such field is zero when unspecified. CAUTION: existing out of tree drivers have to initialize .base_minor explicitly if the descriptor does not reside on clean memory. --- include/cobalt/kernel/rtdm/driver.h |2 ++ kernel/cobalt/rtdm/device.c | 19 +-- kernel/drivers/udd/udd.c|1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 42f0b73..bcf6e54 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -280,6 +280,8 @@ struct rtdm_driver { * allocate a chrdev region for named devices. */ int device_count; + /** Base minor for named devices. */ + int base_minor; /** Reserved area */ struct { union { diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c index 3e6a46b..6c6299f 100644 --- a/kernel/cobalt/rtdm/device.c +++ b/kernel/cobalt/rtdm/device.c @@ -283,17 +283,23 @@ static int register_driver(struct rtdm_driver *drv) return -EINVAL; } - if (drv->device_count <= 0) + if (drv->device_count <= 0 || + drv->device_count >= RTDM_MAX_MINOR) + return -EINVAL; + + if (drv->base_minor < 0 || + drv->base_minor >= RTDM_MAX_MINOR) return -EINVAL; if ((drv->device_flags & RTDM_NAMED_DEVICE) == 0) goto done; - ret = alloc_chrdev_region(&rdev, 0, drv->device_count, + ret = alloc_chrdev_region(&rdev, drv->base_minor, drv->device_count, drv->profile_info.name); if (ret) { - printk(XENO_WARNING "cannot allocate chrdev region %s[0..%d]\n", - drv->profile_info.name, drv->device_count - 1); + printk(XENO_WARNING "cannot allocate chrdev region %s[%d..%d]\n", + drv->profile_info.name, drv->base_minor, + drv->base_minor + drv->device_count - 1); return ret; } @@ -333,7 +339,7 @@ static void unregister_driver(struct rtdm_driver *drv) if (drv->device_flags & RTDM_NAMED_DEVICE) { cdev_del(&drv->named.cdev); - unregister_chrdev_region(MKDEV(drv->named.major, 0), + unregister_chrdev_region(MKDEV(drv->named.major, drv->base_minor), drv->device_count); } } @@ -402,7 +408,8 @@ int rtdm_dev_register(struct rtdm_device *dev) if (drv->device_flags & RTDM_NAMED_DEVICE) { if (drv->device_flags & RTDM_FIXED_MINOR) { minor = dev->minor; - if (minor < 0 || minor >= drv->device_count) { + if (minor < 0 || + minor >= drv->base_minor + drv->device_count) { ret = -ENXIO; goto fail; } diff --git a/kernel/drivers/udd/udd.c b/kernel/drivers/udd/udd.c index 6f12235..e14ff0b 100644 --- a/kernel/drivers/udd/udd.c +++ b/kernel/drivers/udd/udd.c @@ -290,6 +290,7 @@ static inline int register_mapper(struct udd_device *udd) RTDM_SUBCLASS_GENERIC, 0); drv->device_flags = RTDM_NAMED_DEVICE|RTDM_FIXED_MINOR; drv->device_count = UDD_NR_MAPS; + drv->base_minor = 0; drv->ops = (struct rtdm_fd_ops){ .open = mapper_open, .close = mapper_close, ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : cobalt/rtdm: allow up to 1024 minors per driver
Module: xenomai-3 Branch: stable-3.0.x Commit: 3e90650a417f57916a6520c97382dba47f6ed01f URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=3e90650a417f57916a6520c97382dba47f6ed01f Author: Philippe Gerum Date: Wed Jun 1 10:53:28 2016 +0200 cobalt/rtdm: allow up to 1024 minors per driver --- include/cobalt/kernel/rtdm/driver.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 1354d9a..42f0b73 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -94,7 +94,7 @@ enum rtdm_selecttype; /** @} Device Flags */ /** Maximum number of named devices per driver. */ -#define RTDM_MAX_MINOR 256 +#define RTDM_MAX_MINOR 1024 /** @} rtdm_device_register */ ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : boilerplate: provide count-leading/trailing-bits ops
Module: xenomai-3 Branch: next Commit: fe5b21b7faa0309fb46325989343c8722ade8107 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=fe5b21b7faa0309fb46325989343c8722ade8107 Author: Philippe Gerum Date: Tue Jun 7 10:10:17 2016 +0200 boilerplate: provide count-leading/trailing-bits ops --- include/boilerplate/compiler.h | 48 1 file changed, 48 insertions(+) diff --git a/include/boilerplate/compiler.h b/include/boilerplate/compiler.h index e558f73..0509e33 100644 --- a/include/boilerplate/compiler.h +++ b/include/boilerplate/compiler.h @@ -58,4 +58,52 @@ #define __deprecated __attribute__((__deprecated__)) #endif +#ifdef __cplusplus +extern "C" { +#endif + +void __invalid_operand_size(void); + +#define ctz(__v) \ + ({ \ + int __ret; \ + if (!__v) \ + __ret = sizeof(__v) * 8;\ + else\ + switch (sizeof(__v)) { \ + case sizeof(int): \ + __ret = __builtin_ctz((unsigned int)__v); \ + break; \ + case sizeof(long long): \ + __ret = __builtin_ctzll(__v); \ + break; \ + default:\ + __invalid_operand_size(); \ + } \ + __ret; \ + }) + +#define clz(__v) \ + ({ \ + int __ret; \ + if (!__v) \ + __ret = sizeof(__v) * 8;\ + else\ + switch (sizeof(__v)) { \ + case sizeof(int): \ + __ret = __builtin_clz((unsigned int)__v); \ + break; \ + case sizeof(long long): \ + __ret = __builtin_clzll(__v); \ + break; \ + default:\ + __invalid_operand_size(); \ + } \ + __ret; \ + }) + +#ifdef __cplusplus +} +#endif + #endif /* _BOILERPLATE_COMPILER_H */ ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : cobalt/rtdm: allow up to 1024 minors per driver
Module: xenomai-3 Branch: next Commit: 98834bd6bd0edd168ec9fcdb4d6b5217f669d01f URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=98834bd6bd0edd168ec9fcdb4d6b5217f669d01f Author: Philippe Gerum Date: Wed Jun 1 10:53:28 2016 +0200 cobalt/rtdm: allow up to 1024 minors per driver --- include/cobalt/kernel/rtdm/driver.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 1354d9a..42f0b73 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -94,7 +94,7 @@ enum rtdm_selecttype; /** @} Device Flags */ /** Maximum number of named devices per driver. */ -#define RTDM_MAX_MINOR 256 +#define RTDM_MAX_MINOR 1024 /** @} rtdm_device_register */ ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : cobalt/rtdm: add base minor setting for named drivers
Module: xenomai-3 Branch: next Commit: c412063da3a4f4f4c1c4d72497f3ac2c54679d0f URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=c412063da3a4f4f4c1c4d72497f3ac2c54679d0f Author: Philippe Gerum Date: Wed Jun 1 11:18:22 2016 +0200 cobalt/rtdm: add base minor setting for named drivers Some character/named drivers may want to set a non-zero base minor for indexing their devices (e.g. GPIO banks). To this end, the new .base_minor field can be set in device driver descriptors. Most in-tree driver descriptors reside in static memory which guarantees that such field is zero when unspecified. CAUTION: existing out of tree drivers have to initialize .base_minor explicitly if the descriptor does not reside on clean memory. --- include/cobalt/kernel/rtdm/driver.h |2 ++ kernel/cobalt/rtdm/device.c | 19 +-- kernel/drivers/udd/udd.c|1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 42f0b73..bcf6e54 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -280,6 +280,8 @@ struct rtdm_driver { * allocate a chrdev region for named devices. */ int device_count; + /** Base minor for named devices. */ + int base_minor; /** Reserved area */ struct { union { diff --git a/kernel/cobalt/rtdm/device.c b/kernel/cobalt/rtdm/device.c index 3e6a46b..6c6299f 100644 --- a/kernel/cobalt/rtdm/device.c +++ b/kernel/cobalt/rtdm/device.c @@ -283,17 +283,23 @@ static int register_driver(struct rtdm_driver *drv) return -EINVAL; } - if (drv->device_count <= 0) + if (drv->device_count <= 0 || + drv->device_count >= RTDM_MAX_MINOR) + return -EINVAL; + + if (drv->base_minor < 0 || + drv->base_minor >= RTDM_MAX_MINOR) return -EINVAL; if ((drv->device_flags & RTDM_NAMED_DEVICE) == 0) goto done; - ret = alloc_chrdev_region(&rdev, 0, drv->device_count, + ret = alloc_chrdev_region(&rdev, drv->base_minor, drv->device_count, drv->profile_info.name); if (ret) { - printk(XENO_WARNING "cannot allocate chrdev region %s[0..%d]\n", - drv->profile_info.name, drv->device_count - 1); + printk(XENO_WARNING "cannot allocate chrdev region %s[%d..%d]\n", + drv->profile_info.name, drv->base_minor, + drv->base_minor + drv->device_count - 1); return ret; } @@ -333,7 +339,7 @@ static void unregister_driver(struct rtdm_driver *drv) if (drv->device_flags & RTDM_NAMED_DEVICE) { cdev_del(&drv->named.cdev); - unregister_chrdev_region(MKDEV(drv->named.major, 0), + unregister_chrdev_region(MKDEV(drv->named.major, drv->base_minor), drv->device_count); } } @@ -402,7 +408,8 @@ int rtdm_dev_register(struct rtdm_device *dev) if (drv->device_flags & RTDM_NAMED_DEVICE) { if (drv->device_flags & RTDM_FIXED_MINOR) { minor = dev->minor; - if (minor < 0 || minor >= drv->device_count) { + if (minor < 0 || + minor >= drv->base_minor + drv->device_count) { ret = -ENXIO; goto fail; } diff --git a/kernel/drivers/udd/udd.c b/kernel/drivers/udd/udd.c index 6f12235..e14ff0b 100644 --- a/kernel/drivers/udd/udd.c +++ b/kernel/drivers/udd/udd.c @@ -290,6 +290,7 @@ static inline int register_mapper(struct udd_device *udd) RTDM_SUBCLASS_GENERIC, 0); drv->device_flags = RTDM_NAMED_DEVICE|RTDM_FIXED_MINOR; drv->device_count = UDD_NR_MAPS; + drv->base_minor = 0; drv->ops = (struct rtdm_fd_ops){ .open = mapper_open, .close = mapper_close, ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : boilerplate: add AVL library
Module: xenomai-3 Branch: next Commit: 0e25606b1dd4c89d42ce5177023ceb2ab180c3f5 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=0e25606b1dd4c89d42ce5177023ceb2ab180c3f5 Author: Philippe Gerum Date: Tue May 31 17:30:21 2016 +0200 boilerplate: add AVL library --- include/boilerplate/Makefile.am |1 + include/boilerplate/avl.h | 298 ++ lib/boilerplate/Makefile.am |1 + lib/boilerplate/avl.c | 380 +++ 4 files changed, 680 insertions(+) diff --git a/include/boilerplate/Makefile.am b/include/boilerplate/Makefile.am index 2d3ace8..c975509 100644 --- a/include/boilerplate/Makefile.am +++ b/include/boilerplate/Makefile.am @@ -3,6 +3,7 @@ includesubdir = $(includedir)/boilerplate includesub_HEADERS = \ ancillaries.h \ atomic.h\ + avl.h \ compiler.h \ debug.h \ hash.h \ diff --git a/include/boilerplate/avl.h b/include/boilerplate/avl.h new file mode 100644 index 000..1aa84bf --- /dev/null +++ b/include/boilerplate/avl.h @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2015 Gilles Chanteperdrix + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef _BOILERPLATE_AVL_H +#define _BOILERPLATE_AVL_H + +#include + +struct avlh { + unsigned int thr: 3; + int type: 2; + int balance :2; + unsigned int flags :25; /* Application-specific */ + struct avlh *link[3]; +}; + +/* Using -1 and 1 for left and right is slightly faster than 0 and 1, using 0 + for "up" is just here for orthogonality... and avoid wasting 4 bytes or + having to use a union in struct avlh. */ +#define AVL_LEFT -1 +#define AVL_UP0 +#define AVL_RIGHT 1 +/* maps AVL_LEFT to AVL_RIGHT and reciprocally. */ +#define avl_opposite(type) (-(type)) +/* maps AVL_LEFT to -1 and AVL_RIGHT to 1. */ +#define avl_type2sign(type) (type) +/* maps AVL_LEFT and AVL_RIGHT to arrays index (or bit positions). */ +#define avl_type2index(type) ((type)+1) +/* maps <0 to AVL_LEFT and >0 to AVL_RIGHT. */ +#define avl_sign2type(sign) (sign) + +#define AVL_THR_LEFT (1thr &= ~(1 << avl_type2index(side))) +#define avlh_thr_tst(holder, side) ((holder)->thr & (1 << avl_type2index(side))) +#define avlh_link(holder, dir) ((holder)->link[avl_type2index(dir)]) +#define avlh_up(holder)avlh_link((holder), AVL_UP) +#define avlh_left(holder) avlh_link((holder), AVL_LEFT) +#define avlh_right(holder) avlh_link((holder), AVL_RIGHT) +#define avlh_parent_link(holder) (avlh_link(avlh_up(holder), (holder)->type)) + +struct avl; + +typedef struct avlh *avl_search_t(const struct avl *, const struct avlh *, int *); + +typedef int avlh_cmp_t(const struct avlh *const, const struct avlh *const); + +struct avl { + struct avlh anchor; + avl_search_t *search; + avlh_cmp_t *cmp; + struct avlh *end[3]; + unsigned int count; + unsigned int height; +}; + +#define avl_searchfn(avl) ((avl)->search) +#define avl_cmp(avl) ((avl)->cmp) +#define avl_count(avl)((avl)->count) +#define avl_height(avl) ((avl)->height) +#define avl_anchor(avl) (&(avl)->anchor) +#define avl_end(avl, dir) ((avl)->end[avl_type2index(dir)]) +#define avl_top(avl) (avlh_right(avl_anchor(avl))) +#define avl_head(avl) (avl_end((avl), AVL_LEFT)) +#define avl_tail(avl) (avl_end((avl), AVL_RIGHT)) + +#ifdef __cplusplus +extern "C" { +#endif + +void avl_init(struct avl *avl, avl_search_t *search, avlh_cmp_t *cmp); + +void avl_destroy(struct avl *avl); + +void avl_clear(struct avl *avl, void (*destruct)(struct avlh *)); + +int avl_insert(struct avl *avl, struct avlh *holder); + +int avl_prepend(struct avl *avl, struct avlh *holder); + +int avl_append(struct avl
[Xenomai-git] Philippe Gerum : copperplate/heapobj-pshared: unlink main heap file on exit if no registry
Module: xenomai-3 Branch: next Commit: c7088a58d3412cd331bb3e3e1f9d1375ccecdcd7 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=c7088a58d3412cd331bb3e3e1f9d1375ccecdcd7 Author: Philippe Gerum Date: Mon Jun 6 20:34:10 2016 +0200 copperplate/heapobj-pshared: unlink main heap file on exit if no registry sysregd removes the shared heap upon exit of the last process attached to the session. When registry support is disabled, make sure the backing file is unlinked upon exit of the main process. --- lib/copperplate/heapobj-pshared.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/lib/copperplate/heapobj-pshared.c b/lib/copperplate/heapobj-pshared.c index bd9ea47..f4c6f37 100644 --- a/lib/copperplate/heapobj-pshared.c +++ b/lib/copperplate/heapobj-pshared.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -678,6 +679,19 @@ out: return ret; } +#ifndef CONFIG_XENO_REGISTRY +static void unlink_main_heap(void) +{ + /* +* Only the master process run this when there is no registry +* support (i.e. the one which has initialized the main shared +* heap for the session). When the registry is enabled, +* sysregd does the housekeeping. +*/ + shm_unlink(main_pool.fsname); +} +#endif + static int create_main_heap(pid_t *cnode_r) { const char *session = __copperplate_setup_data.session_label; @@ -770,6 +784,10 @@ reset: ret = fchown(fd, geteuid(), getegid()); (void)ret; init: +#ifndef CONFIG_XENO_REGISTRY + atexit(unlink_main_heap); +#endif + ret = ftruncate(fd, 0); /* Clear all previous contents if any. */ if (__bterrno(ret)) goto unlink_fail; ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : copperplate/heapobj-pshared: introduce allocation bitmap
Module: xenomai-3 Branch: next Commit: 497af95d240458e758685d940d4eec6a5a9a4388 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=497af95d240458e758685d940d4eec6a5a9a4388 Author: Philippe Gerum Date: Fri Jun 3 10:00:38 2016 +0200 copperplate/heapobj-pshared: introduce allocation bitmap Using a free list for maintaining pages leads to pathological execution times when releasing blocks obtained from huge heaps (i.e. hundreds of megabytes). Rework the core to use an allocation bitmap instead. --- lib/copperplate/heapobj-pshared.c | 424 + lib/copperplate/internal.h| 18 +- 2 files changed, 259 insertions(+), 183 deletions(-) diff --git a/lib/copperplate/heapobj-pshared.c b/lib/copperplate/heapobj-pshared.c index 8c5dac6..bd9ea47 100644 --- a/lib/copperplate/heapobj-pshared.c +++ b/lib/copperplate/heapobj-pshared.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -43,15 +44,7 @@ #include "xenomai/init.h" #include "internal.h" -#define HOBJ_PAGE_SHIFT9 /* 2^9 => 512 bytes */ -#define HOBJ_PAGE_SIZE (1U << HOBJ_PAGE_SHIFT) -#define HOBJ_PAGE_MASK (~(HOBJ_PAGE_SIZE-1)) -#define HOBJ_PAGE_ALIGN(addr) (((addr)+HOBJ_PAGE_SIZE-1)&HOBJ_PAGE_MASK) - -#define HOBJ_MINALIGNSZ (1U << 4) /* i.e. 16 bytes */ -#define HOBJ_MAXEXTSZ (1U << 31) /* i.e. 2Gb */ - -enum { +enum { /* FIXME: page_free redundant with bitmap */ page_free =0, page_cont =1, page_list =2 @@ -66,8 +59,9 @@ struct shared_extent { struct holder link; memoff_t membase; /* Base offset of page array */ memoff_t memlim;/* Offset limit of page array */ - memoff_t freelist; /* Head of free page list */ - struct page_entry pagemap[1]; /* Start of page map */ + memoff_t bitmap;/* Offset of allocation bitmap */ + int bitwords; /* 32bit words in bitmap */ + struct page_entry pagemap[0]; /* Start of page map */ }; /* @@ -117,24 +111,38 @@ static inline size_t __align_to(size_t size, size_t al) return ((size+al-1)&(~(al-1))); } -static inline size_t get_pagemap_size(size_t h) +static inline size_t get_pagemap_size(size_t h, + memoff_t *bmapoff, int *bmapwords) { + int nrpages = h >> HOBJ_PAGE_SHIFT, bitmapw; + size_t pagemapsz; + /* * Return the size of the meta data required to map 'h' bytes * of user memory in pages of HOBJ_PAGE_SIZE bytes. The meta * data includes the length of the extent descriptor, plus the -* length of the page mapping array. 'h' must be a multiple of -* HOBJ_PAGE_SIZE on entry. +* length of the page mapping array followed by the allocation +* bitmap. 'h' must be a multiple of HOBJ_PAGE_SIZE on entry. */ assert((h & ~HOBJ_PAGE_MASK) == 0); - return __align_to((h >> HOBJ_PAGE_SHIFT) * sizeof(struct page_entry) - + sizeof(struct shared_extent), HOBJ_MINALIGNSZ); + pagemapsz = __align_to(nrpages * sizeof(struct page_entry), + sizeof(uint32_t)); + bitmapw =__align_to(nrpages, 32) / 32; + if (bmapoff) + *bmapoff = offsetof(struct shared_extent, pagemap) + pagemapsz; + if (bmapwords) + *bmapwords = bitmapw; + + return __align_to(pagemapsz + + sizeof(struct shared_extent) + + bitmapw * sizeof(uint32_t), + HOBJ_MINALIGNSZ); } static void init_extent(void *base, struct shared_extent *extent) { - caddr_t freepage; - int n, lastpgnum; + int lastpgnum; + uint32_t *p; __holder_init_nocheck(base, &extent->link); @@ -146,20 +154,18 @@ static void init_extent(void *base, struct shared_extent *extent) */ assert(lastpgnum >= 1); - /* Mark each page as free in the page map. */ - for (n = 0, freepage = __shref(base, extent->membase); -n < lastpgnum; n++, freepage += HOBJ_PAGE_SIZE) { - *((memoff_t *)freepage) = __shoff(base, freepage) + HOBJ_PAGE_SIZE; - extent->pagemap[n].type = page_free; - extent->pagemap[n].bcount = 0; - } - - *((memoff_t *)freepage) = 0; - extent->pagemap[lastpgnum].type = page_free; - extent->pagemap[lastpgnum].bcount = 0; + /* Mark all pages as free in the page map. */ + memset(extent->pagemap, 0, lastpgnum * sizeof(struct page_entry)); - /* The first page starts the free list of a new extent. */ - extent->freelist = extent->membase; + /* Clear the allocation bitmap. */ + p = __shref(base, extent->bitmap); + memset(p, 0, extent->bitwords * sizeof(uint32_t)); + /* +* Mark the unused trailing bits (due to alignment) as