This patch removes much of the #ifdefery that was in ksrc/skins/posix/shm.c. It also initializes a global shared heap (for process-shared objects), as well as a per-process shared heap. These two heaps are mapped in the posix skin library initialization, using the new get_heap_addr syscall to get their addresses.
Of course, at this chance, we use the XNARCH_SHARED_HEAP_FLAGS macro, as a flag passed to xnheap_init_mapped. Several questions here: - the heaps are created with a size of three pages, hardcoded, maybe we should make this size somehow configurable (Kconfig, /proc, whatever). My idea was that each mutex will use about 4 bytes in a heap, so 12 Kbytes is plenty. - if we do not want to waste memory, like the xnthread_t * TSD, I wonder if these two heaps should not be allocated by the core event callback, unfortunately, this would mean that we would have to associate a per-process data with the core skin, which we avoided until now. --- ksrc/skins/posix/internal.h | 10 ++++++ ksrc/skins/posix/module.c | 41 ++++++++++++++++++++++++++ ksrc/skins/posix/shm.c | 44 ++++------------------------ src/skins/posix/init.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 37 deletions(-) Index: ksrc/skins/posix/internal.h =================================================================== --- ksrc/skins/posix/internal.h (revision 3718) +++ ksrc/skins/posix/internal.h (working copy) @@ -71,6 +71,7 @@ typedef struct { xnqueue_t semq; xnqueue_t threadq; xnqueue_t timerq; + xnheap_t shm_heap; } pse51_kqueues_t; #ifdef CONFIG_XENO_OPT_PERVASIVE @@ -202,4 +203,13 @@ static inline int clock_flag(int flag, c int pse51_mq_select_bind(mqd_t fd, struct xnselector *selector, unsigned type, unsigned index); +#ifdef CONFIG_XENO_OPT_PERVASIVE +#define pse51_shm_heap_init(h, l, f) xnheap_init_mapped(h, l, f) +#define pse51_shm_heap_destroy(h) xnheap_destroy_mapped(h) +#else /* !CONFIG_XENO_OPT_PERVASIVE */ +int pse51_shm_heap_init(xnheap_t *heap, unsigned len, int flags); + +void pse51_shm_heap_destroy(xnheap_t *heap); +#endif /* !CONFIG_XENO_OPT_PERVASIVE */ + #endif /* !_POSIX_INTERNAL_H */ Index: ksrc/skins/posix/module.c =================================================================== --- ksrc/skins/posix/module.c (revision 3718) +++ ksrc/skins/posix/module.c (working copy) @@ -78,6 +78,36 @@ MODULE_PARM_DESC(time_slice, "Default ti xntbase_t *pse51_tbase; +#ifndef CONFIG_XENO_OPT_PERVASIVE +static void pse51_free_heap_extent(xnheap_t *heap, + void *extent, u_long size, void *cookie) +{ + xnarch_free_host_mem(extent, size); +} + +int pse51_shm_heap_init(xnheap_t *heap, unsigned len, int flags) +{ + void *heapaddr = xnarch_alloc_host_mem(len); + int err; + + if (heapaddr) { + err = xnheap_init(&shm->heapbase, + heapaddr, len, XNCORE_PAGE_SIZE); + if (err) + xnarch_free_host_mem(heapaddr, len); + + return err; + } + + return -ENOMEM; +} + +void pse51_shm_heap_destroy(xnheap_t *heap) +{ + xnheap_destroy(heap, &pse51_free_heap_extent, NULL); +} +#endif /* !CONFIG_XENO_OPT_PERVASIVE */ + static void pse51_shutdown(int xtype) { pse51_thread_pkg_cleanup(); @@ -98,6 +128,7 @@ static void pse51_shutdown(int xtype) #ifdef CONFIG_XENO_OPT_PERVASIVE pse51_syscall_cleanup(); #endif /* CONFIG_XENO_OPT_PERVASIVE */ + pse51_shm_heap_destroy(&pse51_global_kqueues.shm_heap); #ifdef __KERNEL__ pse51_apc_pkg_cleanup(); #endif /* __KERNEL__ */ @@ -127,11 +158,21 @@ int SKIN_INIT(posix) goto fail_free_tbase; #endif /* __KERNEL__ */ + err = pse51_shm_heap_init(&pse51_global_kqueues.shm_heap, 3 * PAGE_SIZE, + (XNARCH_SHARED_HEAP_FLAGS ?: GFP_USER)); + if (err) + goto fail_cleanup_apc; + #ifdef CONFIG_XENO_OPT_PERVASIVE err = pse51_syscall_init(); #endif /* CONFIG_XENO_OPT_PERVASIVE */ if (err != 0) { + pse51_shm_heap_destroy(&pse51_global_kqueues.shm_heap); + fail_cleanup_apc: +#ifdef __KERNEL__ + pse51_apc_pkg_cleanup(); fail_free_tbase: +#endif /* __KERNEL__ */ xntbase_free(pse51_tbase); fail_shutdown_pod: xnpod_shutdown(err); Index: ksrc/skins/posix/shm.c =================================================================== --- ksrc/skins/posix/shm.c (revision 3718) +++ ksrc/skins/posix/shm.c (working copy) @@ -90,14 +90,6 @@ static void pse51_shm_init(pse51_shm_t * appendq(&pse51_shmq, &shm->link); } -#ifndef CONFIG_XENO_OPT_PERVASIVE -static void pse51_free_heap_extent(xnheap_t *heap, - void *extent, u_long size, void *cookie) -{ - xnarch_free_host_mem(extent, size); -} -#endif /* !CONFIG_XENO_OPT_PERVASIVE */ - /* Must be called nklock locked, irq off. */ static void pse51_shm_destroy(pse51_shm_t * shm, int force) { @@ -111,11 +103,7 @@ static void pse51_shm_destroy(pse51_shm_ if (shm->addr) { xnheap_free(&shm->heapbase, shm->addr); -#ifdef CONFIG_XENO_OPT_PERVASIVE - xnheap_destroy_mapped(&shm->heapbase); -#else /* !CONFIG_XENO_OPT_PERVASIVE. */ - xnheap_destroy(&shm->heapbase, &pse51_free_heap_extent, NULL); -#endif /* !CONFIG_XENO_OPT_PERVASIVE. */ + pse51_shm_heap_destroy(&shm->heapbase); shm->addr = NULL; shm->size = 0; @@ -534,37 +522,19 @@ int ftruncate(int fd, off_t len) memcpy(addr, shm->addr, size); xnheap_free(&shm->heapbase, shm->addr); -#ifdef CONFIG_XENO_OPT_PERVASIVE - xnheap_destroy_mapped(&shm->heapbase); -#else /* !CONFIG_XENO_OPT_PERVASIVE. */ - xnheap_destroy(&shm->heapbase, &pse51_free_heap_extent, - NULL); -#endif /* !CONFIG_XENO_OPT_PERVASIVE. */ + pse51_shm_heap_destroy(&shm->heapbase); shm->addr = NULL; shm->size = 0; } if (len) { -#ifdef CONFIG_XENO_OPT_PERVASIVE - int flags = len <= 128 * 1024 ? GFP_USER : 0; - err = -xnheap_init_mapped(&shm->heapbase, len, flags); -#else /* !CONFIG_XENO_OPT_PERVASIVE. */ - { - void *heapaddr = xnarch_alloc_host_mem(len); - - if (heapaddr) - err = - -xnheap_init(&shm->heapbase, - heapaddr, len, - XNCORE_PAGE_SIZE); - else - err = ENOMEM; + int flags = (XNARCH_SHARED_HEAP_FLAGS ?: + len <= 128 * 1024 ? GFP_USER : 0); - if (err) - goto err_up; - } -#endif /* !CONFIG_XENO_OPT_PERVASIVE. */ + err = -pse51_shm_heap_init(&shm->heapbase, len, flags); + if (err) + goto err_up; shm->size = xnheap_max_contiguous(&shm->heapbase); shm->addr = xnheap_alloc(&shm->heapbase, shm->size); Index: src/skins/posix/init.c =================================================================== --- src/skins/posix/init.c (revision 3718) +++ src/skins/posix/init.c (working copy) @@ -33,10 +33,49 @@ int __pse51_muxid = -1; int __rtdm_muxid = -1; int __rtdm_fd_start = INT_MAX; static int fork_handler_registered; +pthread_key_t pse51_cur_key; +unsigned long pse51_shared_map[2] = {0, 0}; int __wrap_pthread_setschedparam(pthread_t, int, const struct sched_param *); void pse51_clock_init(int); +static void *map_shared_heap(unsigned shared) +{ + void *heap_addr; + int fd, err; + + fd = __real_open("/dev/rtheap", O_RDWR, 0); + if (fd < 0) { + fprintf(stderr, "open: %m\n"); + return MAP_FAILED; + } + + err = XENOMAI_SKINCALL2(__pse51_muxid, + __pse51_get_heap_addr, &heap_addr, shared); + if (err < 0) { + fprintf(stderr, "get_heap_addr: %m\n"); + return MAP_FAILED; + } + + err = __real_ioctl(fd, 0, heap_addr); + if (err < 0) { + fprintf(stderr, "ioctl: %m\n"); + return MAP_FAILED; + } + + heap_addr = __real_mmap(NULL, 3 * getpagesize(), + PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + close(fd); + + return heap_addr; +} + +static void unmap_shared_heap(unsigned long heap_addr) +{ + __real_munmap((void *) heap_addr, 3 * getpagesize()); +} + static __attribute__ ((constructor)) void __init_posix_interface(void) { @@ -83,7 +122,35 @@ void __init_posix_interface(void) } #endif /* !CONFIG_XENO_POSIX_AUTO_MLOCKALL */ + if (pse51_shared_map[0]) + /* We have forked, so, let us recreate the private mapping */ + unmap_shared_heap(pse51_shared_map[0]); + pse51_shared_map[0] = (unsigned long) map_shared_heap(0); + if (pse51_shared_map[0] == (unsigned long) MAP_FAILED) { + perror("Xenomai Posix skin init: mmap(local heap)"); + exit(EXIT_FAILURE); + } + + fprintf(stderr, "sizeof(pthread_mutex_t): %d," + " sizeof(shadow_mutex): %d\n", + sizeof(pthread_mutex_t), sizeof(struct __shadow_mutex)); + if (sizeof(struct __shadow_mutex) > sizeof(pthread_mutex_t)) + exit(EXIT_FAILURE); + if (!fork_handler_registered) { + err = pthread_key_create(&pse51_cur_key, NULL); + if (err) { + fprintf(stderr, "Xenomai Posix skin init:" + " pthread_key_create: %s\n", strerror(err)); + exit(EXIT_FAILURE); + } + + pse51_shared_map[1] = (unsigned long) map_shared_heap(1); + if (pse51_shared_map[1] == (unsigned long) MAP_FAILED) { + perror("Xenomai Posix skin init: mmap(global heap)"); + exit(EXIT_FAILURE); + } + err = pthread_atfork(NULL, NULL, &__init_posix_interface); if (err) { fprintf(stderr, "Xenomai Posix skin init: " @@ -93,3 +160,4 @@ void __init_posix_interface(void) fork_handler_registered = 1; } } + -- Gilles. _______________________________________________ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core