00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef BSP_DELIVTABLE_H
00028 #define BSP_DELIVTABLE_H
00029
00054 #include "bsp_exptable.h"
00055 #include <config.h>
00056 void
00057 deliveryTable_execute (ExpandableTable *restrict , ExpandableTable *restrict ,
00058 ExpandableTable *restrict );
00059
00066 static inline void
00067 deliveryTable_initialize (ExpandableTable * restrict table, const int nprocs, const int rows)
00068 {
00069 union SpecInfo info;
00070 info.deliv.latest_pushed_element =
00071 bsp_calloc(nprocs, sizeof(VarSizeElement *));
00072 varElSizeTable_initialize (table, nprocs, rows, info);
00073 }
00074
00078 static inline void
00079 deliveryTable_reset(ExpandableTable * restrict table)
00080 {
00081 memset(table->info.deliv.latest_pushed_element, 0,
00082 sizeof(VarSizeElement *) * table->nprocs);
00083 expandableTable_reset(table);
00084 }
00085
00088 static inline void
00089 deliveryTable_destruct (ExpandableTable * restrict table)
00090 {
00091 free(table->info.deliv.latest_pushed_element);
00092 expandableTable_destruct (table);
00093 }
00094
00100 static inline void
00101 deliveryTable_expand (ExpandableTable * restrict table, const int rows)
00102 {
00103 union SpecInfo info = table->info;
00104 int offsets[table->nprocs], null[table->nprocs];
00105 int i;
00106
00107 for (i = 0; i < table->nprocs; i++)
00108 {
00109 offsets[i] = info.deliv.latest_pushed_element[i] - table->rows * i -
00110 (VarSizeElement *) table->data;
00111 null[i] = (info.deliv.latest_pushed_element[i] == NULL);
00112 }
00113 expandableTable_expand (table, rows, info);
00114
00115 for (i = 0; i < table->nprocs; i++)
00116 info.deliv.latest_pushed_element[i] = null[i] ? NULL :
00117 (VarSizeElement *) table->data + table->rows * i + offsets[i];
00118 table->info = info;
00119 }
00120
00121 static void
00122 delivInfoMake (union SpecInfo * restrict info , int b , int c)
00123 {
00124 }
00125
00131 static inline void
00132 deliveryTable_push (ExpandableTable * restrict table, const int proc, const VarSizeElement elem)
00133 {
00134 int offsets[table->nprocs], null[table->nprocs];
00135 int i;
00136
00137 for (i = 0; i < table->nprocs; i++)
00138 {
00139 offsets[i] = (i==proc) ?
00140 table->used_slot_count[i]
00141 :
00142 table->info.deliv.latest_pushed_element[i] - table->rows * i -
00143 (VarSizeElement *) table->data;
00144
00145 null[i] = (table->info.deliv.latest_pushed_element[i] == NULL);
00146 }
00147 varElSizeTable_push (table, proc, &delivInfoMake, elem);
00148
00149 for (i = 0; i < table->nprocs; i++)
00150 {
00151 table->info.deliv.latest_pushed_element[i] = null[i] && i!=proc ? NULL :
00152 (VarSizeElement *) table->data + i * table->rows + offsets[i];
00153 }
00154 }
00155
00164 static inline void
00165 deliveryTable_pushSend(ExpandableTable * restrict table, const int proc,
00166 const void * restrict tag, const int tag_size,
00167 const void * restrict payload, const int payload_size)
00168 {
00169
00170 SendObject sendobj; VarSizeElement element;
00171 VarSizeElement * restrict latest_element = table->info.deliv.latest_pushed_element[proc];
00172 int free_space, used_space, object_size;
00173 int old_element_slot_size, new_element_slot_size;
00174 char * restrict pointer;
00175
00178 if (latest_element != NULL &&
00179 latest_element->type == send &&
00180 latest_element->info.send.payload_size == payload_size&&
00181 latest_element->info.send.tag_size == tag_size )
00182 {
00183
00184
00185 object_size = tag_size + payload_size;
00186 used_space =
00187 (table->used_slot_count[proc] - 1)*sizeof(VarSizeElement) + latest_element->size;
00188 free_space = table->rows * sizeof(VarSizeElement) - used_space;
00189
00190 if (object_size > free_space)
00191 {
00192 deliveryTable_expand(table, MAX(table->rows * 2, 1 + object_size / sizeof(VarSizeElement)));
00193 latest_element = table->info.deliv.latest_pushed_element[proc];
00194 }
00195
00196
00197 pointer =
00198 (char *) latest_element + sizeof(VarSizeElement) +
00199 latest_element->info.send.item_count * (tag_size + payload_size);
00200
00201 new_element_slot_size =
00202 no_slots( sizeof(VarSizeElement) + latest_element->size + object_size
00203 , sizeof(VarSizeElement));
00204 old_element_slot_size =
00205 no_slots( sizeof(VarSizeElement) + latest_element->size
00206 , sizeof(VarSizeElement));
00207 table->used_slot_count[proc] += new_element_slot_size - old_element_slot_size;
00208
00209
00210 latest_element->size += object_size;
00211 latest_element->info.send.item_count++;
00212
00213 }
00214 else
00215 {
00216 sendobj.tag_size = tag_size; sendobj.payload_size = payload_size;
00217 sendobj.item_count = 1;
00218 element.size = tag_size + payload_size;
00219 element.type = send;
00220 element.info.send = sendobj;
00221 element.data = NULL;
00222
00223 object_size = no_slots( sizeof(VarSizeElement) + element.size
00224 , sizeof(VarSizeElement));
00225 free_space = table->rows - table->used_slot_count[proc];
00226
00227 if (free_space < object_size)
00228 deliveryTable_expand(table, MAX(table->rows * 2, object_size ));
00229
00230 pointer = (char *)
00231 ( (VarSizeElement *) table->data + proc * table->rows + table->used_slot_count[proc]);
00232 table->info.deliv.latest_pushed_element[proc] = (VarSizeElement *) pointer;
00233
00234
00235 * (VarSizeElement *) pointer = element;
00236 pointer += sizeof(VarSizeElement);
00237
00238 new_element_slot_size =
00239 no_slots( sizeof(VarSizeElement) + payload_size+tag_size
00240 , sizeof(VarSizeElement));
00241 table->used_slot_count[proc] += new_element_slot_size;
00242
00243
00244 }
00245
00246
00247 memcpy( pointer, tag, tag_size);
00248 pointer += tag_size;
00249
00250 memcpy( pointer, payload, payload_size);
00251 }
00252
00260 static inline void
00261 deliveryTable_pushPut(ExpandableTable * restrict table,
00262 const int proc, const void * const dst,
00263 const void * const restrict data, const int size)
00264 {
00265 VarSizeElement * restrict latest_element = table->info.deliv.latest_pushed_element[proc];
00266 int free_space, used_space, object_size;
00267 int old_element_slot_size, new_element_slot_size;
00268 char * restrict pointer;
00269
00271 if (latest_element != NULL &&
00272 latest_element->type == put &&
00273 latest_element->info.put.item_size == size)
00274 {
00275
00276
00277 object_size = sizeof( void * ) + size;
00278 used_space =
00279 (table->used_slot_count[proc] - 1)*sizeof(VarSizeElement) + latest_element->size;
00280 free_space = table->rows * sizeof(VarSizeElement) - used_space;
00281
00282 if (object_size > free_space)
00283 {
00284 deliveryTable_expand(table, MAX(table->rows * 2, 1 + object_size / sizeof(VarSizeElement)));
00285 latest_element = table->info.deliv.latest_pushed_element[proc];
00286 }
00287
00288
00289 pointer =
00290 (char *) latest_element + sizeof(VarSizeElement) +
00291 latest_element->info.put.item_count *
00292 (latest_element->info.put.item_size + sizeof (void *));
00293
00294 new_element_slot_size =
00295 no_slots( sizeof(VarSizeElement) + latest_element->size + object_size
00296 , sizeof(VarSizeElement));
00297 old_element_slot_size =
00298 no_slots( sizeof(VarSizeElement) + latest_element->size
00299 , sizeof(VarSizeElement));
00300 table->used_slot_count[proc] += new_element_slot_size - old_element_slot_size;
00301
00302
00303 latest_element->size += object_size;
00304 latest_element->info.put.item_count++;
00305
00306 }
00307 else
00308 {
00309 PutObject putobj;
00310 VarSizeElement element;
00311 putobj.item_count = 1; putobj.item_size=size;
00312 element.size = size + sizeof(void *);
00313 element.type = put;
00314 element.info.put = putobj;
00315 element.data = NULL;
00316
00317 free_space = table->rows - table->used_slot_count[proc];
00318 object_size =
00319 no_slots(sizeof(VarSizeElement) + size, sizeof(VarSizeElement));
00320 if (free_space < object_size)
00321 deliveryTable_expand(table, MAX(table->rows * 2, object_size ));
00322
00323 pointer = (char *)
00324 ( (VarSizeElement *) table->data + proc * table->rows + table->used_slot_count[proc]);
00325 table->info.deliv.latest_pushed_element[proc] = (VarSizeElement *) pointer;
00326
00327
00328 * (VarSizeElement *) pointer = element;
00329 pointer += sizeof(VarSizeElement);
00330
00331 new_element_slot_size =
00332 no_slots( sizeof(VarSizeElement) + size + sizeof(void *)
00333 , sizeof(VarSizeElement));
00334 table->used_slot_count[proc] += new_element_slot_size;
00335
00336
00337 }
00338
00339
00340 memcpy( pointer, &dst, sizeof(void const *));
00341 pointer += sizeof(void *);
00342
00343 memcpy( pointer, data, size);
00344 }
00345
00346
00347 #endif