diff options
author | Alex Vainman <alexonlists@gmail.com> | 2010-02-01 07:58:04 +0200 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2010-03-19 11:04:10 -0700 |
commit | c2fa381cf71148f01b4958f3e46650f55effa763 (patch) | |
tree | f286412335ce77b85406204e5dee607593526218 | |
parent | 825a14116ccacaabc649745329e0b8b412cfbb08 (diff) | |
download | libibverbs-c2fa381cf71148f01b4958f3e46650f55effa763.tar.gz |
Factor out range handling in ibv_madvise_range()
Clean up some code in ibv_madvise_range() by adding functions
merge_ranges(), split_range() and get_start_node().
Signed-off-by: Alex Vainman <alexv@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | src/memory.c | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/src/memory.c b/src/memory.c index 53d86b7..51839e2 100644 --- a/src/memory.c +++ b/src/memory.c @@ -446,6 +446,49 @@ static struct ibv_mem_node *__mm_find_start(uintptr_t start, uintptr_t end) return node; } +static struct ibv_mem_node *merge_ranges(struct ibv_mem_node *node, + struct ibv_mem_node *prev) +{ + prev->end = node->end; + prev->refcnt = node->refcnt; + __mm_remove(node); + + return prev; +} + +static struct ibv_mem_node *split_range(struct ibv_mem_node *node, + uintptr_t cut_line) +{ + struct ibv_mem_node *new_node = NULL; + + new_node = malloc(sizeof *new_node); + if (!new_node) + return NULL; + new_node->start = cut_line; + new_node->end = node->end; + new_node->refcnt = node->refcnt; + node->end = cut_line - 1; + __mm_add(new_node); + + return new_node; +} + +static struct ibv_mem_node *get_start_node(uintptr_t start, uintptr_t end, + int inc) +{ + struct ibv_mem_node *node, *tmp = NULL; + + node = __mm_find_start(start, end); + if (node->start < start) + node = split_range(node, start); + else { + tmp = __mm_prev(node); + if (tmp && tmp->refcnt == node->refcnt + inc) + node = merge_ranges(node, tmp); + } + return node; +} + static int ibv_madvise_range(void *base, size_t size, int advice) { uintptr_t start, end; @@ -464,46 +507,18 @@ static int ibv_madvise_range(void *base, size_t size, int advice) pthread_mutex_lock(&mm_mutex); - node = __mm_find_start(start, end); - - if (node->start < start) { - tmp = malloc(sizeof *tmp); - if (!tmp) { - ret = -1; - goto out; - } - - tmp->start = start; - tmp->end = node->end; - tmp->refcnt = node->refcnt; - node->end = start - 1; - - __mm_add(tmp); - node = tmp; - } else { - tmp = __mm_prev(node); - if (tmp && tmp->refcnt == node->refcnt + inc) { - tmp->end = node->end; - tmp->refcnt = node->refcnt; - __mm_remove(node); - node = tmp; - } + node = get_start_node(start, end, inc); + if (!node) { + ret = -1; + goto out; } while (node && node->start <= end) { if (node->end > end) { - tmp = malloc(sizeof *tmp); - if (!tmp) { + if (!split_range(node, end + 1)) { ret = -1; goto out; } - - tmp->start = end + 1; - tmp->end = node->end; - tmp->refcnt = node->refcnt; - node->end = end; - - __mm_add(tmp); } node->refcnt += inc; @@ -537,10 +552,8 @@ static int ibv_madvise_range(void *base, size_t size, int advice) if (node) { tmp = __mm_prev(node); - if (tmp && node->refcnt == tmp->refcnt) { - tmp->end = node->end; - __mm_remove(node); - } + if (tmp && node->refcnt == tmp->refcnt) + node = merge_ranges(node, tmp); } out: |