This source file includes following definitions.
- mqs_setup_basic_callbacks
- mqs_version_compatibility
- mqs_version_string
- mqs_dll_taddr_width
- translate
- find_or_create_group
- group_decref
- mqs_setup_image
- mqs_image_has_queues
- mqs_setup_process
- mqs_process_has_queues
- communicators_changed
- find_communicator
- compare_comms
- rebuild_communicator_list
- mqs_update_communicator_list
- mqs_setup_communicator_iterator
- mqs_get_communicator
- mqs_get_comm_group
- mqs_next_communicator
- opal_list_t_init_parser
- next_item_opal_list_t
- opal_free_list_t_dump_position
- opal_free_list_t_init_parser
- opal_free_list_t_next_item
- dump_request
- fetch_request
- mqs_setup_operation_iterator
- mqs_next_operation
- mqs_destroy_process_info
- mqs_destroy_image_info
- mqs_dll_error_string
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 
  71 
  72 #include "ompi_config.h"
  73 
  74 #ifdef HAVE_NO_C_CONST
  75 #define const
  76 #endif
  77 #include <string.h>
  78 #include <stdlib.h>
  79 
  80 
  81 
  82 
  83 
  84 
  85 
  86 
  87 
  88 
  89 
  90 
  91 
  92 
  93 
  94 
  95 
  96 
  97 
  98 
  99 
 100 
 101 
 102 
 103 
 104 
 105 
 106 
 107 
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115 
 116 
 117 
 118 
 119 
 120 
 121 #include "ompi/group/group_dbg.h"
 122 #include "ompi/request/request_dbg.h"
 123 #include "ompi/mca/pml/base/pml_base_request_dbg.h"
 124 #include "mpi.h" 
 125 
 126 #include "msgq_interface.h"
 127 #include "ompi_msgq_dll_defs.h"
 128 
 129 
 130 
 131 
 132 
 133 
 134 
 135 #ifndef NULL
 136 #define NULL ((void *)0)
 137 #endif
 138 #ifndef TRUE
 139 #define TRUE (0==0)
 140 #endif
 141 #ifndef FALSE
 142 #define FALSE (0==1)
 143 #endif
 144 
 145 #ifdef OLD_STYLE_CPP_CONCAT
 146 #define concat(a,b) ab
 147 #define stringize(a) "a"
 148 #else
 149 #define concat(a,b) a##b
 150 #define stringize(a) #a
 151 #endif
 152 
 153 #define OPAL_ALIGN(x,a,t) (((x)+((t)(a)-1)) & ~(((t)(a)-1)))
 154 
 155 
 156 
 157 
 158 #define VERBOSE_GENERAL  0x00000001
 159 #define VERBOSE_GROUP    0x00000002
 160 #define VERBOSE_COMM     0x00000004
 161 #define VERBOSE_LISTS    0x00000008
 162 #define VERBOSE_REQ      0x00000010
 163 #define VERBOSE_REQ_DUMP 0x00000020
 164 
 165 #define VERBOSE 0x00000000
 166 
 167 #if VERBOSE
 168 #define DEBUG(LEVEL, WHAT) if(LEVEL & VERBOSE) { printf WHAT; }
 169 #else
 170 #define DEBUG(LEVEL,WHAT)
 171 #endif  
 172 
 173 
 174 
 175 
 176 void mqs_setup_basic_callbacks (const mqs_basic_callbacks * cb)
 177 {
 178     mqs_basic_entrypoints = cb;
 179 } 
 180 
 181 
 182 
 183 
 184 
 185 
 186 int mqs_version_compatibility (void)
 187 {
 188     return MQS_INTERFACE_COMPATIBILITY;
 189 } 
 190 
 191 static char mqs_version_str[OMPI_MAX_VER_SIZE];
 192 
 193 
 194 char *mqs_version_string (void)
 195 {
 196     int offset;
 197     offset = snprintf(mqs_version_str, OMPI_MAX_VER_SIZE-1,  
 198                       "Open MPI message queue support for parallel debuggers ");
 199     ompi_get_lib_version(mqs_version_str+offset, OMPI_MAX_VER_SIZE-offset);
 200     return mqs_version_str;
 201 } 
 202 
 203 
 204 int mqs_dll_taddr_width (void)
 205 {
 206     return sizeof (mqs_taddr_t);
 207 } 
 208 
 209 
 210 
 211 
 212 
 213 
 214 
 215 
 216 static int translate (group_t *this, int index)
 217 {
 218     if (index == MQS_INVALID_PROCESS ||
 219         ((unsigned int)index) >= ((unsigned int) this->entries))
 220         return MQS_INVALID_PROCESS;
 221     return this->local_to_global[index];
 222 } 
 223 
 224 
 225 
 226 
 227 static group_t * find_or_create_group( mqs_process *proc,
 228                                        mqs_taddr_t group_base )
 229 {
 230     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
 231     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
 232     mqs_image * image        = mqs_get_image (proc);
 233     mpi_image_info *i_info   = (mpi_image_info *)mqs_get_image_info (image);
 234     communicator_t *comm     = extra->communicator_list;
 235     int *tr;
 236     char *trbuffer;
 237     int i, np, is_dense;
 238     group_t *group;
 239     mqs_taddr_t value;
 240     mqs_taddr_t tablep;
 241 
 242     np = ompi_fetch_int( proc,
 243                          group_base + i_info->ompi_group_t.offset.grp_proc_count,
 244                          p_info );
 245     if( np < 0 ) {
 246         DEBUG(VERBOSE_COMM, ("Get a size for the communicator = %d\n", np));
 247         return NULL;  
 248     }
 249     is_dense =
 250         ompi_fetch_int( proc,
 251                         group_base + i_info->ompi_group_t.offset.grp_flags,
 252                         p_info );
 253     is_dense = (0 != (is_dense & OMPI_GROUP_DENSE));
 254 
 255     
 256     for (;comm; comm = comm->next) {
 257         group = comm->group;
 258         if( group && (group->group_base == group_base) ) {
 259             group->ref_count++;                 
 260             DEBUG(VERBOSE_GROUP, ("Increase refcount for group 0x%p to %d\n",
 261                                   (void*)group, group->ref_count) );
 262             return group;
 263         }
 264     }
 265 
 266     
 267     group = (group_t *)mqs_malloc (sizeof (group_t));
 268     tr = (int *)mqs_malloc (np*sizeof(int));
 269     trbuffer = (char *)mqs_malloc (np*sizeof(mqs_taddr_t));
 270     group->local_to_global = tr;
 271     group->group_base = group_base;
 272     DEBUG(VERBOSE_GROUP, ("Create a new group 0x%p with %d members\n",
 273                           (void*)group, np) );
 274 
 275     tablep = ompi_fetch_pointer( proc,
 276                                  group_base + i_info->ompi_group_t.offset.grp_proc_pointers,
 277                                  p_info);
 278 
 279     if( (0 != np) &&
 280         (mqs_ok != mqs_fetch_data(proc, tablep, np * p_info->sizes.pointer_size,
 281                                   trbuffer)) ) {
 282         DEBUG(VERBOSE_GROUP,("Failed to read the proc data. Destroy group %p\n",
 283                              (void*)group));
 284         mqs_free (group);
 285         mqs_free (tr);
 286         mqs_free (trbuffer);
 287         return NULL;
 288     }
 289 
 290     
 291 
 292 
 293 
 294 
 295 
 296 
 297 
 298 
 299 
 300      if( NULL == extra->world_proc_array ) {
 301          extra->world_proc_array = mqs_malloc( np * sizeof(mqs_taddr_t) );
 302          for( i = 0; i < np; i++ ) {
 303              mqs_target_to_host( proc, trbuffer + p_info->sizes.pointer_size*i,
 304                                  &value, p_info->sizes.pointer_size );
 305              extra->world_proc_array[i] = value;
 306              group->local_to_global[i] = is_dense ? i : -1;
 307          }
 308          extra->world_proc_array_entries = np;
 309      } else {
 310          int j;
 311 
 312          for( i = 0; i < np; i++ ) {
 313              mqs_target_to_host( proc, trbuffer + p_info->sizes.pointer_size*i,
 314                                  &value, p_info->sizes.pointer_size );
 315              if (is_dense) {
 316                  
 317                  for( j = 0; j < extra->world_proc_array_entries; j++ ) {
 318                      if( value == extra->world_proc_array[j] ) {
 319                          group->local_to_global[i] = j;
 320                          break;
 321                      }
 322                  }
 323              } else {
 324                  group->local_to_global[i] = -1;
 325              }
 326          }
 327      }
 328 
 329     mqs_free(trbuffer);
 330 
 331     group->entries = np;
 332     group->ref_count = 1;
 333     return group;
 334 } 
 335 
 336 
 337 static void group_decref (group_t * group)
 338 {
 339     DEBUG(VERBOSE_GROUP, ("Decrement reference count for group %p to %d\n", (void*)group,
 340                           (group->ref_count - 1)));
 341     if (--(group->ref_count) == 0) {
 342         mqs_free (group->local_to_global);
 343         DEBUG(VERBOSE_GROUP, ("Destroy group %p\n", (void*)group));
 344         mqs_free (group);
 345     }
 346 } 
 347 
 348 
 349 
 350 
 351 
 352 int mqs_setup_image (mqs_image *image, const mqs_image_callbacks *icb)
 353 {
 354     mpi_image_info *i_info = (mpi_image_info *)mqs_malloc (sizeof (mpi_image_info));
 355 
 356     if (!i_info)
 357         return err_no_store;
 358 
 359     memset ((void *)i_info, 0, sizeof (mpi_image_info));
 360     i_info->image_callbacks = icb;              
 361     i_info->extra = NULL;
 362 
 363     mqs_put_image_info (image, (mqs_image_info *)i_info);
 364 
 365     return mqs_ok;
 366 } 
 367 
 368 
 369 
 370 
 371 
 372 
 373 
 374 int mqs_image_has_queues (mqs_image *image, char **message)
 375 {
 376     mpi_image_info * i_info = (mpi_image_info *)mqs_get_image_info (image);
 377 
 378     i_info->extra = NULL;
 379 
 380     
 381     *message = "The symbols and types in the Open MPI library used by the debugger\n"
 382         "to extract the message queues are not as expected in\n"
 383         "the image '%s'\n"
 384         "No message queue display is possible.\n"
 385         "This is probably an Open MPI version or configuration problem.";
 386 
 387     
 388 
 389 
 390 
 391     mqs_find_function (image, "ompi_debugger_setup_dlls", mqs_lang_c, NULL);
 392 
 393     
 394 
 395 
 396 
 397     if (mqs_find_symbol (image, "MPIR_Ignore_queues", NULL) == mqs_ok) {
 398         *message = NULL;                                
 399         return err_silent_failure;
 400     }
 401 
 402     
 403     return ompi_fill_in_type_info(image, message);
 404 } 
 405 
 406 
 407 
 408 
 409 
 410 
 411 
 412 int mqs_setup_process (mqs_process *process, const mqs_process_callbacks *pcb)
 413 {
 414     
 415     mpi_process_info *p_info = (mpi_process_info *)mqs_malloc (sizeof (mpi_process_info));
 416 
 417     if (p_info) {
 418         mqs_image        *image;
 419         mpi_image_info   *i_info;
 420         mpi_process_info_extra *extra;
 421 
 422         p_info->process_callbacks = pcb;
 423 
 424         p_info->extra = mqs_malloc(sizeof(mpi_process_info_extra));
 425         extra = (mpi_process_info_extra*) p_info->extra;
 426 
 427         
 428         image  = mqs_get_image (process);
 429         i_info   = (mpi_image_info *)mqs_get_image_info (image);
 430 
 431         
 432         extra->communicator_list = NULL;
 433         
 434         extra->comm_lowest_free  = 0;
 435         extra->comm_number_free  = 0;
 436         
 437         extra->show_internal_requests = 0;
 438 
 439         extra->world_proc_array_entries = 0;
 440         extra->world_proc_array = NULL;
 441 
 442         mqs_get_type_sizes (process, &p_info->sizes);
 443         
 444 
 445 
 446 
 447 
 448 
 449         {
 450             mqs_taddr_t typedefs_sizeof;
 451 
 452             if (mqs_find_symbol (image, "MPIR_debug_typedefs_sizeof", &typedefs_sizeof) != mqs_ok) {
 453                 return err_no_store;
 454             }
 455             p_info->sizes.short_size = ompi_fetch_int( process, 
 456                                                        typedefs_sizeof,
 457                                                        p_info );
 458             typedefs_sizeof += p_info->sizes.int_size;
 459             p_info->sizes.int_size = ompi_fetch_int( process, 
 460                                                      typedefs_sizeof,
 461                                                      p_info );
 462             typedefs_sizeof += p_info->sizes.int_size;
 463              p_info->sizes.long_size = ompi_fetch_int( process, 
 464                                                        typedefs_sizeof,
 465                                                        p_info );
 466             typedefs_sizeof += p_info->sizes.int_size;
 467             p_info->sizes.long_long_size = ompi_fetch_int( process, 
 468                                                            typedefs_sizeof,
 469                                                            p_info );
 470             typedefs_sizeof += p_info->sizes.int_size;
 471             p_info->sizes.pointer_size = ompi_fetch_int( process, 
 472                                                          typedefs_sizeof,
 473                                                          p_info );
 474             typedefs_sizeof += p_info->sizes.int_size;
 475             p_info->sizes.bool_size = ompi_fetch_int( process, 
 476                                                       typedefs_sizeof,
 477                                                       p_info );
 478             typedefs_sizeof += p_info->sizes.int_size;
 479             p_info->sizes.size_t_size = ompi_fetch_int( process, 
 480                                                         typedefs_sizeof,
 481                                                         p_info );
 482             DEBUG( VERBOSE_GENERAL,
 483                    ("sizes short = %d int = %d long = %d long long = %d "
 484                     "void* = %d bool = %d size_t = %d\n",
 485                     p_info->sizes.short_size, p_info->sizes.int_size,
 486                     p_info->sizes.long_size, p_info->sizes.long_long_size,
 487                     p_info->sizes.pointer_size, p_info->sizes.bool_size,
 488                     p_info->sizes.size_t_size) );
 489         }
 490 
 491         mqs_put_process_info (process, (mqs_process_info *)p_info);
 492 
 493         return mqs_ok;
 494     }
 495     return err_no_store;
 496 } 
 497 
 498 
 499 
 500 
 501 int mqs_process_has_queues (mqs_process *proc, char **msg)
 502 {
 503     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
 504     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
 505     mqs_image * image        = mqs_get_image (proc);
 506     mpi_image_info   *i_info = (mpi_image_info *)mqs_get_image_info (image);
 507 
 508     
 509     *msg = 0;
 510     DEBUG(VERBOSE_GENERAL,("checking the status of the OMPI dll\n"));
 511     if (mqs_find_symbol (image, "ompi_mpi_communicators", &extra->commlist_base) != mqs_ok)
 512         return err_all_communicators;
 513 
 514     if (mqs_find_symbol (image, "mca_pml_base_send_requests", &extra->send_queue_base) != mqs_ok)
 515         return err_mpid_sends;
 516 
 517     if (mqs_find_symbol (image, "mca_pml_base_recv_requests", &extra->recv_queue_base) != mqs_ok)
 518         return err_mpid_recvs;
 519     DEBUG(VERBOSE_GENERAL,("process_has_queues returned success\n"));
 520     return mqs_ok;
 521 } 
 522 
 523 
 524 
 525 
 526 
 527 static int communicators_changed (mqs_process *proc)
 528 {
 529     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
 530     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
 531     mqs_image * image          = mqs_get_image (proc);
 532     mpi_image_info *i_info   = (mpi_image_info *)mqs_get_image_info (image);
 533     mqs_tword_t number_free;         
 534 
 535     mqs_tword_t lowest_free;         
 536 
 537     lowest_free = ompi_fetch_int( proc,
 538                                   extra->commlist_base + i_info->opal_pointer_array_t.offset.lowest_free,
 539                                   p_info );
 540     number_free = ompi_fetch_int( proc,
 541                                   extra->commlist_base + i_info->opal_pointer_array_t.offset.number_free,
 542                                   p_info );
 543     if( (lowest_free != extra->comm_lowest_free) ||
 544         (number_free != extra->comm_number_free) ) {
 545         DEBUG(VERBOSE_COMM, ("Recreate the communicator list\n"
 546                              "    lowest_free [current] %d != [stored] %d\n"
 547                              "    number_free [current] %d != [stored] %d\n",
 548                              (int)lowest_free, (int)extra->comm_lowest_free,
 549                              (int)number_free, (int)extra->comm_number_free) );
 550         return 1;
 551     }
 552     DEBUG(VERBOSE_COMM, ("Communicator list not modified\n") );
 553     return 0;
 554 } 
 555 
 556 
 557 
 558 
 559 
 560 
 561 
 562 static communicator_t * find_communicator( mpi_process_info *p_info,
 563                                            int recv_ctx )
 564 {
 565     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
 566     communicator_t * comm = extra->communicator_list;
 567 
 568     for( ; comm; comm = comm->next ) {
 569         if( comm->comm_info.unique_id == (mqs_taddr_t)recv_ctx )
 570             return comm;
 571     }
 572 
 573     return NULL;
 574 } 
 575 
 576 
 577 
 578 
 579 static int compare_comms (const void *a, const void *b)
 580 {
 581     communicator_t * ca = *(communicator_t **)a;
 582     communicator_t * cb = *(communicator_t **)b;
 583 
 584     return cb->comm_info.unique_id - ca->comm_info.unique_id;
 585 } 
 586 
 587 
 588 
 589 
 590 static int rebuild_communicator_list (mqs_process *proc)
 591 {
 592     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
 593     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
 594     mqs_image * image        = mqs_get_image (proc);
 595     mpi_image_info *i_info   = (mpi_image_info *)mqs_get_image_info (image);
 596     communicator_t **commp, *old;
 597     int i, commcount = 0, context_id;
 598     mqs_tword_t comm_size, lowest_free, number_free;
 599     mqs_taddr_t comm_addr_base;
 600     mqs_taddr_t comm_ptr;
 601 
 602     DEBUG(VERBOSE_COMM,("rebuild_communicator_list called "
 603                         "(commlist_base %llx, array offset %ld array size %d)\n",
 604                         (long long)extra->commlist_base,
 605                         (long)i_info->opal_pointer_array_t.offset.addr,
 606                         i_info->opal_pointer_array_t.size));
 607     
 608 
 609 
 610 
 611     comm_size = ompi_fetch_int( proc,
 612                                 extra->commlist_base + i_info->opal_pointer_array_t.offset.size,
 613                                 p_info );
 614     lowest_free = ompi_fetch_int( proc,
 615                                   extra->commlist_base + i_info->opal_pointer_array_t.offset.lowest_free,
 616                                   p_info );
 617     number_free = ompi_fetch_int( proc,
 618                                   extra->commlist_base + i_info->opal_pointer_array_t.offset.number_free,
 619                                   p_info );
 620     extra->comm_lowest_free = lowest_free;
 621     extra->comm_number_free = number_free;
 622 
 623     DEBUG(VERBOSE_COMM,("Number of coms %d lowest_free %d number_free %d\n",
 624                         (int)comm_size, (int)lowest_free, (int)number_free));
 625     
 626 
 627 
 628 
 629 
 630 
 631 
 632     extra->world_proc_array_entries = 0;
 633     mqs_free( extra->world_proc_array );
 634     extra->world_proc_array = NULL;
 635 
 636     
 637     comm_addr_base =
 638         ompi_fetch_pointer( proc,
 639                             extra->commlist_base + i_info->opal_pointer_array_t.offset.addr,
 640                             p_info );
 641     DEBUG(VERBOSE_COMM,("Array of communicators starting at 0x%llx (sizeof(mqs_taddr_t*) = %d)\n",
 642                         (long long)comm_addr_base, (int)sizeof(mqs_taddr_t)));
 643     for( i = 0; (commcount < (comm_size - number_free)) && (i < comm_size); i++ ) {
 644         
 645         comm_ptr =
 646             ompi_fetch_pointer( proc,
 647                                 comm_addr_base + i * p_info->sizes.pointer_size,
 648                                 p_info );
 649         DEBUG(VERBOSE_GENERAL,("Fetch communicator pointer 0x%llx\n", (long long)comm_ptr));
 650         if( 0 == comm_ptr ) continue;
 651         commcount++;
 652         
 653         DEBUG(VERBOSE_GENERAL, ("Retrieve context_id from 0x%llx and local_rank from 0x%llx\n",
 654                                 (long long)(comm_ptr + i_info->ompi_communicator_t.offset.c_contextid),
 655                                 (long long)(comm_ptr + i_info->ompi_communicator_t.offset.c_my_rank)));
 656         context_id = ompi_fetch_int( proc,
 657                                      comm_ptr + i_info->ompi_communicator_t.offset.c_contextid,
 658                                      p_info );
 659         
 660         old = find_communicator(p_info, context_id);
 661         if( NULL == old ) {
 662             mqs_taddr_t group_base;
 663 
 664             old = (communicator_t *)mqs_malloc (sizeof (communicator_t));
 665             
 666             old->next                 = extra->communicator_list;
 667             extra->communicator_list = old;
 668             old->comm_ptr             = comm_ptr;
 669             old->comm_info.unique_id  = context_id;
 670             old->comm_info.local_rank = ompi_fetch_int(proc,
 671                                                        comm_ptr + i_info->ompi_communicator_t.offset.c_my_rank,
 672                                                        p_info);
 673             old->group = NULL;
 674 
 675             DEBUG(VERBOSE_COMM,("Create new communicator 0x%lx with context_id %d and local_rank %d\n",
 676                                 (long)old, context_id, local_rank));
 677             
 678             group_base =
 679                 ompi_fetch_pointer( proc, comm_ptr + i_info->ompi_communicator_t.offset.c_local_group,
 680                                     p_info );
 681             old->group = find_or_create_group( proc, group_base );
 682         }
 683         mqs_fetch_data( proc, comm_ptr + i_info->ompi_communicator_t.offset.c_name,
 684                         64, old->comm_info.name );
 685 
 686         if( NULL != old->group ) {
 687             old->comm_info.size = old->group->entries;
 688         }
 689         old->present = TRUE;
 690         DEBUG(VERBOSE_COMM,("Communicator 0x%llx %d local_rank %d name %s group %p\n",
 691                             (long long)old->comm_ptr, (int)old->comm_info.unique_id,
 692                             (int)old->comm_info.local_rank, old->comm_info.name,
 693                             (void*)old->group));
 694     }
 695 
 696     
 697 
 698 
 699     commp = &extra->communicator_list;
 700     commcount = 0;
 701     for (; *commp; ) {
 702         communicator_t *comm = *commp;
 703         if (comm->present) {
 704             comm->present = FALSE;
 705             commcount++;
 706             DEBUG(VERBOSE_COMM, ("Keep communicator 0x%llx name %s\n",
 707                                  (long long)comm->comm_ptr, comm->comm_info.name));
 708             commp = &(*commp)->next;        
 709         } else { 
 710             *commp = comm->next;                        
 711             DEBUG(VERBOSE_COMM, ("Remove communicator 0x%llx name %s (group %p)\n",
 712                                  (long long)comm->comm_ptr, comm->comm_info.name,
 713                                  (void*)comm->group));
 714             group_decref (comm->group);         
 715             mqs_free (comm);
 716         }
 717     }
 718 
 719     if (commcount) {
 720         
 721         communicator_t ** comm_array =
 722             (communicator_t **) mqs_malloc(commcount * sizeof (communicator_t *));
 723         communicator_t *comm = extra->communicator_list;
 724 
 725         for (i=0; i<commcount; i++, comm=comm->next)
 726             comm_array [i] = comm;
 727 
 728         
 729         qsort (comm_array, commcount, sizeof (communicator_t *), compare_comms);
 730 
 731         
 732         extra->communicator_list = NULL;
 733         for (i=0; i<commcount; i++) {
 734             comm = comm_array[i];
 735             comm->next = extra->communicator_list;
 736             extra->communicator_list = comm;
 737         }
 738 
 739         mqs_free (comm_array);
 740     }
 741 
 742     return mqs_ok;
 743 } 
 744 
 745 
 746 
 747 
 748 int mqs_update_communicator_list (mqs_process *proc)
 749 {
 750     if (communicators_changed (proc))
 751         return rebuild_communicator_list (proc);
 752     return mqs_ok;
 753 } 
 754 
 755 
 756 
 757 
 758 
 759 
 760 int mqs_setup_communicator_iterator (mqs_process *proc)
 761 {
 762     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
 763     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
 764 
 765     
 766     extra->current_communicator = extra->communicator_list;
 767     
 768     extra->next_msg.free_list            = 0;
 769     extra->next_msg.current_item         = 0;
 770     extra->next_msg.opal_list_t_pos.list = 0;
 771 
 772     DEBUG(VERBOSE_COMM,("mqs_setup_communicator_iterator called\n"));
 773     return extra->current_communicator == NULL ? mqs_end_of_list : mqs_ok;
 774 } 
 775 
 776 
 777 
 778 
 779 int mqs_get_communicator (mqs_process *proc, mqs_communicator *comm)
 780 {
 781     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
 782     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
 783 
 784     if (extra->current_communicator) {
 785         *comm = extra->current_communicator->comm_info;
 786         DEBUG(VERBOSE_COMM,("mqs_get_communicator %d local_rank %d name %s\n",
 787                             (int)comm->unique_id, (int)comm->local_rank,
 788                             comm->name));
 789         return mqs_ok;
 790     }
 791     DEBUG(VERBOSE_COMM,("No more communicators for this iteration\n"));
 792     return err_no_current_communicator;
 793 } 
 794 
 795 
 796 
 797 
 798 int mqs_get_comm_group (mqs_process *proc, int *group_members)
 799 {
 800     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
 801     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
 802     communicator_t     *comm   = extra->current_communicator;
 803 
 804     if (comm && comm->group) {
 805         group_t * g = comm->group;
 806         int i;
 807 
 808         for (i=0; i<g->entries; i++)
 809             group_members[i] = g->local_to_global[i];
 810 
 811         return mqs_ok;
 812     }
 813     return err_no_current_communicator;
 814 } 
 815 
 816 
 817 
 818 
 819 int mqs_next_communicator (mqs_process *proc)
 820 {
 821     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
 822     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
 823 
 824     extra->current_communicator = extra->current_communicator->next;
 825     return (extra->current_communicator != NULL) ? mqs_ok : mqs_end_of_list;
 826 } 
 827 
 828 
 829 
 830 
 831 static int opal_list_t_init_parser( mqs_process *proc, mpi_process_info *p_info,
 832                                     mqs_opal_list_t_pos* position, mqs_taddr_t list )
 833 {
 834     mqs_image * image        = mqs_get_image (proc);
 835     mpi_image_info *i_info   = (mpi_image_info *)mqs_get_image_info (image);
 836 
 837     position->list = list;
 838     position->sentinel = position->list + i_info->opal_list_t.offset.opal_list_sentinel;
 839     position->current_item =
 840         ompi_fetch_pointer( proc, position->sentinel + i_info->opal_list_item_t.offset.opal_list_next,
 841                             p_info );
 842     if( position->current_item == position->sentinel )
 843         position->current_item = 0;
 844     DEBUG(VERBOSE_LISTS,("opal_list_t_init_parser list = 0x%llx, sentinel = 0x%llx, "
 845                          "current_item = 0x%llx\n", (long long)position->list,
 846                          (long long)position->sentinel, (long long)position->current_item));
 847     return mqs_ok;
 848 }
 849 
 850 static int next_item_opal_list_t( mqs_process *proc, mpi_process_info *p_info,
 851                                   mqs_opal_list_t_pos* position, mqs_taddr_t* active_item )
 852 {
 853     mqs_image * image        = mqs_get_image (proc);
 854     mpi_image_info *i_info   = (mpi_image_info *)mqs_get_image_info (image);
 855 
 856     *active_item = position->current_item;
 857     if( 0 == position->current_item )
 858         return mqs_end_of_list;
 859 
 860     position->current_item =
 861         ompi_fetch_pointer( proc,
 862                             position->current_item + i_info->opal_list_item_t.offset.opal_list_next,
 863                             p_info );
 864     if( position->current_item == position->sentinel )
 865         position->current_item = 0;
 866     return mqs_ok;
 867 }
 868 
 869 #if defined(CODE_NOT_USED)
 870 
 871 
 872 
 873 static void opal_free_list_t_dump_position( mqs_opal_free_list_t_pos* position )
 874 {
 875     printf( "position->opal_list_t_pos.current_item = 0x%llx\n", (long long)position->opal_list_t_pos.current_item );
 876     printf( "position->opal_list_t_pos.list         = 0x%llx\n", (long long)position->opal_list_t_pos.list );
 877     printf( "position->opal_list_t_pos.sentinel     = 0x%llx\n", (long long)position->opal_list_t_pos.sentinel );
 878     printf( "position->current_item                 = 0x%llx\n", (long long)position->current_item );
 879     printf( "position->upper_bound                  = 0x%llx\n", (long long)position->upper_bound );
 880     printf( "position->header_space                 = %llx\n", (long long)position->header_space );
 881     printf( "position->free_list                    = 0x%llx\n", (long long)position->free_list );
 882     printf( "position->fl_frag_class                = 0x%llx\n", (long long)position->fl_frag_class );
 883     printf( "position->fl_mpool                     = 0x%llx\n", (long long)position->fl_mpool );
 884     printf( "position->fl_frag_size                 = %llx\n", (long long)position->fl_frag_size );
 885     printf( "position->fl_frag_alignment            = %llx\n", (long long)position->fl_frag_alignment );
 886     printf( "position->fl_num_per_alloc             = %llx\n", (long long)position->fl_num_per_alloc );
 887     printf( "position->fl_num_allocated             = %llx\n", (long long)position->fl_num_allocated );
 888     printf( "position->fl_num_initial_alloc         = %llx\n", (long long)position->fl_num_initial_alloc );
 889 }
 890 #endif  
 891 
 892 static int opal_free_list_t_init_parser( mqs_process *proc, mpi_process_info *p_info,
 893                                          mqs_opal_free_list_t_pos* position, mqs_taddr_t free_list )
 894 {
 895     mqs_image * image          = mqs_get_image (proc);
 896     mpi_image_info *i_info   = (mpi_image_info *)mqs_get_image_info (image);
 897     mqs_taddr_t active_allocation;
 898 
 899     position->free_list = free_list;
 900 
 901     position->fl_frag_size =
 902         ompi_fetch_size_t( proc, position->free_list + i_info->opal_free_list_t.offset.fl_frag_size,
 903                            p_info );
 904     position->fl_frag_alignment =
 905         ompi_fetch_size_t( proc, position->free_list + i_info->opal_free_list_t.offset.fl_frag_alignment,
 906                            p_info );
 907     position->fl_frag_class =
 908         ompi_fetch_pointer( proc, position->free_list + i_info->opal_free_list_t.offset.fl_frag_class,
 909                             p_info );
 910     position->fl_mpool =
 911         ompi_fetch_pointer( proc, position->free_list + i_info->opal_free_list_t.offset.fl_mpool,
 912                             p_info );
 913     position->fl_num_per_alloc =
 914         ompi_fetch_size_t( proc, position->free_list + i_info->opal_free_list_t.offset.fl_num_per_alloc,
 915                            p_info );
 916     position->fl_num_allocated =
 917         ompi_fetch_size_t( proc, position->free_list + i_info->opal_free_list_t.offset.fl_num_allocated,
 918                            p_info );
 919 
 920     if( 0 == position->fl_mpool ) {
 921         position->header_space = position->fl_frag_size;
 922     } else {
 923         DEBUG(VERBOSE_GENERAL, ("BLAH !!! (CORRECT ME)\n"));
 924         position->header_space = position->fl_frag_size;
 925     }
 926     position->header_space = OPAL_ALIGN( position->header_space,
 927                                          position->fl_frag_alignment, mqs_taddr_t );
 928 
 929     
 930 
 931 
 932 
 933 
 934 
 935     if( position->fl_num_allocated <= position->fl_num_per_alloc ) {
 936         position->fl_num_initial_alloc = position->fl_num_allocated;
 937     } else {
 938         position->fl_num_initial_alloc = position->fl_num_allocated % position->fl_num_per_alloc;
 939         if( 0 == position->fl_num_initial_alloc )
 940             position->fl_num_initial_alloc = position->fl_num_per_alloc;
 941     }
 942     DEBUG(VERBOSE_LISTS,("opal_free_list_t fl_frag_size = %lld fl_header_space = %lld\n"
 943                          "                 fl_frag_alignment = %lld fl_num_per_alloc = %lld\n"
 944                          "                 fl_num_allocated = %lld fl_num_initial_alloc = %lld\n"
 945                          "                 header_space = %lld\n",
 946                          (long long)position->fl_frag_size, (long long)position->header_space,
 947                          (long long)position->fl_frag_alignment, (long long)position->fl_num_per_alloc,
 948                          (long long)position->fl_num_allocated, (long long)position->fl_num_initial_alloc,
 949                          (long long)position->header_space));
 950 
 951     
 952 
 953 
 954     opal_list_t_init_parser( proc, p_info, &position->opal_list_t_pos,
 955                              position->free_list + i_info->opal_free_list_t.offset.fl_allocations );
 956     next_item_opal_list_t( proc, p_info, &position->opal_list_t_pos, &active_allocation );
 957     DEBUG(VERBOSE_LISTS,("active_allocation 0x%llx header_space %d\n",
 958                          (long long)active_allocation, (int)position->header_space));
 959     if( 0 == active_allocation ) {  
 960         position->upper_bound = 0;
 961     } else {
 962         
 963 
 964 
 965         active_allocation += i_info->opal_free_list_item_t.size;
 966         active_allocation = OPAL_ALIGN( active_allocation,
 967                                         position->fl_frag_alignment, mqs_taddr_t );
 968         
 969 
 970 
 971         position->upper_bound =
 972             position->fl_num_initial_alloc * position->header_space + active_allocation;
 973         DEBUG(VERBOSE_LISTS,("there are some elements in the list "
 974                              "active_allocation = %llx upper_bound = %llx\n",
 975                              (long long)active_allocation, (long long)position->upper_bound));
 976     }
 977     position->current_item = active_allocation;
 978 
 979     
 980     return mqs_ok;
 981 }
 982 
 983 
 984 
 985 
 986 static int opal_free_list_t_next_item( mqs_process *proc, mpi_process_info *p_info,
 987                                        mqs_opal_free_list_t_pos* position, mqs_taddr_t* active_item )
 988 {
 989     mqs_image * image          = mqs_get_image (proc);
 990     mpi_image_info *i_info   = (mpi_image_info *)mqs_get_image_info (image);
 991     mqs_taddr_t active_allocation;
 992 
 993     *active_item = position->current_item;
 994     if( 0 == position->current_item )  
 995         return mqs_ok;
 996 
 997     position->current_item += position->header_space;
 998     if( position->current_item >= position->upper_bound ) {
 999         DEBUG(VERBOSE_LISTS,("Reach the end of one of the opal_free_list_t "
1000                              "allocations. Go to the next one\n"));
1001         
1002         next_item_opal_list_t( proc, p_info,
1003                                &position->opal_list_t_pos, &active_allocation );
1004         if( 0 == active_allocation ) { 
1005             position->current_item = 0;
1006             return mqs_ok;
1007         }
1008         
1009 
1010 
1011         active_allocation += i_info->opal_free_list_item_t.size;
1012         active_allocation = OPAL_ALIGN( active_allocation,
1013                                         position->fl_frag_alignment, mqs_taddr_t );
1014         
1015 
1016 
1017         position->upper_bound =
1018             position->fl_num_per_alloc * position->header_space + active_allocation;
1019         position->current_item = active_allocation;
1020         DEBUG(VERBOSE_LISTS,("there are more elements in the list "
1021                              "active_allocation = %llx upper_bound = %llx\n",
1022                              (long long)active_allocation, (long long)position->upper_bound));
1023         
1024     }
1025     DEBUG(VERBOSE_LISTS,("Free list actual position 0x%llx next element at 0x%llx\n",
1026                          (long long)*active_item, (long long)position->current_item));
1027     return mqs_ok;
1028 }
1029 
1030 static void dump_request( mqs_taddr_t current_item, mqs_pending_operation *res )
1031 {
1032     if(!(VERBOSE_REQ_DUMP & VERBOSE)) return;
1033     printf( "\n+===============================================+\n"
1034             "|Request 0x%llx contain \n"
1035             "|    res->status              = %d\n"
1036             "|    res->desired_local_rank  = %ld\n"
1037             "|    res->desired_global_rank = %ld\n"
1038             "|    res->tag_wild            = %ld\n"
1039             "|    res->desired_tag         = %ld\n"
1040             "|    res->system_buffer       = %s\n"
1041             "|    res->buffer              = 0x%llx\n"
1042             "|    res->desired_length      = %ld\n",
1043         (long long)current_item, res->status, (long)res->desired_local_rank,
1044         (long)res->desired_global_rank, (long)res->tag_wild, (long)res->desired_tag,
1045         (TRUE == res->system_buffer ? "TRUE" : "FALSE"), (long long)res->buffer,
1046         (long)res->desired_length );
1047 
1048     if( res->status > mqs_st_pending ) {
1049         printf( "|    res->actual_length       = %ld\n"
1050                 "|    res->actual_tag          = %ld\n"
1051                 "|    res->actual_local_rank   = %ld\n"
1052                 "|    res->actual_global_rank  = %ld\n",
1053                 (long)res->actual_length, (long)res->actual_tag,
1054                 (long)res->actual_local_rank, (long)res->actual_global_rank );
1055     }
1056     if( '\0' != res->extra_text[0][0] )
1057         printf( "|    extra[0] = %s\n", res->extra_text[0] );
1058     if( '\0' != res->extra_text[1][0] )
1059         printf( "|    extra[1] = %s\n", res->extra_text[1] );
1060     if( '\0' != res->extra_text[2][0] )
1061         printf( "|    extra[2] = %s\n", res->extra_text[2] );
1062     if( '\0' != res->extra_text[3][0] )
1063         printf( "|    extra[3] = %s\n", res->extra_text[3] );
1064     if( '\0' != res->extra_text[4][0] )
1065         printf( "|    extra[4] = %s\n", res->extra_text[4] );
1066     printf( "+===============================================+\n\n" );
1067 }
1068 
1069 
1070 
1071 
1072 
1073 static int fetch_request( mqs_process *proc, mpi_process_info *p_info,
1074                           mqs_pending_operation *res, int look_for_user_buffer )
1075 {
1076     mqs_image * image        = mqs_get_image (proc);
1077     mpi_image_info *i_info   = (mpi_image_info *)mqs_get_image_info (image);
1078     mqs_taddr_t current_item;
1079     mqs_tword_t req_complete, req_pml_complete, req_valid, req_type;
1080     mqs_taddr_t req_buffer, req_comm;
1081     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
1082 
1083     
1084   rescan_requests:
1085     while( 1 ) {
1086         opal_free_list_t_next_item( proc, p_info,
1087                                     &extra->next_msg, ¤t_item );
1088         if( 0 == current_item ) {
1089             DEBUG(VERBOSE_REQ,("no more items in the %s request queue\n",
1090                                look_for_user_buffer ? "receive" : "send" ));
1091             return mqs_end_of_list;
1092         }
1093         req_valid = ompi_fetch_int( proc, current_item + i_info->ompi_request_t.offset.req_state, p_info );
1094         if( OMPI_REQUEST_INVALID == req_valid ) continue;
1095         req_comm = ompi_fetch_pointer( proc, current_item + i_info->mca_pml_base_request_t.offset.req_comm, p_info );
1096         if( extra->current_communicator->comm_ptr == req_comm ) break;
1097         DEBUG(VERBOSE_REQ,("unmatched request (0x%llx) req_comm = %llx current_com = %llx\n",
1098                            (long long)current_item, (long long)req_comm,
1099                            (long long)extra->current_communicator->comm_ptr));
1100     }
1101 
1102     res->extra_text[0][0] = 0; res->extra_text[1][0] = 0; res->extra_text[2][0] = 0;
1103     res->extra_text[3][0] = 0; res->extra_text[4][0] = 0;
1104 
1105     req_type = ompi_fetch_int( proc, current_item + i_info->ompi_request_t.offset.req_type, p_info );
1106     if( OMPI_REQUEST_PML == req_type ) {
1107         mqs_taddr_t ompi_datatype;
1108         char data_name[64];
1109 
1110         
1111 
1112 
1113 
1114         res->desired_tag =
1115             ompi_fetch_int( proc, current_item + i_info->mca_pml_base_request_t.offset.req_tag, p_info );
1116         if( MPI_ANY_TAG == (int)res->desired_tag ) {
1117             res->tag_wild = TRUE;
1118         } else {
1119             
1120             if( ((int)res->desired_tag < 0) && (0 == extra->show_internal_requests) )
1121                 goto rescan_requests;
1122             res->tag_wild = FALSE;
1123         }
1124 
1125         req_type =
1126             ompi_fetch_int( proc, current_item + i_info->mca_pml_base_request_t.offset.req_type,
1127                             p_info);
1128         req_complete =
1129             ompi_fetch_bool( proc,
1130                              current_item + i_info->ompi_request_t.offset.req_complete,
1131                              p_info );
1132         req_pml_complete =
1133             ompi_fetch_bool( proc,
1134                              current_item + i_info->mca_pml_base_request_t.offset.req_pml_complete,
1135                              p_info );
1136         res->status = (0 == req_complete ? mqs_st_pending : mqs_st_complete);
1137 
1138         res->desired_local_rank  = ompi_fetch_int( proc, current_item + i_info->mca_pml_base_request_t.offset.req_peer, p_info );
1139         res->desired_global_rank = translate( extra->current_communicator->group,
1140                                               res->desired_local_rank );
1141 
1142         res->buffer = ompi_fetch_pointer( proc, current_item + i_info->mca_pml_base_request_t.offset.req_addr,
1143                                      p_info );
1144         
1145         res->system_buffer = FALSE;
1146 
1147         
1148         ompi_datatype =
1149             ompi_fetch_pointer( proc,
1150                                 current_item + i_info->mca_pml_base_request_t.offset.req_datatype, p_info );
1151         
1152         res->desired_length =
1153             ompi_fetch_size_t( proc,
1154                                ompi_datatype + i_info->ompi_datatype_t.offset.size,
1155                                p_info );
1156         
1157         mqs_fetch_data( proc, ompi_datatype + i_info->ompi_datatype_t.offset.name,
1158                         64, data_name );
1159         if( '\0' != data_name[0] ) {
1160             
1161             
1162             
1163             
1164             
1165             
1166             
1167             data_name[4] = '\0';
1168             snprintf( (char*)res->extra_text[1], 64, "Data: %d",
1169                       (int)res->desired_length);
1170             snprintf( (char*)res->extra_text[2], 64, "%s",
1171                       data_name );
1172         }
1173         
1174         res->desired_length *=
1175             ompi_fetch_size_t( proc,
1176                                current_item + i_info->mca_pml_base_request_t.offset.req_count,
1177                                p_info );
1178 
1179         if( MCA_PML_REQUEST_SEND == req_type ) {
1180             snprintf( (char *)res->extra_text[0], 64, "Send: 0x%llx", (long long)current_item );
1181             req_buffer =
1182                 ompi_fetch_pointer( proc,
1183                                     current_item + i_info->mca_pml_base_send_request_t.offset.req_addr,
1184                                     p_info );
1185             res->system_buffer = ( req_buffer == res->buffer ? FALSE : TRUE );
1186             res->actual_length =
1187                 ompi_fetch_size_t( proc,
1188                                    current_item + i_info->mca_pml_base_send_request_t.offset.req_bytes_packed, p_info );
1189             res->actual_tag         = res->desired_tag;
1190             res->actual_local_rank  = res->desired_local_rank;
1191             res->actual_global_rank = res->actual_local_rank;
1192         } else if( MCA_PML_REQUEST_RECV == req_type ) {
1193             snprintf( (char *)res->extra_text[0], 64, "Receive: 0x%llx", (long long)current_item );
1194             
1195 
1196 
1197 
1198 
1199             res->actual_tag =
1200                 ompi_fetch_int( proc, current_item + i_info->ompi_request_t.offset.req_status +
1201                                 i_info->ompi_status_public_t.offset.MPI_TAG, p_info );
1202             if( MPI_ANY_TAG != (int)res->actual_tag ) {
1203                 res->status = mqs_st_matched;
1204                 res->desired_length =
1205                     ompi_fetch_size_t( proc,
1206                                        current_item + i_info->mca_pml_base_recv_request_t.offset.req_bytes_packed,
1207                                        p_info );
1208                 res->actual_local_rank =
1209                     ompi_fetch_int( proc, current_item + i_info->ompi_request_t.offset.req_status +
1210                                     i_info->ompi_status_public_t.offset.MPI_SOURCE, p_info );
1211                 res->actual_global_rank = translate( extra->current_communicator->group,
1212                                                   res->actual_local_rank );
1213             }
1214         } else {
1215             snprintf( (char *)res->extra_text[0], 64, "Unknown type of request 0x%llx", (long long)current_item );
1216         }
1217         if( 0 != req_pml_complete ) {
1218                         snprintf( (char *)res->extra_text[1], 64, "Data transfer completed" );
1219         }
1220 
1221         
1222         
1223 
1224 
1225         if( (mqs_st_pending < res->status) && (MCA_PML_REQUEST_SEND != req_type) ) {  
1226             res->actual_length       =
1227                 ompi_fetch_size_t( proc, current_item + i_info->ompi_request_t.offset.req_status +
1228                                    i_info->ompi_status_public_t.offset._ucount, p_info );
1229             res->actual_tag          =
1230                 ompi_fetch_int( proc, current_item + i_info->ompi_request_t.offset.req_status +
1231                                 i_info->ompi_status_public_t.offset.MPI_TAG, p_info );
1232             res->actual_local_rank   =
1233                 ompi_fetch_int( proc, current_item + i_info->ompi_request_t.offset.req_status +
1234                                 i_info->ompi_status_public_t.offset.MPI_SOURCE, p_info );
1235             res->actual_global_rank  = translate( extra->current_communicator->group,
1236                                                   res->actual_local_rank );
1237         }
1238         dump_request( current_item, res );
1239     }
1240     return mqs_ok;
1241 }
1242 
1243 
1244 
1245 
1246 int mqs_setup_operation_iterator (mqs_process *proc, int op)
1247 {
1248     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
1249     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
1250 
1251     extra->what = (mqs_op_class)op;
1252 
1253     switch (op) {
1254     case mqs_pending_sends:
1255         DEBUG(VERBOSE_REQ,("setup the send queue iterator\n"));
1256         opal_free_list_t_init_parser( proc, p_info, &extra->next_msg, extra->send_queue_base );
1257         return mqs_ok;
1258 
1259     case mqs_pending_receives:
1260         DEBUG(VERBOSE_REQ,("setup the receive queue iterator\n"));
1261         opal_free_list_t_init_parser( proc, p_info, &extra->next_msg, extra->recv_queue_base );
1262         return mqs_ok;
1263 
1264     case mqs_unexpected_messages:  
1265         return mqs_no_information;
1266 
1267     default:
1268         return err_bad_request;
1269     }
1270 } 
1271 
1272 
1273 
1274 
1275 
1276 
1277 
1278 int mqs_next_operation (mqs_process *proc, mqs_pending_operation *op)
1279 {
1280     mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc);
1281     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
1282 
1283     switch (extra->what) {
1284     case mqs_pending_receives:
1285         DEBUG(VERBOSE_REQ,("digging for the receive queue\n"));
1286         return fetch_request( proc, p_info, op, TRUE );
1287     case mqs_unexpected_messages:
1288         
1289         return err_bad_request;
1290     case mqs_pending_sends:
1291         DEBUG(VERBOSE_REQ,("digging for the send queue\n"));
1292         return fetch_request( proc, p_info, op, FALSE );
1293     default: return err_bad_request;
1294     }
1295 } 
1296 
1297 
1298 
1299 
1300 void mqs_destroy_process_info (mqs_process_info *mp_info)
1301 {
1302     mpi_process_info *p_info = (mpi_process_info *)mp_info;
1303     mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra;
1304     
1305     communicator_t *comm;
1306 
1307     if( NULL != extra) {
1308         comm = extra->communicator_list;
1309         while (comm) {
1310             communicator_t *next = comm->next;
1311 
1312             if( NULL != comm->group )
1313                 group_decref (comm->group);  
1314             mqs_free (comm);
1315 
1316             comm = next;
1317         }
1318         if (NULL != extra) {
1319             mqs_free(extra);
1320         }
1321     }
1322     mqs_free (p_info);
1323 } 
1324 
1325 
1326 
1327 
1328 
1329 void mqs_destroy_image_info (mqs_image_info *info)
1330 {
1331     mqs_free (info);
1332 } 
1333 
1334 
1335 
1336 char * mqs_dll_error_string (int errcode)
1337 {
1338     switch (errcode) {
1339     case err_silent_failure:
1340         return "";
1341     case err_no_current_communicator:
1342         return "No current communicator in the communicator iterator";
1343     case err_bad_request:
1344         return "Attempting to setup to iterate over an unknown queue of operations";
1345     case err_no_store:
1346         return "Unable to allocate store";
1347     case err_failed_qhdr:
1348         return "Failed to find type MPID_QHDR";
1349     case err_unexpected:
1350         return "Failed to find field 'unexpected' in MPID_QHDR";
1351     case err_posted:
1352         return "Failed to find field 'posted' in MPID_QHDR";
1353     case err_failed_queue:
1354         return "Failed to find type MPID_QUEUE";
1355     case err_first:
1356         return "Failed to find field 'first' in MPID_QUEUE";
1357     case err_context_id:
1358         return "Failed to find field 'context_id' in MPID_QEL";
1359     case err_tag:
1360         return "Failed to find field 'tag' in MPID_QEL";
1361     case err_tagmask:
1362         return "Failed to find field 'tagmask' in MPID_QEL";
1363     case err_lsrc:
1364         return "Failed to find field 'lsrc' in MPID_QEL";
1365     case err_srcmask:
1366         return "Failed to find field 'srcmask' in MPID_QEL";
1367     case err_next:
1368         return "Failed to find field 'next' in MPID_QEL";
1369     case err_ptr:
1370         return "Failed to find field 'ptr' in MPID_QEL";
1371     case err_missing_type:
1372         return "Failed to find some type";
1373     case err_missing_symbol:
1374         return "Failed to find field the global symbol";
1375     case err_db_shandle:
1376         return "Failed to find field 'db_shandle' in MPIR_SQEL";
1377     case err_db_comm:
1378         return "Failed to find field 'db_comm' in MPIR_SQEL";
1379     case err_db_target:
1380         return "Failed to find field 'db_target' in MPIR_SQEL";
1381     case err_db_tag:
1382         return "Failed to find field 'db_tag' in MPIR_SQEL";
1383     case err_db_data:
1384         return "Failed to find field 'db_data' in MPIR_SQEL";
1385     case err_db_byte_length:
1386         return "Failed to find field 'db_byte_length' in MPIR_SQEL";
1387     case err_db_next:
1388         return "Failed to find field 'db_next' in MPIR_SQEL";
1389     case err_failed_rhandle:
1390         return "Failed to find type MPIR_RHANDLE";
1391     case err_is_complete:
1392         return "Failed to find field 'is_complete' in MPIR_RHANDLE";
1393     case err_buf:
1394         return "Failed to find field 'buf' in MPIR_RHANDLE";
1395     case err_len:
1396         return "Failed to find field 'len' in MPIR_RHANDLE";
1397     case err_s:
1398         return "Failed to find field 's' in MPIR_RHANDLE";
1399     case err_failed_status:
1400         return "Failed to find type MPI_Status";
1401     case err_count:
1402         return "Failed to find field 'count' in MPIR_Status";
1403     case err_MPI_SOURCE:
1404         return "Failed to find field 'MPI_SOURCE' in MPIR_Status";
1405     case err_MPI_TAG:
1406         return "Failed to find field 'MPI_TAG' in MPIR_Status";
1407     case err_failed_commlist:
1408         return "Failed to find type MPIR_Comm_list";
1409     case err_sequence_number:
1410         return "Failed to find field 'sequence_number' in MPIR_Comm_list";
1411     case err_comm_first:
1412         return "Failed to find field 'comm_first' in MPIR_Comm_list";
1413     case err_failed_communicator:
1414         return "Failed to find type MPIR_Communicator";
1415     case err_lrank_to_grank:
1416         return "Failed to find field 'lrank_to_grank' in MPIR_Communicator";
1417     case err_send_context:
1418         return "Failed to find field 'send_context' in MPIR_Communicator";
1419     case err_recv_context:
1420         return "Failed to find field 'recv_context' in MPIR_Communicator";
1421     case err_comm_next:
1422         return "Failed to find field 'comm_next' in MPIR_Communicator";
1423     case err_comm_name:
1424         return "Failed to find field 'comm_name' in MPIR_Communicator";
1425     case err_all_communicators:
1426         return "Failed to find the global symbol MPIR_All_communicators";
1427     case err_mpid_sends:
1428         return "Failed to access the global send requests list";
1429     case err_mpid_recvs:
1430         return "Failed to access the global receive requests list";
1431     case err_group_corrupt:
1432         return "Could not read a communicator's group from the process (probably a store corruption)";
1433 
1434     default: return "Unknown error code";
1435     }
1436 }