# rtai_shm.h

Go to the documentation of this file.

    00001
    00026 /*
    00027 ACKNOWLEDGMENTS:
    00028 - The suggestion and the code for mmapping at a user specified address is due to  Trevor Woolven (trevw@zentropix.com).
    00029 */
    00030
    00031
    00032 #ifndef _RTAI_SHM_H
    00033 #define _RTAI_SHM_H
    00034
    00038 #define GLOBAL_HEAP_ID  0x9ac6d9e5  // nam2num("RTGLBH");
    00039
    00040 #define USE_VMALLOC     0
    00041 #define USE_GFP_KERNEL  1
    00042 #define USE_GFP_ATOMIC  2
    00043 #define USE_GFP_DMA     3
    00044
    00066 #define rtai_kmalloc(name, size) \
    00067         rt_shm_alloc(name, size, USE_VMALLOC)  // legacy
    00068
    00086 #define rtai_kfree(name) \
    00087         rt_shm_free(name)  // legacy
    00088
    00089 #if defined(__KERNEL__)
    00090
    00091 #include <linux/module.h>
    00092 #include <linux/version.h>
    00093 #include <linux/vmalloc.h>
    00094 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
    00095 #include <linux/wrapper.h>
    00096 #else /* >= 2.6.0 */
    00097 #include <linux/mm.h>
    00098 #define mem_map_reserve(p)   SetPageReserved(p)
    00099 #define mem_map_unreserve(p) ClearPageReserved(p)
    00100 #endif /* < 2.6.0 */
    00101
    00102 #include <rtai_malloc.h>
    00103
    00104 #include <asm/rtai_shm.h>
    00105
    00106 #ifdef __cplusplus
    00107 extern "C" {
    00108 #endif /* __cplusplus */
    00109
    00110 int __rtai_shm_init(void);
    00111
    00112 void __rtai_shm_exit(void);
    00113
    00114 void *rt_shm_alloc(unsigned long name,
    00115                    int size,
    00116                    int suprt);
    00117
    00118 #define rt_shm_alloc_adr(adr, name, size) \
    00119         rt_shm_alloc(name, size, suprt)
    00120
    00121 int rt_shm_free(unsigned long name);
    00122
    00123 void *rt_heap_open(unsigned long name,
    00124                    int size,
    00125                    int suprt);
    00126
    00127 #define rt_heap_open_adr(adr, name, size, suprt) \
    00128         rt_heap_open(name, size, suprt)
    00129
    00130 void *rt_halloc(int size);
    00131
    00132 void rt_hfree(void *addr);
    00133
    00134 void *rt_named_halloc(unsigned long name,
    00135                       int size);
    00136
    00137 void rt_named_hfree(void *addr);
    00138
    00139 void *rt_named_malloc(unsigned long name,
    00140                       int size);
    00141
    00142 void rt_named_free(void *addr);
    00143
    00144 void *rvmalloc(unsigned long size);
    00145
    00146 void rvfree(void *mem,
    00147             unsigned long size);
    00148
    00149 int rvmmap(void *mem,
    00150            unsigned long memsize,
    00151            struct vm_area_struct *vma);
    00152
    00153 void *rkmalloc(int *size,
    00154                int suprt);
    00155
    00156 void rkfree(void *mem,
    00157             unsigned long size);
    00158
    00159 int rkmmap(void *mem,
    00160            unsigned long memsize,
    00161            struct vm_area_struct *vma);
    00162
    00163 #ifdef __cplusplus
    00164 }
    00165 #endif /* __cplusplus */
    00166
    00167 #else /* !__KERNEL__ */
    00168
    00169 #include <fcntl.h>
    00170 #include <unistd.h>
    00171 #include <sys/mman.h>
    00172 #include <sys/ioctl.h>
    00173 #include <rtai_lxrt.h>
    00174
    00175 //#define SHM_USE_LXRT
    00176
    00177 #define RTAI_SHM_DEV  "/dev/rtai_shm"
    00178
    00179 static inline void *_rt_shm_alloc(void *start, unsigned long name, int size, int suprt, int isheap)
    00180 {
    00181         int hook;
    00182         void *adr;
    00183         if ((hook = open(RTAI_SHM_DEV, O_RDWR)) <= 0) {
    00184                 return 0;
    00185         } else {
    00186                 struct { unsigned long name, arg, suprt; } arg = { name, size, suprt };
    00187 #ifdef SHM_USE_LXRT
    00188                 if ((size = rtai_lxrt(BIDX, SIZARG, SHM_ALLOC, &arg).i[LOW])) {
    00189 #else
    00190                 if ((size = ioctl(hook, SHM_ALLOC, (unsigned long)(&arg)))) {
    00191 #endif
    00192                         if ((adr = mmap(start, size, PROT_WRITE | PROT_READ, MAP_SHARED | MAP_LOCKED, hook, 0)) == (void *)-1) {;
    00193 #ifdef SHM_USE_LXRT
    00194                                 rtai_lxrt(BIDX, sizeof(name), SHM_FREE, &name);
    00195 #else
    00196                                 ioctl(hook, SHM_FREE, &name);
    00197 #endif
    00198                                 adr = 0;
    00199                         }
    00200                         if (isheap) {
    00201                                 arg.arg = (unsigned long)adr;
    00202 #ifdef SHM_USE_LXRT
    00203                                 rtai_lxrt(BIDX, SIZARG, HEAP_SET, &arg);
    00204 #else
    00205                                 ioctl(hook, HEAP_SET, &arg);
    00206 #endif
    00207                         }
    00208                 } else {
    00209                         adr = 0;
    00210                 }
    00211         }
    00212         close(hook);
    00213         return adr;
    00214 }
    00215
    00216 #define rt_shm_alloc(name, size, suprt)  \
    00217         _rt_shm_alloc(0, name, size, suprt, 0)
    00218
    00219 #define rt_heap_open(name, size, suprt)  \
    00220         _rt_shm_alloc(0, name, size, suprt, 1)
    00221
    00243 #define rtai_malloc(name, size)  \
    00244         _rt_shm_alloc(0, name, size, USE_VMALLOC, 0)  // legacy
    00245
    00286 #define rt_shm_alloc_adr(start_address, name, size, suprt)  \
    00287         _rt_shm_alloc(start_address, name, size, suprt, 0)
    00288
    00289 #define rt_heap_open_adr(start, name, size, suprt)  \
    00290         _rt_shm_alloc(start, name, size, suprt, 1)
    00291
    00315 #define rtai_malloc_adr(start_address, name, size)  \
    00316         _rt_shm_alloc(start_address, name, size, USE_VMALLOC, 0)  // legacy
    00317
    00318 static inline int rt_shm_free(unsigned long name)
    00319 {
    00320         int hook, size;
    00321         struct { void *nameadr; } arg = { &name };
    00322         if ((hook = open(RTAI_SHM_DEV, O_RDWR)) <= 0) {
    00323                 return 0;
    00324         }
    00325 // no SHM_FREE needed, we release it all and munmap will do it through
    00326 // the vma close operation provided by shm.c
    00327 #ifdef SHM_USE_LXRT
    00328         if ((size = rtai_lxrt(BIDX, SIZARG, SHM_SIZE, &arg).i[LOW])) {
    00329 #else
    00330         if ((size = ioctl(hook, SHM_SIZE, (unsigned long)&arg))) {
    00331 #endif
    00332                 if (munmap((void *)name, size)) {
    00333                         size = 0;
    00334                 }
    00335         }
    00336         close(hook);
    00337         return size;
    00338 }
    00339
    00359 #define rtai_free(name, adr)  \
    00360         rt_shm_free(name)  // legacy
    00361
    00362 RTAI_PROTO(void *, rt_halloc, (int size))
    00363 {
    00364         struct { int size; } arg = { size };
    00365         return rtai_lxrt(BIDX, SIZARG, HEAP_ALLOC, &arg).v[LOW];
    00366 }
    00367
    00368 RTAI_PROTO(void, rt_hfree, (void *addr))
    00369 {
    00370         struct { void *addr; } arg = { addr };
    00371         rtai_lxrt(BIDX, SIZARG, HEAP_FREE, &arg);
    00372 }
    00373
    00374 RTAI_PROTO(void *, rt_named_halloc, (unsigned long name, int size))
    00375 {
    00376         struct { unsigned long name; int size; } arg = { name, size };
    00377         return rtai_lxrt(BIDX, SIZARG, HEAP_NAMED_ALLOC, &arg).v[LOW];
    00378 }
    00379
    00380 RTAI_PROTO(void, rt_named_hfree, (void *addr))
    00381 {
    00382         struct { void *addr; } arg = { addr };
    00383         rtai_lxrt(BIDX, SIZARG, HEAP_NAMED_FREE, &arg);
    00384 }
    00385
    00386 RTAI_PROTO(void *, rt_malloc, (int size))
    00387 {
    00388         struct { int size; } arg = { size };
    00389         return rtai_lxrt(BIDX, SIZARG, MALLOC, &arg).v[LOW];
    00390 }
    00391
    00392 RTAI_PROTO(void, rt_free, (void *addr))
    00393 {
    00394         struct { void *addr; } arg = { addr };
    00395         rtai_lxrt(BIDX, SIZARG, FREE, &arg);
    00396 }
    00397
    00398 RTAI_PROTO(void *, rt_named_malloc, (unsigned long name, int size))
    00399 {
    00400         struct { unsigned long name; int size; } arg = { name, size };
    00401         return rtai_lxrt(BIDX, SIZARG, NAMED_MALLOC, &arg).v[LOW];
    00402 }
    00403
    00404 RTAI_PROTO(void, rt_named_free, (void *addr))
    00405 {
    00406         struct { void *addr; } arg = { addr };
    00407         rtai_lxrt(BIDX, SIZARG, NAMED_FREE, &arg);
    00408 }
    00409
    00410 #endif /* __KERNEL__ */
    00411
    00433 #define rt_heap_close(name, adr)  rt_shm_free(name)
    00434
    00435 // aliases in use already, different heads different choices
    00436 #define rt_heap_init         rt_heap_open
    00437 #define rt_heap_create       rt_heap_open
    00438 #define rt_heap_acquire      rt_heap_open
    00439 #define rt_heap_init_adr     rt_heap_open_adr
    00440 #define rt_heap_create_adr   rt_heap_open_adr
    00441 #define rt_heap_acquire_adr  rt_heap_open_adr
    00442
    00443 #define rt_heap_delete       rt_heap_close
    00444 #define rt_heap_destroy      rt_heap_close
    00445 #define rt_heap_release      rt_heap_close
    00446
    00447 // these have no aliases, and never will
    00448
    00464 #define rt_global_heap_open()  rt_heap_open(GLOBAL_HEAP_ID, 0, 0)
    00465
    00482 #define rt_global_heap_close()  rt_heap_close(GLOBAL_HEAP_ID, 0)
    00483
    00486 #endif /* !_RTAI_SHM_H */