X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=buffer_tree.c;h=9884c2e2ff1b1fc4661bab71b585bede6d2eba6a;hp=4aeb790a6e3c6e8efe9a841e4b12fbe331f360f9;hb=a4f75cecaaee538edb7aae3f0ff19168a1dab59d;hpb=a09516998f148e8892bb8665ffe3dcf58ac7e5c5 diff --git a/buffer_tree.c b/buffer_tree.c index 4aeb790a..9884c2e2 100644 --- a/buffer_tree.c +++ b/buffer_tree.c @@ -1,3 +1,10 @@ +/* + * Copyright (C) 2009-2010 Andre Noll + * + * Licensed under the GPL v2. For licencing details see COPYING. + */ + +/** \file buffer_tree.c Buffer tree and buffer pool implementations. */ #include #include @@ -159,6 +166,35 @@ size_t btr_pool_get_buffer(struct btr_pool *btrp, char **result) return btr_pool_available(btrp); } +/** + * Get references to buffers pointing to free space of the buffer pool area. + * + * \param btrp The buffer pool. + * \param iov The scatter array. + * + * \return Zero if the buffer pool is full, one if the free space of the buffer + * pool area is available as a single contiguous buffer, two if the free space + * consists of two buffers. If this function returns the value n, then n + * elements of \a iov are initialized. + */ +int btr_pool_get_buffers(struct btr_pool *btrp, struct iovec iov[2]) +{ + size_t sz, unused; + char *buf; + + sz = btr_pool_get_buffer(btrp, &buf); + if (sz == 0) + return 0; + iov[0].iov_len = sz; + iov[0].iov_base = buf; + unused = btr_pool_unused(btrp); + if (sz == unused) + return 1; + iov[1].iov_len = unused - sz; + iov[1].iov_base = btrp->area_start; + return 2; +} + /** * Mark a part of the buffer pool area as allocated. * @@ -727,12 +763,15 @@ void btr_splice_out_node(struct btr_node *btrn) assert(list_empty(&btrn->children)); } -/* - * Return the size of the largest input queue. +/** + * Return number of queued output bytes of a buffer tree node. + * + * \param btrn The node whose output queue size should be computed. * - * Iterates over all children of the given node. + * This function iterates over all children of the given node and returns the + * size of the largest input queue. */ -static size_t btr_bytes_pending(struct btr_node *btrn) +size_t btr_get_output_queue_size(struct btr_node *btrn) { size_t max_size = 0; struct btr_node *ch; @@ -822,7 +861,7 @@ static void merge_input_pool(struct btr_node *btrn, size_t dest_size) struct btr_buffer_reference *br, *wbr = NULL; int num_refs; /* including wrap buffer */ char *buf, *buf1 = NULL, *buf2 = NULL; - size_t sz, sz1 = 0, sz2 = 0, wsz; + size_t sz, sz1 = 0, sz2 = 0, wb_consumed = 0; br = get_first_input_br(btrn); if (!br || br_available_bytes(br) >= dest_size) @@ -839,6 +878,7 @@ static void merge_input_pool(struct btr_node *btrn, size_t dest_size) wbr = br; if (sz >= dest_size) return; + wb_consumed = br->consumed; continue; } if (!buf1) { @@ -858,7 +898,7 @@ static void merge_input_pool(struct btr_node *btrn, size_t dest_size) assert(buf2 + sz2 == buf); sz2 += sz; next: - if (sz1 + sz2 >= dest_size) + if (sz1 + sz2 >= dest_size + wb_consumed) break; } if (!buf2) /* nothing to do */ @@ -890,7 +930,6 @@ next: * We already have a wrap buffer, but it is too small. It might be * partially used. */ - wsz = br_available_bytes(wbr); if (wbr->wrap_count == sz1 && wbr->btrb->size >= sz1 + sz2) /* nothing we can do about it */ return; sz = sz1 + sz2 - wbr->btrb->size; /* amount of new data */ @@ -1074,7 +1113,7 @@ int btr_node_status(struct btr_node *btrn, size_t min_iqs, if (type != BTR_NT_LEAF) { if (btr_no_children(btrn)) return -E_BTR_NO_CHILD; - if (btr_bytes_pending(btrn) > BTRN_MAX_PENDING) + if (btr_get_output_queue_size(btrn) > BTRN_MAX_PENDING) return 0; } if (type != BTR_NT_ROOT) {