aboutsummaryrefslogtreecommitdiff
path: root/src/modules/dataman
diff options
context:
space:
mode:
authorLorenz Meier <lm@inf.ethz.ch>2014-05-14 23:42:52 -0700
committerLorenz Meier <lm@inf.ethz.ch>2014-05-14 23:42:52 -0700
commit839373f5aebe462e55533c0e8a0b960de46d4c24 (patch)
treeab67360bab216d0a96909fea38102c34e286cd32 /src/modules/dataman
parent9cd1fa5b51672c4c9eebaea2ccbc6e3ea69c02f0 (diff)
parentcd9a72e391948fbf620c8cb129020ae7ecc9cab3 (diff)
downloadpx4-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
Diffstat (limited to 'src/modules/dataman')
-rw-r--r--src/modules/dataman/dataman.c29
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);