
00001 /* -*- Mode: C; c-basic-offset:4 ; -*- */ 00002 /* 00003 * $Id$ 00004 * 00005 * Copyright (C) 1997 University of Chicago. 00006 * See COPYRIGHT notice in top-level directory. 00007 */ 00008 00009 #include "adio.h" 00010 #include "adio_extern.h" 00011 00012 ADIOI_Async_node *ADIOI_Malloc_async_node(void) 00013 { 00014 /* returns a pointer to a new node that can be added to ADIOI_Async_list. 00015 To reduce the number of system calls, mallocs NUM nodes at a time 00016 and maintains list of available nodes. Supplies a node from this 00017 list if available, else mallocs a new set of NUM and provides one 00018 from that set. Is NUM=100 a good number? */ 00019 00020 #define NUM 100 00021 00022 ADIOI_Async_node *curr, *ptr; 00023 int i; 00024 00025 if (!ADIOI_Async_avail_head) { 00026 ADIOI_Async_avail_head = (ADIOI_Async_node *) 00027 ADIOI_Malloc(NUM*sizeof(ADIOI_Async_node)); 00028 curr = ADIOI_Async_avail_head; 00029 for (i=1; i<NUM; i++) { 00030 curr->next = ADIOI_Async_avail_head+i; 00031 curr = curr->next; 00032 } 00033 curr->next = NULL; 00034 ADIOI_Async_avail_tail = curr; 00035 00036 /* keep track of malloced area that needs to be freed later */ 00037 if (!ADIOI_Malloc_async_tail) { 00038 ADIOI_Malloc_async_tail = (ADIOI_Malloc_async *) 00039 ADIOI_Malloc(sizeof(ADIOI_Malloc_async)); 00040 ADIOI_Malloc_async_head = ADIOI_Malloc_async_tail; 00041 ADIOI_Malloc_async_head->ptr = ADIOI_Async_avail_head; 00042 ADIOI_Malloc_async_head->next = NULL; 00043 } 00044 else { 00045 ADIOI_Malloc_async_tail->next = (ADIOI_Malloc_async *) 00046 ADIOI_Malloc(sizeof(ADIOI_Malloc_async)); 00047 ADIOI_Malloc_async_tail = ADIOI_Malloc_async_tail->next; 00048 ADIOI_Malloc_async_tail->ptr = ADIOI_Async_avail_head; 00049 ADIOI_Malloc_async_tail->next = NULL; 00050 } 00051 } 00052 00053 ptr = ADIOI_Async_avail_head; 00054 ADIOI_Async_avail_head = ADIOI_Async_avail_head->next; 00055 if (!ADIOI_Async_avail_head) ADIOI_Async_avail_tail = NULL; 00056 00057 return ptr; 00058 } 00059 00060 00061 void ADIOI_Free_async_node(ADIOI_Async_node *node) 00062 { 00063 /* moves this node to available pool. does not actually free it. */ 00064 00065 if (!ADIOI_Async_avail_tail) 00066 ADIOI_Async_avail_head = ADIOI_Async_avail_tail = node; 00067 else { 00068 ADIOI_Async_avail_tail->next = node; 00069 ADIOI_Async_avail_tail = node; 00070 } 00071 node->next = NULL; 00072 } 00073 00074 00075 void ADIOI_Add_req_to_list(ADIO_Request *request) 00076 { 00077 /* add request to list of outstanding requests */ 00078 00079 ADIOI_Async_node *curr; 00080 00081 if (!ADIOI_Async_list_head) { 00082 ADIOI_Async_list_head = ADIOI_Malloc_async_node(); 00083 ADIOI_Async_list_head->request = request; 00084 ADIOI_Async_list_head->prev = ADIOI_Async_list_head->next = NULL; 00085 ADIOI_Async_list_tail = ADIOI_Async_list_head; 00086 (*request)->ptr_in_async_list = ADIOI_Async_list_head; 00087 } 00088 else { 00089 curr = ADIOI_Async_list_tail; 00090 curr->next = ADIOI_Malloc_async_node(); 00091 ADIOI_Async_list_tail = curr->next; 00092 ADIOI_Async_list_tail->request = request; 00093 ADIOI_Async_list_tail->prev = curr; 00094 ADIOI_Async_list_tail->next = NULL; 00095 (*request)->ptr_in_async_list = ADIOI_Async_list_tail; 00096 } 00097 } 00098 00099 00100 void ADIOI_Complete_async(int *error_code) 00101 { 00102 /* complete all outstanding async I/O operations so that new ones can be 00103 initiated. Remove them all from async_list. */ 00104 00105 ADIO_Status status; 00106 ADIO_Request *request; 00107 ADIOI_Async_node *tmp; 00108 00109 if (!ADIOI_Async_list_head) *error_code = MPI_SUCCESS; 00110 while (ADIOI_Async_list_head) { 00111 request = ADIOI_Async_list_head->request; 00112 (*request)->queued = -1; /* ugly internal hack that prevents 00113 ADIOI_xxxComplete from freeing the request object. 00114 This is required, because the user will call MPI_Wait 00115 later, which would require status to be filled. */ 00116 switch ((*request)->optype) { 00117 case ADIOI_READ: 00118 /* (*((*request)->fd->fns->ADIOI_xxx_ReadComplete))(request, 00119 &status,error_code);*/ 00120 ADIO_ReadComplete(request, &status, error_code); 00121 break; 00122 case ADIOI_WRITE: 00123 /* (*((*request)->fd->fns->ADIOI_xxx_WriteComplete))(request, 00124 &status, error_code);*/ 00125 ADIO_WriteComplete(request, &status, error_code); 00126 break; 00127 default: 00128 FPRINTF(stderr, "Error in ADIOI_Complete_Async\n"); 00129 break; 00130 } 00131 (*request)->queued = 0; /* dequeued, but request object not 00132 freed */ 00133 00134 tmp = ADIOI_Async_list_head; 00135 ADIOI_Async_list_head = ADIOI_Async_list_head->next; 00136 ADIOI_Free_async_node(tmp); 00137 } 00138 ADIOI_Async_list_tail = NULL; 00139 } 00140 00141 00142 void ADIOI_Del_req_from_list(ADIO_Request *request) 00143 { 00144 /* Delete a request that has already been completed from the async 00145 list and move it to the list of available nodes. Typically called 00146 from within an ADIO_Test/ADIO_Wait. */ 00147 00148 ADIOI_Async_node *curr, *prev, *next; 00149 00150 curr = (*request)->ptr_in_async_list; 00151 prev = curr->prev; 00152 00153 if (prev) prev->next = curr->next; 00154 else ADIOI_Async_list_head = curr->next; 00155 00156 next = curr->next; 00157 if (next) next->prev = prev; 00158 else ADIOI_Async_list_tail = prev; 00159 00160 ADIOI_Free_async_node(curr); 00161 }
1.5.5