root/ompi/mca/io/romio321/romio/adio/common/async_list.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ADIOI_Malloc_async_node
  2. ADIOI_Free_async_node
  3. ADIOI_Add_req_to_list
  4. ADIOI_Complete_async
  5. ADIOI_Del_req_from_list

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   2 /* 
   3  *
   4  *   Copyright (C) 1997 University of Chicago. 
   5  *   See COPYRIGHT notice in top-level directory.
   6  */
   7 
   8 #include "adio.h"
   9 #include "adio_extern.h"
  10 
  11 ADIOI_Async_node *ADIOI_Malloc_async_node(void)
  12 {
  13 /* returns a pointer to a new node that can be added to ADIOI_Async_list.
  14    To reduce the number of system calls, mallocs NUM nodes at a time
  15    and maintains list of available nodes. Supplies a node from this
  16    list if available, else mallocs a new set of NUM and provides one
  17    from that set. Is NUM=100 a good number? */
  18 
  19 #define NUM 100
  20 
  21     ADIOI_Async_node *curr, *ptr;
  22     int i;
  23 
  24     if (!ADIOI_Async_avail_head) {
  25         ADIOI_Async_avail_head = (ADIOI_Async_node *)
  26                       ADIOI_Malloc(NUM*sizeof(ADIOI_Async_node));  
  27         curr = ADIOI_Async_avail_head;
  28         for (i=1; i<NUM; i++) {
  29             curr->next = ADIOI_Async_avail_head+i;
  30             curr = curr->next;
  31         }
  32         curr->next = NULL;
  33         ADIOI_Async_avail_tail = curr;
  34 
  35         /* keep track of malloced area that needs to be freed later */
  36         if (!ADIOI_Malloc_async_tail) {
  37             ADIOI_Malloc_async_tail = (ADIOI_Malloc_async *)
  38                 ADIOI_Malloc(sizeof(ADIOI_Malloc_async)); 
  39             ADIOI_Malloc_async_head = ADIOI_Malloc_async_tail;
  40             ADIOI_Malloc_async_head->ptr = ADIOI_Async_avail_head;
  41             ADIOI_Malloc_async_head->next = NULL;
  42         }
  43         else {
  44             ADIOI_Malloc_async_tail->next = (ADIOI_Malloc_async *)
  45                 ADIOI_Malloc(sizeof(ADIOI_Malloc_async));
  46             ADIOI_Malloc_async_tail = ADIOI_Malloc_async_tail->next;
  47             ADIOI_Malloc_async_tail->ptr = ADIOI_Async_avail_head;
  48             ADIOI_Malloc_async_tail->next = NULL;
  49         }
  50     }
  51 
  52     ptr = ADIOI_Async_avail_head;
  53     ADIOI_Async_avail_head = ADIOI_Async_avail_head->next;
  54     if (!ADIOI_Async_avail_head) ADIOI_Async_avail_tail = NULL;
  55 
  56     return ptr;
  57 }
  58 
  59 
  60 void ADIOI_Free_async_node(ADIOI_Async_node *node)
  61 {
  62 /* moves this node to available pool. does not actually free it. */
  63 
  64     if (!ADIOI_Async_avail_tail)
  65         ADIOI_Async_avail_head = ADIOI_Async_avail_tail = node;
  66     else {
  67         ADIOI_Async_avail_tail->next = node;
  68         ADIOI_Async_avail_tail = node;
  69     }
  70     node->next = NULL;
  71 }
  72 
  73 
  74 void ADIOI_Add_req_to_list(ADIO_Request *request)
  75 {
  76 /* add request to list of outstanding requests */
  77 
  78     ADIOI_Async_node *curr;
  79 
  80     if (!ADIOI_Async_list_head) {
  81         ADIOI_Async_list_head = ADIOI_Malloc_async_node();
  82         ADIOI_Async_list_head->request = request;
  83         ADIOI_Async_list_head->prev = ADIOI_Async_list_head->next = NULL;
  84         ADIOI_Async_list_tail = ADIOI_Async_list_head;
  85         (*request)->ptr_in_async_list = ADIOI_Async_list_head;
  86     }
  87     else {
  88         curr = ADIOI_Async_list_tail;
  89         curr->next = ADIOI_Malloc_async_node();
  90         ADIOI_Async_list_tail = curr->next;
  91         ADIOI_Async_list_tail->request = request;
  92         ADIOI_Async_list_tail->prev = curr;
  93         ADIOI_Async_list_tail->next = NULL;
  94         (*request)->ptr_in_async_list = ADIOI_Async_list_tail;
  95     }
  96 }
  97         
  98 /* Sets error_code to MPI_SUCCESS on success, creates an error code on
  99  * failure.
 100  */
 101 void ADIOI_Complete_async(int *error_code)
 102 {
 103 /* complete all outstanding async I/O operations so that new ones can be
 104    initiated. Remove them all from async_list. */
 105 
 106     ADIO_Status status;
 107     ADIO_Request *request;
 108     ADIOI_Async_node *tmp;
 109     static char myname[] = "ADIOI_Complete_async";
 110 
 111     *error_code = MPI_SUCCESS;
 112 
 113     while (ADIOI_Async_list_head) {
 114         request = ADIOI_Async_list_head->request;
 115         (*request)->queued = -1; /* ugly internal hack that prevents
 116                   ADIOI_xxxComplete from freeing the request object. 
 117                   This is required, because the user will call MPI_Wait
 118                   later, which would require status to be filled. */
 119         switch ((*request)->optype) {
 120         case ADIOI_READ:
 121 /*          (*((*request)->fd->fns->ADIOI_xxx_ReadComplete))(request,
 122                                                     &status,error_code);*/
 123             ADIO_ReadComplete(request, &status, error_code);
 124             break;
 125         case ADIOI_WRITE:
 126 /*          (*((*request)->fd->fns->ADIOI_xxx_WriteComplete))(request,
 127                                                      &status, error_code);*/
 128             ADIO_WriteComplete(request, &status, error_code);
 129             break;
 130         default:
 131             /* --BEGIN ERROR HANDLING-- */
 132             *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 133                                                MPIR_ERR_RECOVERABLE,
 134                                                myname, __LINE__,
 135                                                MPI_ERR_INTERN,
 136                                                "Unknown request optype", 0);
 137             return;
 138             /* --END ERROR HANDLING-- */
 139         }
 140         (*request)->queued = 0;  /* dequeued, but request object not
 141                                     freed */
 142 
 143         tmp = ADIOI_Async_list_head;
 144         ADIOI_Async_list_head = ADIOI_Async_list_head->next;
 145         ADIOI_Free_async_node(tmp);
 146     }
 147     ADIOI_Async_list_tail = NULL;
 148 }
 149 
 150 
 151 void ADIOI_Del_req_from_list(ADIO_Request *request)
 152 {
 153 /* Delete a request that has already been completed from the async
 154    list and move it to the list of available nodes. Typically called
 155    from within an ADIO_Test/ADIO_Wait. */ 
 156 
 157     ADIOI_Async_node *curr, *prev, *next;
 158 
 159     curr = (*request)->ptr_in_async_list;
 160     prev = curr->prev;
 161 
 162     if (prev) prev->next = curr->next;
 163     else ADIOI_Async_list_head = curr->next;
 164 
 165     next = curr->next;
 166     if (next) next->prev = prev;
 167     else ADIOI_Async_list_tail = prev;
 168 
 169     ADIOI_Free_async_node(curr);
 170 }

/* [<][>][^][v][top][bottom][index][help] */