# Cobalt/Heap management services

专用于实时分配的内存区域。

### 详细描述

专用于实时分配的内存区域。

堆是用于动态内存分配的内存区域，这种分配方式具有时间限制。内存块以任意顺序分配和释放，分配模式和块大小直到运行时才知道。

### 函数文档

#### rt_heap_alloc

> int rt_heap_alloc (RT_HEAP *heap, size_t size, RTIME timeout, void **blockp);

从堆中分配一个块（具有相对标量超时）。

此例程是 rt_heap_alloc_timed() 的一个变体，接受以标量值表示的相对超时规范。在 timeout 中传递 TM_INFINITE 会导致调用者无限期阻塞，直到有可用的块。在 timeout 中传递 TM_NONBLOCK 会导致服务在块不可用的情况下立即返回，而不会阻塞。

标签

`xthread-nowait`, `switch-primary`

示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <alchemy/task.h>
    #include <alchemy/heap.h>

    #define TASK_PRIO 50
    #define TASK_MODE T_JOINABLE
    #define TASK_STKSZ 0

    #define HEAP_SIZE 1024 * 10  // 10KB 堆大小
    #define ALLOC_SIZE 1024      // 要分配的块大小

    RT_HEAP heap_desc;

    void heap_task(void *arg)
    {
        int ret;
        char *block_ptr;
        char test_data[50] = "This is the test data for heap";

        printf("Task: Try to alloc from heap....\n");

        ret = rt_heap_alloc(&heap_desc, ALLOC_SIZE, TM_INFINITE, (void **)&block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_alloc %s\n", strerror(-ret));
            return;
        }

        printf("Task: Success alloc %d bytes from heap，Addr: %p\n", ALLOC_SIZE, block_ptr);

        // 使用分配的内存...
        memcpy(block_ptr,test_data,strlen(test_data));
        printf("Task: %s\n",block_ptr);

        // 释放内存
        ret = rt_heap_free(&heap_desc, block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_free %s\n", strerror(-ret));
        } else {
            printf("Task: released successfully\n");
        }
    }

    int main(int argc, char *argv[])
    {
        RT_TASK task_desc;
        int ret;

        // 创建堆
        ret = rt_heap_create(&heap_desc, "MyHeap", HEAP_SIZE, H_FIFO);
        if (ret) {
            fprintf(stderr, "Main: rt_heap_create %s\n", strerror(-ret));
            return EXIT_FAILURE;
        }

        // 创建任务
        ret = rt_task_create(&task_desc, "HeapTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
        if (ret) {
            fprintf(stderr, "Main: rt_task_create %s\n", strerror(-ret));
            rt_heap_delete(&heap_desc);
            return EXIT_FAILURE;
        }

        // 启动任务
        rt_task_start(&task_desc, &heap_task, NULL);

        // 等待任务完成
        rt_task_join(&task_desc);

        // 清理
        rt_heap_delete(&heap_desc);
        rt_task_delete(&task_desc);

        return EXIT_SUCCESS;
    }

#### rt_heap_alloc_timed

> int rt_heap_alloc_timed (RT_HEAP *heap, size_t size, const struct timespec *abs_timeout, void **blockp);

从堆中分配一个块。

此服务从给定的堆中分配一个块，或者如果在 rt_heap_create() 的创建模式中提到了 H_SINGLE，那么返回单个内存段的地址。当在进入此服务时没有足够的内存可用，任务可能会被阻塞，直到他们的分配请求可以被满足。

参数

- heap 堆描述符。
- size 请求的块的大小（以字节为单位）。如果堆被管理为单块区域（H_SINGLE），这个值可以是零，或者与 rt_heap_create() 给出的值相同。在这种情况下，同一个覆盖整个堆空间的块被返回给此服务的所有调用者。
- abs_timeout 一个以秒/纳秒表示的绝对日期，基于 Alchemy 时钟，指定等待从堆中获取请求大小的块的时间限制。传递 NULL 会导致调用者无限期阻塞，直到有块可用。传递 { .tv_sec = 0, .tv_nsec = 0 } 会导致服务在块不可用的情况下立即返回，而不会阻塞。
- blockp 一个指向内存位置的指针，成功时会写入分配的块的地址，或者单个内存段的起始地址。在前一种情况下，可以使用 rt_heap_free() 释放块。

返回值

成功时返回零。否则：

- 如果在块可用之前达到 abs_timeout，则返回 -ETIMEDOUT。
- 如果 abs_timeout 等于 { .tv_sec = 0, .tv_nsec = 0 } 并且在进入分配请求时没有立即可用的块，则返回 -EWOULDBLOCK。
- 如果在块变得可用之前为当前任务调用了 rt_task_unblock()，则返回 -EINTR。
- 如果 heap 不是有效的堆描述符，或者 heap 被管理为单块区域（即 H_SINGLE 模式）并且 size 非零但不匹配传递给 rt_heap_create() 的原始堆大小，则返回 -EINVAL。
- 如果在调用者等待块时删除了堆，则返回 -EIDRM。在这种情况下，此服务返回时，堆不再有效。
- 如果此服务应阻塞，但未从 xkernel 线程调用，则返回 -EPERM。

标签

`xthread-nowait`, `switch-primary`

注意

如果启用了共享多处理（即，传递了 --enable-pshared 到 configure 脚本），那么请求的块大小大于两倍的分配页面大小的请求将被向上舍入到下一个页面大小。当前的分配页面大小为 512 字节（HOBJ_PAGE_SIZE），这意味着任何大于 1k 的请求都将被向上舍入到下一个 512 字节边界。

示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <alchemy/task.h>
    #include <alchemy/heap.h>

    #define TASK_PRIO 50
    #define TASK_MODE T_JOINABLE
    #define TASK_STKSZ 0

    #define HEAP_SIZE 1024 * 10  // 10KB 堆大小
    #define ALLOC_SIZE 1024      // 要分配的块大小

    RT_HEAP heap_desc;

    void heap_task(void *arg)
    {
        int ret;
        char *block_ptr;
        char test_data[50] = "This is the test data for heap";

        printf("Task: Try to alloc from heap....\n");

        struct timespec ts;
        clock_gettime(CLOCK_MONOTONIC, &ts);
        ts.tv_sec += 2;  // 2 seconds
        ret = rt_heap_alloc_timed(&heap_desc, ALLOC_SIZE, &ts, (void **)&block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_alloc %s\n", strerror(-ret));
            return;
        }

        printf("Task: Success alloc %d bytes from heap，Addr: %p\n", ALLOC_SIZE, block_ptr);

        // 使用分配的内存...
        memcpy(block_ptr,test_data,strlen(test_data));
        printf("Task: %s\n",block_ptr);

        // 释放内存
        ret = rt_heap_free(&heap_desc, block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_free %s\n", strerror(-ret));
        } else {
            printf("Task: released successfully\n");
        }
    }

    int main(int argc, char *argv[])
    {
        RT_TASK task_desc;
        int ret;

        // 创建堆
        ret = rt_heap_create(&heap_desc, "MyHeap", HEAP_SIZE, H_FIFO);
        if (ret) {
            fprintf(stderr, "Main: rt_heap_create %s\n", strerror(-ret));
            return EXIT_FAILURE;
        }

        // 创建任务
        ret = rt_task_create(&task_desc, "HeapTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
        if (ret) {
            fprintf(stderr, "Main: rt_task_create %s\n", strerror(-ret));
            rt_heap_delete(&heap_desc);
            return EXIT_FAILURE;
        }

        // 启动任务
        rt_task_start(&task_desc, &heap_task, NULL);

        // 等待任务完成
        rt_task_join(&task_desc);

        // 清理
        rt_heap_delete(&heap_desc);
        rt_task_delete(&task_desc);

        return EXIT_SUCCESS;
    }

#### rt_heap_alloc_until

> int rt_heap_alloc_until (RT_HEAP *heap, size_t size, RTIME timeout, void **blockp);

从堆中分配一个块（具有绝对标量超时）。

此例程是 rt_heap_alloc_timed() 的一个变体，接受以标量值表示的绝对超时规范。在 timeout 中传递 TM_INFINITE 会导致调用者无限期阻塞，直到有可用的块。在 timeout 中传递 TM_NONBLOCK 会导致服务在块不可用的情况下立即返回，而不会阻塞。

参数

- heap 堆描述符。
- size 请求的块的大小（以字节为单位）。如果堆被管理为单块区域（H_SINGLE），这个值可以是零，或者与 rt_heap_create() 给出的值相同。在这种情况下，同一个覆盖整个堆空间的块被返回给此服务的所有调用者。
- abs_timeout 以时钟滴答表示的绝对日期。传递 TM_INFINITE 可使调用者无限期阻塞。传递 TM_NONBLOCK 可使服务立即返回而不阻塞，以防互斥锁已被其他任务锁定。
- blockp 一个指向内存位置的指针，成功时会写入分配的块的地址，或者单个内存段的起始地址。在前一种情况下，可以使用 rt_heap_free() 释放块。

标签

`xthread-nowait`, `switch-primary`

示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <alchemy/task.h>
    #include <alchemy/heap.h>

    #define TASK_PRIO 50
    #define TASK_MODE T_JOINABLE
    #define TASK_STKSZ 0

    #define HEAP_SIZE 1024 * 10  // 10KB 堆大小
    #define ALLOC_SIZE 1024      // 要分配的块大小

    RT_HEAP heap_desc;

    void heap_task(void *arg)
    {
        int ret;
        char *block_ptr;
        char test_data[50] = "This is the test data for heap";

        printf("Task: Try to alloc from heap....\n");

        RTIME timeout = rt_timer_read() + 2000000000;  // 2 seconds
        ret = rt_heap_alloc_until(&heap_desc, ALLOC_SIZE, timeout, (void **)&block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_alloc %s\n", strerror(-ret));
            return;
        }

        printf("Task: Success alloc %d bytes from heap，Addr: %p\n", ALLOC_SIZE, block_ptr);

        // 使用分配的内存...
        memcpy(block_ptr,test_data,strlen(test_data));
        printf("Task: %s\n",block_ptr);

        // 释放内存
        ret = rt_heap_free(&heap_desc, block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_free %s\n", strerror(-ret));
        } else {
            printf("Task: released successfully\n");
        }
    }

    int main(int argc, char *argv[])
    {
        RT_TASK task_desc;
        int ret;

        // 创建堆
        ret = rt_heap_create(&heap_desc, "MyHeap", HEAP_SIZE, H_FIFO);
        if (ret) {
            fprintf(stderr, "Main: rt_heap_create %s\n", strerror(-ret));
            return EXIT_FAILURE;
        }

        // 创建任务
        ret = rt_task_create(&task_desc, "HeapTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
        if (ret) {
            fprintf(stderr, "Main: rt_task_create %s\n", strerror(-ret));
            rt_heap_delete(&heap_desc);
            return EXIT_FAILURE;
        }

        // 启动任务
        rt_task_start(&task_desc, &heap_task, NULL);

        // 等待任务完成
        rt_task_join(&task_desc);

        // 清理
        rt_heap_delete(&heap_desc);
        rt_task_delete(&task_desc);

        return EXIT_SUCCESS;
    }

#### rt_heap_bind

> int rt_heap_bind (RT_HEAP *heap, const char *name, RTIME timeout);

绑定到一个堆。

此例程创建一个新的描述符来引用由其符号名称标识的现有堆。如果在入口处对象不存在，调用者可能会阻塞，直到创建了给定名称的堆。

参数

- heap 由操作填充的堆描述符的地址。失败时，此内存的内容是未定义的。
- name 一个有效的以 NULL 结尾的名称，用于标识要绑定的堆。此字符串应与传递给 rt_heap_create() 的对象名称参数匹配。
- timeout 等待注册发生的时钟刻度数（见注）。传递 TM_INFINITE 会导致调用者无限期阻塞，直到对象被注册。传递 TM_NONBLOCK 会导致服务在对象在入口处未注册时立即返回，而不等待。

返回值

成功时返回零。否则：

- 如果在检索完成之前为当前任务调用了 rt_task_unblock()，则返回 -EINTR。
- 如果 timeout 等于 TM_NONBLOCK 并且在入口处未注册搜索的对象，则返回 -EWOULDBLOCK。
- 如果无法在指定的时间内检索到对象，则返回 -ETIMEDOUT。
- 如果此服务应阻塞，但未从 xkernel 线程调用，则返回 -EPERM。

标签

`xthread-nowait`, `switch-primary`

注意

超时值被解释为 Alchemy 时钟分辨率的倍数（参见 -alchemy-clock-resolution 选项，默认为 1 纳秒）。

示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <alchemy/task.h>
    #include <alchemy/heap.h>

    #define TASK_PRIO 50
    #define TASK_MODE T_JOINABLE
    #define TASK_STKSZ 0

    #define HEAP_SIZE 1024 * 10  // 10KB 堆大小
    #define ALLOC_SIZE 1024      // 要分配的块大小

    RT_HEAP heap_desc;

    void heap_task(void *arg)
    {
        int ret;
        char *block_ptr;
        char test_data[50] = "This is the test data for heap";
        RT_HEAP heap_task;

        ret = rt_heap_bind(&heap_task,"MyHeap",TM_INFINITE);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_bind %s\n", strerror(-ret));
            return;
        }

        printf("Task: Bind to heap, Try to alloc from heap....\n");

        ret = rt_heap_alloc(&heap_task, ALLOC_SIZE, TM_INFINITE, (void **)&block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_alloc %s\n", strerror(-ret));
            return;
        }

        printf("Task: Success alloc %d bytes from heap，Addr: %p\n", ALLOC_SIZE, block_ptr);

        // 使用分配的内存...
        memcpy(block_ptr,test_data,strlen(test_data));
        printf("Task: %s\n",block_ptr);

        // 释放内存
        ret = rt_heap_free(&heap_task, block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_free %s\n", strerror(-ret));
        } else {
            printf("Task: released successfully\n");
        }

        rt_heap_unbind(&heap_task);
    }

    int main(int argc, char *argv[])
    {
        RT_TASK task_desc;
        int ret;

        // 创建堆
        ret = rt_heap_create(&heap_desc, "MyHeap", HEAP_SIZE, H_FIFO);
        if (ret) {
            fprintf(stderr, "Main: rt_heap_create %s\n", strerror(-ret));
            return EXIT_FAILURE;
        }

        // 创建任务
        ret = rt_task_create(&task_desc, "HeapTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
        if (ret) {
            fprintf(stderr, "Main: rt_task_create %s\n", strerror(-ret));
            rt_heap_delete(&heap_desc);
            return EXIT_FAILURE;
        }

        // 启动任务
        rt_task_start(&task_desc, &heap_task, NULL);

        // 等待任务完成
        rt_task_join(&task_desc);

        // 清理
        rt_heap_delete(&heap_desc);
        rt_task_delete(&task_desc);

        return EXIT_SUCCESS;
    }

#### rt_heap_create

> int rt_heap_create (RT_HEAP *heap, const char *name, size_t heapsize, int mode);

创建一个堆。

此例程创建一个适合时间有界的 RAM 块分配请求的内存堆。当没有足够的内存可用时，任务可能会被阻塞，直到他们的分配请求可以被满足。

默认情况下，堆支持以任意顺序分配多个内存块。然而，通过将 H_SINGLE 标志传递到 mode 参数中，可以请求单块管理，在这种情况下，堆管理的整个内存空间作为一个唯一的块提供。在这种模式下，通过 rt_heap_alloc() 做出的所有分配请求都将返回相同的块地址，指向堆内存的开始。

参数

- heap 一个堆描述符的地址，可以在此调用成功后用于唯一标识创建的对象。
- name 一个代表堆符号名称的 ASCII 字符串。当非 NULL 和非空时，此字符串的副本用于将创建的堆索引到对象注册表中。
- heapsz 内存池的大小（以字节为单位），块将被声明和释放给这个区域。这个区域是不可扩展的，所以这个值必须与可能预期的最高内存压力相兼容。有效范围在 1 字节到 2Gb 之间。
- mode 堆创建模式。以下标志可以被 OR 到这个位掩码中，每个标志都会影响新堆：
  - H_FIFO 使任务在等待可用块时在堆上以 FIFO 顺序挂起。
  - H_PRIO 使任务在等待可用块时在堆上以优先级顺序挂起。
  - H_SINGLE 导致整个堆空间被管理为一个单一的内存块。

返回值

成功时返回零。否则：

- 如果 mode 无效，或者 heapsz 为零或大于 2Gb，则返回 -EINVAL。
- 如果系统无法从主堆获取内存以创建堆，则返回 -ENOMEM。
- 如果名称与已注册的堆冲突，则返回 -EEXIST。
- 如果此服务是从无效的上下文调用的，例如中断或非 xkernel 线程，则返回 -EPERM。

标签

`xthread-only`, `mode-unrestricted`, `switch-secondary`

注意

属于同一 xkernel 会话的多个进程可以共享堆。

示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <alchemy/task.h>
    #include <alchemy/heap.h>

    #define TASK_PRIO 50
    #define TASK_MODE T_JOINABLE
    #define TASK_STKSZ 0

    #define HEAP_SIZE 1024 * 10  // 10KB 堆大小
    #define ALLOC_SIZE 1024      // 要分配的块大小

    RT_HEAP heap_desc;

    void heap_task(void *arg)
    {
        int ret;
        char *block_ptr;
        char test_data[50] = "This is the test data for heap";

        printf("Task: Try to alloc from heap....\n");

        ret = rt_heap_alloc(&heap_desc, ALLOC_SIZE, TM_INFINITE, (void **)&block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_alloc %s\n", strerror(-ret));
            return;
        }

        printf("Task: Success alloc %d bytes from heap，Addr: %p\n", ALLOC_SIZE, block_ptr);

        // 使用分配的内存...
        memcpy(block_ptr,test_data,strlen(test_data));
        printf("Task: %s\n",block_ptr);

        // 释放内存
        ret = rt_heap_free(&heap_desc, block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_free %s\n", strerror(-ret));
        } else {
            printf("Task: released successfully\n");
        }
    }

    int main(int argc, char *argv[])
    {
        RT_TASK task_desc;
        int ret;

        // 创建堆
        ret = rt_heap_create(&heap_desc, "MyHeap", HEAP_SIZE, H_FIFO);
        if (ret) {
            fprintf(stderr, "Main: rt_heap_create %s\n", strerror(-ret));
            return EXIT_FAILURE;
        }

        // 创建任务
        ret = rt_task_create(&task_desc, "HeapTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
        if (ret) {
            fprintf(stderr, "Main: rt_task_create %s\n", strerror(-ret));
            rt_heap_delete(&heap_desc);
            return EXIT_FAILURE;
        }

        // 启动任务
        rt_task_start(&task_desc, &heap_task, NULL);

        // 等待任务完成
        rt_task_join(&task_desc);

        // 清理
        rt_heap_delete(&heap_desc);
        rt_task_delete(&task_desc);

        return EXIT_SUCCESS;
    }

#### rt_heap_delete

> int rt_heap_delete (RT_HEAP *heap);

删除一个堆。

此例程删除由 rt_heap_create() 调用先前创建的堆对象，并释放当前阻塞在其上的所有任务。

参数

- heap 堆描述符。

返回值

成功时返回零。否则：

- 如果 heap 不是有效的堆描述符，则返回 -EINVAL。
- 如果此服务是从异步上下文调用的，则返回 -EPERM。

标签

`mode-unrestricted`, `switch-secondary`

示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <alchemy/task.h>
    #include <alchemy/heap.h>

    #define TASK_PRIO 50
    #define TASK_MODE T_JOINABLE
    #define TASK_STKSZ 0

    #define HEAP_SIZE 1024 * 10  // 10KB 堆大小
    #define ALLOC_SIZE 1024      // 要分配的块大小

    RT_HEAP heap_desc;

    void heap_task(void *arg)
    {
        int ret;
        char *block_ptr;
        char test_data[50] = "This is the test data for heap";

        printf("Task: Try to alloc from heap....\n");

        ret = rt_heap_alloc(&heap_desc, ALLOC_SIZE, TM_INFINITE, (void **)&block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_alloc %s\n", strerror(-ret));
            return;
        }

        printf("Task: Success alloc %d bytes from heap，Addr: %p\n", ALLOC_SIZE, block_ptr);

        // 使用分配的内存...
        memcpy(block_ptr,test_data,strlen(test_data));
        printf("Task: %s\n",block_ptr);

        // 释放内存
        ret = rt_heap_free(&heap_desc, block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_free %s\n", strerror(-ret));
        } else {
            printf("Task: released successfully\n");
        }
    }

    int main(int argc, char *argv[])
    {
        RT_TASK task_desc;
        int ret;

        // 创建堆
        ret = rt_heap_create(&heap_desc, "MyHeap", HEAP_SIZE, H_FIFO);
        if (ret) {
            fprintf(stderr, "Main: rt_heap_create %s\n", strerror(-ret));
            return EXIT_FAILURE;
        }

        // 创建任务
        ret = rt_task_create(&task_desc, "HeapTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
        if (ret) {
            fprintf(stderr, "Main: rt_task_create %s\n", strerror(-ret));
            rt_heap_delete(&heap_desc);
            return EXIT_FAILURE;
        }

        // 启动任务
        rt_task_start(&task_desc, &heap_task, NULL);

        // 等待任务完成
        rt_task_join(&task_desc);

        // 清理
        rt_heap_delete(&heap_desc);
        rt_task_delete(&task_desc);

        return EXIT_SUCCESS;
    }

#### rt_heap_free

> int rt_heap_free (RT_HEAP *heap, void *block);

释放堆中的块。

此服务用于将块释放回其所属的堆。一旦块返回到内存池，将尝试满足所有阻塞在 rt_heap_alloc() 上的任务请求。

参数

- heap: 堆描述符。
- block: 要释放的块的地址。

返回值

成功时返回零。否则：

- 如果 heap 不是有效的堆描述符，或者 block 不是之前由 rt_heap_alloc() 服务从 heap 分配的有效块，则返回 -EINVAL。

标签

`unrestricted`, `switch-primary`

示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <alchemy/task.h>
    #include <alchemy/heap.h>

    #define TASK_PRIO 50
    #define TASK_MODE T_JOINABLE
    #define TASK_STKSZ 0

    #define HEAP_SIZE 1024 * 10  // 10KB 堆大小
    #define ALLOC_SIZE 1024      // 要分配的块大小

    RT_HEAP heap_desc;

    void heap_task(void *arg)
    {
        int ret;
        char *block_ptr;
        char test_data[50] = "This is the test data for heap";

        printf("Task: Try to alloc from heap....\n");

        ret = rt_heap_alloc(&heap_desc, ALLOC_SIZE, TM_INFINITE, (void **)&block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_alloc %s\n", strerror(-ret));
            return;
        }

        printf("Task: Success alloc %d bytes from heap，Addr: %p\n", ALLOC_SIZE, block_ptr);

        // 使用分配的内存...
        memcpy(block_ptr,test_data,strlen(test_data));
        printf("Task: %s\n",block_ptr);

        // 释放内存
        ret = rt_heap_free(&heap_desc, block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_free %s\n", strerror(-ret));
        } else {
            printf("Task: released successfully\n");
        }
    }

    int main(int argc, char *argv[])
    {
        RT_TASK task_desc;
        int ret;

        // 创建堆
        ret = rt_heap_create(&heap_desc, "MyHeap", HEAP_SIZE, H_FIFO);
        if (ret) {
            fprintf(stderr, "Main: rt_heap_create %s\n", strerror(-ret));
            return EXIT_FAILURE;
        }

        // 创建任务
        ret = rt_task_create(&task_desc, "HeapTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
        if (ret) {
            fprintf(stderr, "Main: rt_task_create %s\n", strerror(-ret));
            rt_heap_delete(&heap_desc);
            return EXIT_FAILURE;
        }

        // 启动任务
        rt_task_start(&task_desc, &heap_task, NULL);

        // 等待任务完成
        rt_task_join(&task_desc);

        // 清理
        rt_heap_delete(&heap_desc);
        rt_task_delete(&task_desc);

        return EXIT_SUCCESS;
    }

#### rt_heap_inquire

> int rt_heap_inquire (RT_HEAP *heap, RT_HEAP_INFO *info);

查询堆状态。

此例程返回有关堆的状态信息。

参数

- heap 堆描述符。
- info 一个指向返回缓冲区的指针，用于复制信息。

返回值

成功时返回零。否则：

- 如果 heap 不是有效的堆描述符，则返回 -EINVAL。

标签

`unrestricted`, `switch-primary`

示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <alchemy/task.h>
    #include <alchemy/heap.h>

    #define TASK_PRIO 50
    #define TASK_MODE T_JOINABLE
    #define TASK_STKSZ 0

    #define HEAP_SIZE 1024 * 10  // 10KB 堆大小
    #define ALLOC_SIZE 1024      // 要分配的块大小

    RT_HEAP heap_desc;

    void heap_task(void *arg)
    {
        int ret;
        char *block_ptr;
        char test_data[50] = "This is the test data for heap";
        RT_HEAP_INFO info;

        printf("Task: Try to alloc from heap....\n");

        ret = rt_heap_alloc(&heap_desc, ALLOC_SIZE, TM_INFINITE, (void **)&block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_alloc %s\n", strerror(-ret));
            return;
        }

        printf("Task: Success alloc %d bytes from heap，Addr: %p\n", ALLOC_SIZE, block_ptr);

        // 使用分配的内存...
        memcpy(block_ptr,test_data,strlen(test_data));
        printf("Task: %s\n",block_ptr);

        ret = rt_heap_inquire(&heap_desc,&info);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_inquire %s\n", strerror(-ret));
            return;
        }
        printf("Current heap information:\n");
        printf("[ %s ] mode: %d, size: %d, use : %d, free : %d\n",
        info.name, info.mode, info.heapsize, info.usedmem, info.usablemem - info.usedmem);

        // 释放内存
        ret = rt_heap_free(&heap_desc, block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_free %s\n", strerror(-ret));
        } else {
            printf("Task: released successfully\n");
        }
    }

    int main(int argc, char *argv[])
    {
        RT_TASK task_desc;
        int ret;

        // 创建堆
        ret = rt_heap_create(&heap_desc, "MyHeap", HEAP_SIZE, H_FIFO);
        if (ret) {
            fprintf(stderr, "Main: rt_heap_create %s\n", strerror(-ret));
            return EXIT_FAILURE;
        }

        // 创建任务
        ret = rt_task_create(&task_desc, "HeapTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
        if (ret) {
            fprintf(stderr, "Main: rt_task_create %s\n", strerror(-ret));
            rt_heap_delete(&heap_desc);
            return EXIT_FAILURE;
        }

        // 启动任务
        rt_task_start(&task_desc, &heap_task, NULL);

        // 等待任务完成
        rt_task_join(&task_desc);

        // 清理
        rt_heap_delete(&heap_desc);
        rt_task_delete(&task_desc);

        return EXIT_SUCCESS;
    }

#### rt_heap_unbind

> int rt_heap_unbind (RT_HEAP *heap);

解除堆绑定。

参数

- heap: 堆描述符。

此例程释放之前对堆的绑定。此调用返回后，描述符将不再有效，无法引用该对象。

标签

`thread-unrestricted`

示例代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <alchemy/task.h>
    #include <alchemy/heap.h>

    #define TASK_PRIO 50
    #define TASK_MODE T_JOINABLE
    #define TASK_STKSZ 0

    #define HEAP_SIZE 1024 * 10  // 10KB 堆大小
    #define ALLOC_SIZE 1024      // 要分配的块大小

    RT_HEAP heap_desc;

    void heap_task(void *arg)
    {
        int ret;
        char *block_ptr;
        char test_data[50] = "This is the test data for heap";
        RT_HEAP heap_task;

        ret = rt_heap_bind(&heap_task,"MyHeap",TM_INFINITE);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_bind %s\n", strerror(-ret));
            return;
        }

        printf("Task: Bind to heap, Try to alloc from heap....\n");

        ret = rt_heap_alloc(&heap_task, ALLOC_SIZE, TM_INFINITE, (void **)&block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_alloc %s\n", strerror(-ret));
            return;
        }

        printf("Task: Success alloc %d bytes from heap，Addr: %p\n", ALLOC_SIZE, block_ptr);

        // 使用分配的内存...
        memcpy(block_ptr,test_data,strlen(test_data));
        printf("Task: %s\n",block_ptr);

        // 释放内存
        ret = rt_heap_free(&heap_task, block_ptr);
        if (ret) {
            fprintf(stderr, "Task: rt_heap_free %s\n", strerror(-ret));
        } else {
            printf("Task: released successfully\n");
        }

        rt_heap_unbind(&heap_task);
    }

    int main(int argc, char *argv[])
    {
        RT_TASK task_desc;
        int ret;

        // 创建堆
        ret = rt_heap_create(&heap_desc, "MyHeap", HEAP_SIZE, H_FIFO);
        if (ret) {
            fprintf(stderr, "Main: rt_heap_create %s\n", strerror(-ret));
            return EXIT_FAILURE;
        }

        // 创建任务
        ret = rt_task_create(&task_desc, "HeapTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
        if (ret) {
            fprintf(stderr, "Main: rt_task_create %s\n", strerror(-ret));
            rt_heap_delete(&heap_desc);
            return EXIT_FAILURE;
        }

        // 启动任务
        rt_task_start(&task_desc, &heap_task, NULL);

        // 等待任务完成
        rt_task_join(&task_desc);

        // 清理
        rt_heap_delete(&heap_desc);
        rt_task_delete(&task_desc);

        return EXIT_SUCCESS;
    }