[Pvfs2-cvs] commit by slang in pvfs2/src/common/misc: pint-segpool.c pint-segpool.h module.mk.in

CVS commit program cvs at parl.clemson.edu
Mon Apr 6 17:47:37 EDT 2009


Update of /projects/cvsroot/pvfs2/src/common/misc
In directory parlweb1:/tmp/cvs-serv7881/src/common/misc

Modified Files:
      Tag: sa-branch
	module.mk.in 
Added Files:
      Tag: sa-branch
	pint-segpool.c pint-segpool.h 
Log Message:
added segment pool interface.


--- /dev/null	2004-06-24 14:04:38.000000000 -0400
+++ pint-segpool.c	2009-04-06 17:47:37.000000000 -0400
@@ -0,0 +1,344 @@
+
+#include "quicklist.h"
+#include "pint-request.h"
+#include "pint-segpool.h"
+#include "gen-locks.h"
+#include "id-generator.h"
+#include <assert.h>
+
+struct PINT_sp_segments
+{
+    PVFS_offset *offsets;
+    PVFS_size *sizes;
+    int count;
+    struct qlist_head link;
+};
+
+struct PINT_segpool_handle
+{
+    PINT_Request_state *file_req_state;
+    PINT_Request_state *mem_req_state;
+    PINT_request_file_data filedata;
+    enum PINT_segpool_type type;
+    struct qlist_head segments_list;
+    gen_mutex_t mutex;
+};
+
+int PINT_segpool_init(
+    PVFS_Request mem_request,
+    PVFS_Request file_request,
+    PVFS_size file_size,
+    uint32_t server_number,
+    uint32_t server_count,
+    PINT_dist *dist,
+    enum PINT_segpool_type type,
+    PINT_segpool_handle_t *h)
+{
+    struct PINT_segpool_handle *handle;
+
+    handle = malloc(sizeof(*handle));
+    if(!handle)
+    {
+        return -PVFS_ENOMEM;
+    }
+
+    handle->file_req_state = PINT_new_request_state(file_request);
+    handle->mem_req_state = PINT_new_request_state(mem_request);
+    handle->filedata.fsize = file_size;
+    handle->filedata.dist = dist;
+    handle->filedata.server_nr = server_number;
+    handle->filedata.server_ct = server_count;
+    handle->type = type;
+
+    INIT_QLIST_HEAD(&handle->segments_list);
+
+    gen_mutex_init(&handle->mutex);
+
+    *h = handle;
+    return 0;
+}
+
+int PINT_segpool_destroy(PINT_segpool_handle_t h)
+{
+    struct PINT_sp_segments *segments;
+    struct PINT_sp_segments *tmp;
+
+    gen_mutex_lock(&h->mutex);
+    PINT_free_request_states(h->file_req_state);
+    PINT_free_request_states(h->mem_req_state);
+
+    qlist_for_each_entry_safe(segments, tmp, &h->segments_list, link)
+    {
+        if(segments->count > 0)
+        {
+            free(segments->offsets);
+            free(segments->sizes);
+        }
+        qlist_del(&segments->link);
+        free(segments);
+    }
+
+    gen_mutex_unlock(&h->mutex);
+    gen_mutex_destroy(&h->mutex);
+    free(h);
+
+    return 0;
+}
+
+int PINT_segpool_register(PINT_segpool_handle_t h,
+                          PINT_segpool_unit_id *id)
+{
+    struct PINT_sp_segments *segments;
+
+    segments = malloc(sizeof(*segments));
+    if(!segments)
+    {
+        return -PVFS_ENOMEM;
+    }
+
+    segments->offsets = NULL;
+    segments->sizes = NULL;
+    segments->count = 0;
+    qlist_add(&segments->link, &h->segments_list);
+    id_gen_fast_register((PVFS_id_gen_t *)id, segments);
+    return 0;
+}
+
+/**
+ * Takes the handle and requester id as inputs.  The bytes
+ * field is an inout parameter.  As input, it should dereference
+ * to the max bytes that can be summed for the returned segments,
+ * and as output, it dereferences to the total bytes of all the
+ * segments returned.
+ * The count parameter is an out parameter, dereferencing to the
+ * number of segments returned.
+ * The offsets and sizes are output arrays * the size of *count.
+ *
+ * The offsets and sizes do not need to be freed after each call
+ * to PINT_segpool_take_segments.
+ */
+int PINT_segpool_take_segments(PINT_segpool_handle_t h,
+                               PINT_segpool_unit_id id,
+                               PVFS_size *bytes,
+                               int *count,
+                               PVFS_offset **offsets,
+                               PVFS_size **sizes)
+{
+    struct PINT_sp_segments *segments;
+    PINT_Request_result result;
+    int type;
+    int ret;
+
+    segments = id_gen_fast_lookup(id);
+
+    result.bytemax = *bytes;
+    result.segs = 0;
+    result.bytes = 0;
+
+    gen_mutex_lock(&h->mutex);
+
+    if(PINT_REQUEST_DONE(h->file_req_state))
+    {
+        *bytes = 0;
+        *count = 0;
+        *offsets = NULL;
+        *sizes = NULL;
+        gen_mutex_unlock(&h->mutex);
+        return 0;
+    }
+
+    if(segments->count == 0)
+    {
+        /* first time we need to allocate offset and size arrays */
+        result.segmax = 1;
+        result.offset_array = NULL;
+        result.size_array = NULL;
+        ret = PINT_process_request(h->file_req_state,
+                                   h->mem_req_state,
+                                   &h->filedata,
+                                   &result,
+                                   PINT_CKSIZE);
+        if(ret != 0)
+        {
+            goto done;
+        }
+
+        if(result.segs == 0)
+        {
+            *bytes = 0;
+            *count = 0;
+            *offsets = NULL;
+            *sizes = NULL;
+            goto done;
+        }
+
+        segments->count = result.segs;
+        segments->offsets = realloc(
+            segments->offsets, sizeof(PVFS_offset)*result.segs);
+        if(!segments->offsets)
+        {
+            gen_mutex_unlock(&h->mutex);
+            return -PVFS_ENOMEM;
+        }
+        segments->sizes = realloc(
+            segments->sizes, sizeof(PVFS_size)*result.segs);
+        if(!segments->sizes)
+        {
+            free(segments->offsets);
+            gen_mutex_unlock(&h->mutex);
+            return -PVFS_ENOMEM;
+        }
+
+        result.segs = 0;
+        result.bytes = 0;
+    }
+
+    result.segmax = segments->count;
+    result.offset_array = segments->offsets;
+    result.size_array = segments->sizes;
+
+    if(h->type == PINT_SP_SERVER_WRITE || h->type == PINT_SP_SERVER_READ)
+    {
+        type = PINT_SERVER;
+    }
+    else
+    {
+        type = PINT_CLIENT;
+    }
+
+    ret = PINT_process_request(h->file_req_state,
+                               h->mem_req_state,
+                               &h->filedata,
+                               &result,
+                               type);
+    if(ret != 0)
+    {
+        goto done;
+    }
+
+    /* what if there were more segments this time than last time?
+     * realloc the offset and sizes arrays if so
+     */
+    if(!PINT_REQUEST_DONE(h->file_req_state) && result.bytes < result.bytemax)
+    {
+        int prev_segment_count = result.segs;
+        assert(result.segmax == result.segs);
+
+        result.bytemax = result.bytemax - result.bytes;
+        result.segmax = 1;
+        result.segs = 0;
+        result.bytes = 0;
+        ret = PINT_process_request(h->file_req_state,
+                                   h->mem_req_state,
+                                   &h->filedata,
+                                   &result,
+                                   PINT_CKSIZE);
+        if(ret != 0)
+        {
+            goto done;
+        }
+
+        segments->count += result.segs;
+        segments->offsets = realloc(
+            segments->offsets, sizeof(PVFS_offset)*segments->count);
+        segments->sizes = realloc(
+            segments->sizes, sizeof(PVFS_size)*segments->count);
+        result.offset_array = segments->offsets + prev_segment_count;
+        result.size_array = segments->sizes + prev_segment_count;
+        result.segmax = result.segs;
+        result.segs = 0;
+        result.bytes = 0;
+
+        ret = PINT_process_request(h->file_req_state,
+                                   h->mem_req_state,
+                                   &h->filedata,
+                                   &result,
+                                   type);
+        if(ret != 0)
+        {
+            goto done;
+        }
+
+    }
+
+    *bytes = result.bytes;
+    *count = result.segs;
+    *offsets = result.offset_array;
+    *sizes = result.size_array;
+
+done:
+    gen_mutex_unlock(&h->mutex);
+    return ret;
+}
+
+
+#include "pint-dist-utils.h"
+
+/**
+ * Testing code for the above.  This tests:
+ *
+ */
+int main(int argc, char *argv[])
+{
+    PINT_segpool_handle_t handle;
+    PINT_segpool_unit_id id[3];
+    PVFS_size bytes[3];
+    int count[3];
+    PVFS_offset *offsets[3];
+    PVFS_size *sizes[3];
+
+    PVFS_Request mem_req, file_req;
+
+    PINT_dist_initialize(NULL);
+
+    PINT_dist *dist = PINT_dist_create("simple_stripe");
+    PINT_dist_lookup(dist);
+
+    PVFS_Request_vector(1000, 1024, 6, PVFS_DOUBLE, &mem_req);
+    PVFS_Request_vector(2000, 512, 6, PVFS_DOUBLE, &file_req);
+
+    PINT_segpool_init(mem_req,
+                      file_req,
+                      1024*1024*8,
+                      1,
+                      123,
+                      dist,
+                      PINT_SP_SERVER_READ,
+                      &handle);
+
+    PINT_segpool_register(handle, &id[0]);
+    PINT_segpool_register(handle, &id[1]);
+    PINT_segpool_register(handle, &id[2]);
+
+    bytes[0] = 1024*6;
+    bytes[1] = 1024*6;
+    bytes[2] = 1024*6;
+
+    while(1)
+    {
+        PINT_segpool_take_segments(handle, id[0], &(bytes[0]), &(count[0]),
+                                   &(offsets[0]), &(sizes[0]));
+        if(count[0] == 0) break;
+
+
+        PINT_segpool_take_segments(handle, id[1], &(bytes[1]), &(count[1]),
+                                   &(offsets[1]), &(sizes[1]));
+        if(count[1] == 0) break;
+
+        PINT_segpool_take_segments(handle, id[2], &(bytes[2]), &(count[2]),
+                                   &(offsets[2]), &(sizes[2]));
+        if(count[2] == 0) break;
+    }
+
+    return 0;
+}
+
+/*
+ * Local variables:
+ *  mode: c
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ *
+ * vim: ft=c ts=4 sts=4 sw=4 expandtab
+ */

--- /dev/null	2004-06-24 14:04:38.000000000 -0400
+++ pint-segpool.h	2009-04-06 17:47:37.000000000 -0400
@@ -0,0 +1,60 @@
+#ifndef __PINT_SEGPOOL_H__
+#define __PINT_SEGPOOL_H__
+
+#include "pvfs2-types.h"
+#include "pvfs2-request.h"
+#include "pint-distribution.h"
+
+/* The segment pool interface is used for pipelining, where
+ * multiple calls to get segments from the same request are made.
+ *
+ * The basic use of the interface is as follows.  Given a memory and file request,
+ * PINT_segpool_handle_init is called to initialize the segment pool handle.
+ * This call is made once for a given memory and file request.
+ *
+ * Component elements (each pipelining unit) then calls PINT_segpool_register
+ * to register its intent to take segments from the pool.  This is needed to
+ * get a unique unit id that can be passed to PINT_segpool_take_segments to
+ * identify which unit is taking segments.
+ *
+ * Different pipelining elements then call PINT_segpool_take_segments as necessary
+ * using the offset and size arrays returned.  The offset and size arrays returned
+ * are valid until the same pipelining unit calls PINT_segpool_take_segments again,
+ * or PINT_segpool_destroy is called.
+ *
+ * Finally a call to PINT_segpool_destroy is called to cleanup.
+ */
+
+enum PINT_segpool_type
+{
+    PINT_SP_SERVER_READ = 1,
+    PINT_SP_SERVER_WRITE,
+    PINT_SP_CLIENT_READ,
+    PINT_SP_CLIENT_WRITE
+};
+
+typedef struct PINT_segpool_handle *PINT_segpool_handle_t;
+typedef PVFS_id_gen_t PINT_segpool_unit_id;
+
+int PINT_segpool_init(PVFS_Request mem_request,
+                      PVFS_Request file_request,
+                      PVFS_size file_size,
+                      uint32_t server_number,
+                      uint32_t server_count,
+                      PINT_dist *dist,
+                      enum PINT_segpool_type type,
+                      PINT_segpool_handle_t *h);
+
+int PINT_segpool_destroy(PINT_segpool_handle_t h);
+
+int PINT_segpool_register(PINT_segpool_handle_t h,
+                          PINT_segpool_unit_id *id);
+
+int PINT_segpool_take_segments(PINT_segpool_handle_t h,
+                               PINT_segpool_unit_id id,
+                               PVFS_size *bytes,
+                               int *count,
+                               PVFS_offset **offsets,
+                               PVFS_size **sizes);
+
+#endif

Index: module.mk.in
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/module.mk.in,v
diff -p -u -r1.37 -r1.37.4.1
--- module.mk.in	13 Jan 2009 17:57:57 -0000	1.37
+++ module.mk.in	6 Apr 2009 21:47:37 -0000	1.37.4.1
@@ -40,7 +40,8 @@ SERVERSRC += $(DIR)/server-config.c \
 	     $(DIR)/msgpairarray.c \
 	     $(DIR)/pint-eattr.c \
 	     $(DIR)/pint-mem.c \
-	     $(DIR)/pint-hint.c
+	     $(DIR)/pint-hint.c \
+	     $(DIR)/pint-segpool.c
 
 LIBBMISRC += $(DIR)/str-utils.c \
 	  $(DIR)/pint-event.c \



More information about the Pvfs2-cvs mailing list