diff options
author | Lorenz Meier <lm@inf.ethz.ch> | 2014-05-14 23:42:52 -0700 |
---|---|---|
committer | Lorenz Meier <lm@inf.ethz.ch> | 2014-05-14 23:42:52 -0700 |
commit | 839373f5aebe462e55533c0e8a0b960de46d4c24 (patch) | |
tree | ab67360bab216d0a96909fea38102c34e286cd32 | |
parent | 9cd1fa5b51672c4c9eebaea2ccbc6e3ea69c02f0 (diff) | |
parent | cd9a72e391948fbf620c8cb129020ae7ecc9cab3 (diff) | |
download | px4-firmware-839373f5aebe462e55533c0e8a0b960de46d4c24.tar.gz px4-firmware-839373f5aebe462e55533c0e8a0b960de46d4c24.tar.bz2 px4-firmware-839373f5aebe462e55533c0e8a0b960de46d4c24.zip |
Merge pull request #938 from jean-m-cyr/master
Reduce potential dataman memory fragmentation
-rw-r--r-- | src/modules/dataman/dataman.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/src/modules/dataman/dataman.c b/src/modules/dataman/dataman.c index 5f3ada0cd..1a65313e8 100644 --- a/src/modules/dataman/dataman.c +++ b/src/modules/dataman/dataman.c @@ -76,7 +76,8 @@ typedef enum { typedef struct { sq_entry_t link; /**< list linkage */ sem_t wait_sem; - dm_function_t func; + unsigned char first; + unsigned char func; ssize_t result; union { struct { @@ -101,6 +102,8 @@ typedef struct { }; } work_q_item_t; +const size_t k_work_item_allocation_chunk_size = 8; + /* Usage statistics */ static unsigned g_func_counts[dm_number_of_funcs]; @@ -178,9 +181,23 @@ create_work_item(void) unlock_queue(&g_free_q); - /* If we there weren't any free items then obtain memory for a new one */ - if (item == NULL) - item = (work_q_item_t *)malloc(sizeof(work_q_item_t)); + /* If we there weren't any free items then obtain memory for a new ones */ + if (item == NULL) { + item = (work_q_item_t *)malloc(k_work_item_allocation_chunk_size * sizeof(work_q_item_t)); + if (item) { + item->first = 1; + lock_queue(&g_free_q); + for (int i = 1; i < k_work_item_allocation_chunk_size; i++) { + (item + i)->first = 0; + sq_addfirst(&(item + i)->link, &(g_free_q.q)); + } + /* Update the queue size and potentially the maximum queue size */ + g_free_q.size += k_work_item_allocation_chunk_size - 1; + if (g_free_q.size > g_free_q.max_size) + g_free_q.max_size = g_free_q.size; + unlock_queue(&g_free_q); + } + } /* If we got one then lock the item*/ if (item) @@ -718,8 +735,8 @@ task_main(int argc, char *argv[]) for (;;) { if ((work = (work_q_item_t *)sq_remfirst(&(g_free_q.q))) == NULL) break; - - free(work); + if (work->first) + free(work); } destroy_q(&g_work_q); |