⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shm.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 2 页
字号:
 * */void *rt_named_malloc(unsigned long name, int size){	void *mem_ptr;	if ((mem_ptr = rt_get_adr_cnt(name))) {		return mem_ptr;	}	if ((mem_ptr = _rt_halloc(size, &rt_smp_linux_task->heap[GLOBAL]))) {		if (rt_register(name, mem_ptr, IS_HPCK, 0)) {                        return mem_ptr;                }                rt_hfree(mem_ptr);	}	return NULL;}/** * Free a named chunk of the global real time heap.  * * @internal *  * rt_named_free is used to free a previously allocated chunk of the global * real time heap. * * @param addr is the addr of the memory to be freed. * * Analogously to what done by all the named allocation functions the freeing  * calls of named memory chunks have just the effect of decrementing its usage * count, any shared piece of the global heap being freed only when the last  * is done, as that is the one the really frees any allocated memory. * So one must be carefull not to use rt_free on a named global heap chunk,  * since it will force its unconditional immediate freeing. * */void rt_named_free(void *adr){	unsigned long name;	name = rt_get_name(adr);	if (!rt_drg_on_name_cnt(name)) {		_rt_hfree(adr, &rt_smp_linux_task->heap[GLOBAL]);	}}/*  * we must care of this because LXRT callable functions are set as non  * blocking, so they are called directly. */#define RTAI_TASK(return_instr) \do { \	if (!(task = _rt_whoami())->is_hard) { \		if (!(task = current->this_rt_task[0])) { \			return_instr; \		} \	} \} while (0)static inline void *rt_halloc_typed(int size, int htype){	RT_TASK *task;	RTAI_TASK(return NULL);	return _rt_halloc(size, &task->heap[htype]);}static inline void rt_hfree_typed(void *addr, int htype){	RT_TASK *task;	RTAI_TASK(return);	_rt_hfree(addr, &task->heap[htype]);}static inline void *rt_named_halloc_typed(unsigned long name, int size, int htype){	RT_TASK *task;	void *mem_ptr;	RTAI_TASK(return NULL);	if ((mem_ptr = rt_get_adr_cnt(name))) {		return task->heap[htype].huadr + (mem_ptr - task->heap[htype].hkadr);	}	if ((mem_ptr = _rt_halloc(size, &task->heap[htype]))) {		if (rt_register(name, task->heap[htype].hkadr + (mem_ptr - task->heap[htype].huadr), IS_HPCK, 0)) {                        return mem_ptr;                }		_rt_hfree(mem_ptr, &task->heap[htype]);	}	return NULL;}static inline void rt_named_hfree_typed(void *adr, int htype){	RT_TASK *task;	unsigned long name;	RTAI_TASK(return);	name = rt_get_name(task->heap[htype].hkadr + (adr - task->heap[htype].huadr));	if (!rt_drg_on_name_cnt(name)) {		_rt_hfree(adr, &task->heap[htype]);	}}/** * Allocate a chunk of a group real time heap in kernel/user space. Since  * it is not named there is no chance to retrieve and share it elsewhere. * * @internal *  * rt_halloc is used to allocate a non sharable piece of a group real time  * heap. * * @param size is the size of the requested memory in bytes; * * A process/task must have opened the real time group heap to use and can use * just one real time group heap. Be careful and avoid opening more than one  * group real time heap per process/task. If more than one is opened then just  * the last will used. * * @returns the pointer to the allocated memory, 0 on failure. * */void *rt_halloc(int size){	return rt_halloc_typed(size, SPECIFIC);}/** * Free a chunk of a group real time heap. * * @internal *  * rt_hfree is used to free a previously allocated chunck of a group real  * time heap. * * @param addr is the addr of the memory to be freed. * */void rt_hfree(void *adr){	rt_hfree_typed(adr, SPECIFIC);}/** * Allocate a chunk of a group real time heap in kernel/user space. Since  * it is named it can be retrieved and shared everywhere among the group  * peers, i.e all processes/tasks that have opened the same group heap. * * @internal *  * rt_named_halloc is used to allocate a sharable piece of a group real  * time heap. * * @param name is an unsigned long identifier; *  * @param size is the amount of required shared memory; *  * Since @a name can be a clumsy identifier, services are provided to * convert 6 characters identifiers to unsigned long, and vice versa. *  * @see nam2num() and num2nam(). *  * A process/task must have opened the real time group heap to use and can use * just one real time group heap. Be careful and avoid opening more than one * group real time heap per process/task. If more than one is opened then just * the last will used. It must be remarked that only the very first call does  * a real allocation, any subsequent call with the same name will just  * increase the usage count and receive the appropriate pointer to the already * allocated memory having the same name. * * @returns a valid address on succes, 0 on failure. * */void *rt_named_halloc(unsigned long name, int size){	return rt_named_halloc_typed(name, size, SPECIFIC);}/** * Free a chunk of a group real time heap.  * * @internal *  * rt_named_hfree is used to free a previously allocated chunk of the global * real time heap. * * @param addr is the addr of the memory to be freed. * * Analogously to what done by all the named allocation functions the freeing  * calls of named memory chunks have just the effect of decrementing a usage * count, any shared piece of the global heap being freed only when the last  * is done, as that is the one the really frees any allocated memory. * So one must be carefull not to use rt_hfree on a named global heap chunk,  * since it will force its unconditional immediate freeing. * */void rt_named_hfree(void *adr){	rt_named_hfree_typed(adr, SPECIFIC);}static void *rt_malloc_new_usp(int size){	return rt_halloc_typed(size, GLOBAL);}static void rt_free_new_usp(void *adr){	rt_hfree_typed(adr, GLOBAL);}static void *rt_named_malloc_usp(unsigned long name, int size){	return rt_named_halloc_typed(name, size, GLOBAL);}static void rt_named_free_usp(void *adr){	rt_named_hfree_typed(adr, GLOBAL);}static void rt_set_heap(unsigned long name, void *adr){	int size, htype;	void *hptr;	RT_TASK *task;	hptr = ALIGN2PAGE(rt_get_adr(name));	size = ((abs(rt_get_type(name)) - sizeof(rtheap_t) - 1) & PAGE_MASK);	if (!atomic_cmpxchg((int *)hptr, 0, name)) {		rtheap_init(hptr + size, hptr, size, PAGE_SIZE);		if (name == GLOBAL_HEAP_ID) {			rt_smp_linux_task->heap[GLOBAL].hkadr = (void *)hptr;			rt_smp_linux_task->heap[GLOBAL].huadr = adr;			rt_smp_linux_task->heap[GLOBAL].hsize = size;		}	}	RTAI_TASK(return);	htype = name == GLOBAL_HEAP_ID ? GLOBAL : SPECIFIC;	task->heap[htype].hkadr = (void *)hptr;	task->heap[htype].huadr = adr;	task->heap[htype].hsize = size;}/** * Open/create a named group real time heap to be shared inter-intra kernel  * modules and Linux processes. * * @internal *  * rt_heap_open is used to allocate open/create a shared real time heap. *  * @param name is an unsigned long identifier; *  * @param size is the amount of required shared memory; *  * @param suprt is the kernel allocation method to be used, it can be: * - USE_VMALLOC, use vmalloc; * - USE_GFP_KERNEL, use kmalloc with GFP_KERNEL; * - USE_GFP_ATOMIC, use kmalloc with GFP_ATOMIC; * - USE_GFP_DMA, use kmalloc with GFP_DMA. * * Since @a name can be a clumsy identifier, services are provided to * convert 6 characters identifiers to unsigned long, and vice versa. *  * @see nam2num() and num2nam(). *  * It must be remarked that only the very first open does a real allocation,  * any subsequent one with the same name from anywhere will just map the area  * to the user space, or return the related pointer to the already allocated  * memory in kernel space. In any case the functions return a pointer to the  * allocated memory, appropriately mapped to the memory space in use. * Be careful and avoid opening more than one group heap per process/task, if  * more than one is opened then just the last will used. * * @returns a valid address on succes, 0 on failure. * */void *rt_heap_open(unsigned long name, int size, int suprt){	void *adr;	if ((adr = rt_shm_alloc(name, ((size - 1) & PAGE_MASK) + PAGE_SIZE + sizeof(rtheap_t), suprt))) {		rt_set_heap(name, adr);		return adr;	}	return 0;}struct rt_native_fun_entry rt_shm_entries[] = {        { { 0, rt_shm_alloc_usp },		SHM_ALLOC },        { { 0, rt_shm_free },			SHM_FREE },        { { 0, rt_shm_size },			SHM_SIZE },        { { 0, rt_set_heap },			HEAP_SET},        { { 0, rt_halloc },			HEAP_ALLOC },        { { 0, rt_hfree },			HEAP_FREE },        { { 0, rt_named_halloc },		HEAP_NAMED_ALLOC },        { { 0, rt_named_hfree },		HEAP_NAMED_FREE },        { { 0, rt_malloc_new_usp },		MALLOC },        { { 0, rt_free_new_usp },		FREE },        { { 0, rt_named_malloc_usp },		NAMED_MALLOC },        { { 0, rt_named_free_usp },		NAMED_FREE },        { { 0, 0 },				000 }};extern int set_rt_fun_entries(struct rt_native_fun_entry *entry);extern void reset_rt_fun_entries(struct rt_native_fun_entry *entry);#define GLOBAL_HEAP_SIZE  PAGE_SIZE*31;  // just to have something at the momentstatic int GlobalHeapSize = GLOBAL_HEAP_SIZE;MODULE_PARM(GlobalHeapSize, "i");static void *global_heap;int __rtai_shm_init (void){	if (misc_register(&rtai_shm_dev) < 0) {		printk("***** UNABLE TO REGISTER THE SHARED MEMORY DEVICE (miscdev minor: %d) *****\n", RTAI_SHM_MISC_MINOR);		return -EBUSY;	}	if (!(global_heap = rt_heap_open(GLOBAL_HEAP_ID, GlobalHeapSize, #ifdef CONFIG_RTAI_MALLOC_VMALLOCUSE_VMALLOC#else USE_GFP_KERNEL#endif))) {		misc_deregister(&rtai_shm_dev);		printk("***** UNABLE TO CREATE THE GLOBAL REAL TIME HEAP (size: %d) *****\n", GlobalHeapSize);		return -ENOMEM;	}	return set_rt_fun_entries(rt_shm_entries);}void __rtai_shm_exit (void){        int slot;        struct rt_registry_entry_struct entry;	rt_heap_close(GLOBAL_HEAP_ID, global_heap);	for (slot = 1; slot <= MAX_SLOTS; slot++) {		if (rt_get_registry_slot(slot, &entry) && entry.adr) {			if (abs(entry.type) >= PAGE_SIZE) {        			char name[8];				while (_rt_shm_free(entry.name, entry.type));                        	num2nam(entry.name, name);	                        rt_printk("\nSHM_CLEANUP_MODULE releases: '%s':0x%lx:%lu (%d).\n", name, entry.name, entry.name, entry.type);                        }		}	}	reset_rt_fun_entries(rt_shm_entries);	misc_deregister(&rtai_shm_dev);	return;}/*@}*/#ifndef CONFIG_RTAI_SHM_BUILTINmodule_init(__rtai_shm_init);module_exit(__rtai_shm_exit);#endif /* !CONFIG_RTAI_SHL_BUILTIN */#ifdef CONFIG_KBUILDEXPORT_SYMBOL(rt_shm_alloc);EXPORT_SYMBOL(rt_shm_free);EXPORT_SYMBOL(rt_malloc_new);EXPORT_SYMBOL(rt_free_new);EXPORT_SYMBOL(rt_named_malloc);EXPORT_SYMBOL(rt_named_free);EXPORT_SYMBOL(rt_halloc);EXPORT_SYMBOL(rt_hfree);EXPORT_SYMBOL(rt_named_halloc);EXPORT_SYMBOL(rt_named_hfree);EXPORT_SYMBOL(rt_heap_open);#endif /* CONFIG_KBUILD */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -