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

📄 heap.c

📁 xenomai 很好的linux实时补丁
💻 C
📖 第 1 页 / 共 2 页
字号:
 * * @brief Allocate a block or return the single segment base. * * This service allocates a block from the heap's internal pool, or * returns the address of the single memory segment in the caller's * address space. Tasks may wait for some requested amount of memory * to become available from local heaps. * * @param heap The descriptor address of the heap to allocate a block * from. * * @param size The requested size in bytes of the block. If the heap * is managed as a single-block area (H_SINGLE), this value can be * either zero, or the same value given to rt_heap_create(). In that * case, the same block covering the entire heap space will always be * returned to all callers of this service. * * @param timeout The number of clock ticks to wait for a block of * sufficient size to be available from a local heap (see * note). Passing TM_INFINITE causes the caller to block indefinitely * until some block is eventually available. Passing TM_NONBLOCK * causes the service to return immediately without waiting if no * block is available on entry. This parameter has no influence if the * heap is managed as a single-block area since the entire heap space * is always available. * * @param blockp A pointer to a memory location which will be written * upon success with the address of the allocated block, or the start * address of the single memory segment. In the former case, the block * should be freed using rt_heap_free(). * * @return 0 is returned upon success. Otherwise: * * - -EINVAL is returned if @a heap is not a heap descriptor, or @a * heap is managed as a single-block area (i.e. H_SINGLE mode) and @a * size is non-zero but does not match the original heap size passed * to rt_heap_create(). * * - -EIDRM is returned if @a heap is a deleted heap descriptor. * * - -ETIMEDOUT is returned if @a timeout is different from * TM_NONBLOCK and no block is available within the specified amount * of time. * * - -EWOULDBLOCK is returned if @a timeout is equal to TM_NONBLOCK * and no block is immediately available on entry. * * - -EINTR is returned if rt_task_unblock() has been called for the * waiting task before any block was available. * * - -EPERM is returned if this service should block but was called * from a context which cannot sleep (e.g. interrupt, non-realtime or * scheduler locked). * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Interrupt service routine *   only if @a timeout is equal to TM_NONBLOCK, or the heap is *   managed as a single-block area. * * - Kernel-based task * - User-space task (switches to primary mode) * * Rescheduling: always unless the request is immediately satisfied or * @a timeout specifies a non-blocking operation. Operations on * single-block heaps never start the rescheduling procedure. * * @note This service is sensitive to the current operation mode of * the system timer, as defined by the rt_timer_start() service. In * periodic mode, clock ticks are interpreted as periodic jiffies. In * oneshot mode, clock ticks are interpreted as nanoseconds. */int rt_heap_alloc (RT_HEAP *heap,		   size_t size,		   RTIME timeout,		   void **blockp){    void *block = NULL;    RT_TASK *task;    int err = 0;    spl_t s;    xnlock_get_irqsave(&nklock,s);    heap = xeno_h2obj_validate(heap,XENO_HEAP_MAGIC,RT_HEAP);    if (!heap)	{	err = -EINVAL;	goto unlock_and_exit;	}    /* In single-block mode, there is only a single allocation       returning the whole addressable heap space to the user. All       users referring to this heap are then returned the same       block. */    if (heap->mode & H_SINGLE)	{	block = heap->sba;	if (!block)	    {	    /* It's ok to pass zero for size here, since the requested	       size is implicitely the whole heap space; but if	       non-zero is given, it must match the original heap	       size. */	    if (size > 0 && size != heap->csize)		{		err = -EINVAL;		goto unlock_and_exit;		}	    block = heap->sba = xnheap_alloc(&heap->heap_base,					     xnheap_max_contiguous(&heap->heap_base));	    }	if (block)	    goto unlock_and_exit;	err = -ENOMEM;	/* This should never happen. Paranoid. */	goto unlock_and_exit;	}    block = xnheap_alloc(&heap->heap_base,size);    if (block)	goto unlock_and_exit;    if (timeout == TM_NONBLOCK)	{	err = -EWOULDBLOCK;	goto unlock_and_exit;	}    if (xnpod_unblockable_p())	{	err = -EPERM;	goto unlock_and_exit;	}    task = xeno_current_task();    task->wait_args.heap.size = size;    task->wait_args.heap.block = NULL;    xnsynch_sleep_on(&heap->synch_base,timeout);    if (xnthread_test_flags(&task->thread_base,XNRMID))	err = -EIDRM; /* Heap deleted while pending. */    else if (xnthread_test_flags(&task->thread_base,XNTIMEO))	err = -ETIMEDOUT; /* Timeout.*/    else if (xnthread_test_flags(&task->thread_base,XNBREAK))	err = -EINTR; /* Unblocked.*/    else	block = task->wait_args.heap.block; unlock_and_exit:    *blockp = block;    xnlock_put_irqrestore(&nklock,s);    return err;}/** * @fn int rt_heap_free(RT_HEAP *heap,void *block) * * @brief Free a block. * * This service releases a block to the heap's internal pool. If some * task is currently waiting for a block so that it's pending request * could be satisfied as a result of the release, it is immediately * resumed. * * If the heap is defined as a single-block area (i.e. H_SINGLE mode), * this service leads to a null-effect and always returns * successfully. * * @param heap The address of the heap descriptor to which the block * @a block belong. * * @param block The address of the block to free. * * @return 0 is returned upon success, or -EINVAL if @a block is not a * valid block previously allocated by the rt_heap_alloc() service. * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Interrupt service routine * - Kernel-based task * - User-space task * * Rescheduling: possible. */int rt_heap_free (RT_HEAP *heap,		  void *block){    int err, nwake;    spl_t s;    if (block == NULL)	return -EINVAL;    xnlock_get_irqsave(&nklock,s);    heap = xeno_h2obj_validate(heap,XENO_HEAP_MAGIC,RT_HEAP);    if (!heap)        {        err = xeno_handle_error(heap,XENO_HEAP_MAGIC,RT_HEAP);        goto unlock_and_exit;        }        if (heap->mode & H_SINGLE)	/* No-op in single-block mode. */	{	err = 0;	goto unlock_and_exit;	}    err = xnheap_free(&heap->heap_base,block);    if (!err && xnsynch_nsleepers(&heap->synch_base) > 0)	{	xnpholder_t *holder, *nholder;		nholder = getheadpq(xnsynch_wait_queue(&heap->synch_base));	nwake = 0;	while ((holder = nholder) != NULL)	    {	    RT_TASK *sleeper = thread2rtask(link2thread(holder,plink));	    void *block;	    block = xnheap_alloc(&heap->heap_base,			       sleeper->wait_args.heap.size);	    if (block)		{		nholder = xnsynch_wakeup_this_sleeper(&heap->synch_base,holder);		sleeper->wait_args.heap.block = block;		nwake++;		}	    else		nholder = nextpq(xnsynch_wait_queue(&heap->synch_base),holder);	    }	if (nwake > 0)	    xnpod_schedule();	} unlock_and_exit:    xnlock_put_irqrestore(&nklock,s);    return err;}/** * @fn int rt_heap_inquire(RT_HEAP *heap, RT_HEAP_INFO *info) * * @brief Inquire about a heap. * * Return various information about the status of a given heap. * * @param heap The descriptor address of the inquired heap. * * @param info The address of a structure the heap information will * be written to. * @return 0 is returned and status information is written to the * structure pointed at by @a info upon success. Otherwise: * * - -EINVAL is returned if @a heap is not a message queue descriptor. * * - -EIDRM is returned if @a heap is a deleted queue descriptor. * * Environments: * * This service can be called from: * * - Kernel module initialization/cleanup code * - Interrupt service routine * - Kernel-based task * - User-space task * * Rescheduling: never. */int rt_heap_inquire (RT_HEAP *heap,		     RT_HEAP_INFO *info){    int err = 0;    spl_t s;    xnlock_get_irqsave(&nklock,s);    heap = xeno_h2obj_validate(heap,XENO_HEAP_MAGIC,RT_HEAP);    if (!heap)        {        err = xeno_handle_error(heap,XENO_HEAP_MAGIC,RT_HEAP);        goto unlock_and_exit;        }        strcpy(info->name,heap->name);    info->nwaiters = xnsynch_nsleepers(&heap->synch_base);    info->heapsize = heap->csize;    info->mode = heap->mode; unlock_and_exit:    xnlock_put_irqrestore(&nklock,s);    return err;}/** * @fn int rt_heap_bind(RT_HEAP *heap,const char *name,RTIME timeout) * * @brief Bind to a mappable heap. * * This user-space only service retrieves the uniform descriptor of a * given mappable Xenomai heap identified by its symbolic name. If the * heap does not exist on entry, this service blocks the caller until * a heap of the given name is created. * * @param name A valid NULL-terminated name which identifies the * heap to bind to. * * @param heap The address of a heap descriptor retrieved by the * operation. Contents of this memory is undefined upon failure. * * @param timeout The number of clock ticks to wait for the * registration to occur (see note). Passing TM_INFINITE causes the * caller to block indefinitely until the object is * registered. Passing TM_NONBLOCK causes the service to return * immediately without waiting if the object is not registered on * entry. * * @return 0 is returned upon success. Otherwise: * * - -EFAULT is returned if @a heap or @a name is referencing invalid * memory. * * - -EINTR is returned if rt_task_unblock() has been called for the * waiting task before the retrieval has completed. * * - -EWOULDBLOCK is returned if @a timeout is equal to TM_NONBLOCK * and the searched object is not registered on entry. * * - -ETIMEDOUT is returned if the object cannot be retrieved within * the specified amount of time. * * - -EPERM is returned if this service should block, but was called * from a context which cannot sleep (e.g. interrupt, non-realtime or * scheduler locked). * * Environments: * * This service can be called from: * * - User-space task (switches to primary mode) * * Rescheduling: always unless the request is immediately satisfied or * @a timeout specifies a non-blocking operation. * * @note This service is sensitive to the current operation mode of * the system timer, as defined by the rt_timer_start() service. In * periodic mode, clock ticks are interpreted as periodic jiffies. In * oneshot mode, clock ticks are interpreted as nanoseconds. *//** * @fn int rt_heap_unbind(RT_HEAP *heap) * * @brief Unbind from a mappable heap. * * This user-space only service unbinds the calling task from the heap * object previously retrieved by a call to rt_heap_bind(). * * Unbinding from a heap when it is no more needed is especially * important in order to properly release the mapping resources used * to attach the heap memory to the caller's address space. * * @param heap The address of a heap descriptor to unbind from. * * @return 0 is always returned. * * This service can be called from: * * - User-space task. * * Rescheduling: never. */int __native_heap_pkg_init (void){    return 0;}void __native_heap_pkg_cleanup (void){}/*@}*/EXPORT_SYMBOL(rt_heap_create);EXPORT_SYMBOL(rt_heap_delete);EXPORT_SYMBOL(rt_heap_alloc);EXPORT_SYMBOL(rt_heap_free);EXPORT_SYMBOL(rt_heap_inquire);

⌨️ 快捷键说明

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