This source file includes following definitions.
- ompi_osc_pt2pt_peer_locked
- ompi_osc_pt2pt_peer_unex
- ompi_osc_pt2pt_peer_eager_active
- ompi_osc_pt2pt_peer_set_flag
- ompi_osc_pt2pt_peer_set_locked
- ompi_osc_pt2pt_peer_set_unex
- ompi_osc_pt2pt_peer_set_eager_active
- ompi_osc_pt2pt_peer_lookup
- mark_incoming_completion
- mark_outgoing_completion
- ompi_osc_signal_outgoing
- osc_pt2pt_copy_on_recv
- osc_pt2pt_copy_for_send
- osc_pt2pt_gc_clean
- osc_pt2pt_gc_add_buffer
- osc_pt2pt_add_pending
- get_tag
- tag_to_target
- tag_to_origin
- ompi_osc_pt2pt_accumulate_lock
- ompi_osc_pt2pt_accumulate_trylock
- ompi_osc_pt2pt_in_passive_epoch
- ompi_osc_pt2pt_accumulate_unlock
- ompi_osc_pt2pt_module_lock_find
- ompi_osc_pt2pt_module_lock_insert
- ompi_osc_pt2pt_module_lock_remove
- ompi_osc_pt2pt_module_sync_lookup
- ompi_osc_pt2pt_access_epoch_active
- ompi_osc_pt2pt_peer_sends_active
   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 #ifndef OMPI_OSC_PT2PT_H
  27 #define OMPI_OSC_PT2PT_H
  28 
  29 #include "ompi_config.h"
  30 #include "opal/class/opal_list.h"
  31 #include "opal/class/opal_free_list.h"
  32 #include "opal/class/opal_hash_table.h"
  33 #include "opal/threads/threads.h"
  34 #include "opal/util/output.h"
  35 
  36 #include "ompi/win/win.h"
  37 #include "ompi/info/info.h"
  38 #include "ompi/communicator/communicator.h"
  39 #include "ompi/datatype/ompi_datatype.h"
  40 #include "ompi/request/request.h"
  41 #include "ompi/mca/osc/osc.h"
  42 #include "ompi/mca/osc/base/base.h"
  43 #include "ompi/memchecker.h"
  44 
  45 #include "osc_pt2pt_header.h"
  46 #include "osc_pt2pt_sync.h"
  47 
  48 BEGIN_C_DECLS
  49 
  50 struct ompi_osc_pt2pt_frag_t;
  51 struct ompi_osc_pt2pt_receive_t;
  52 
  53 struct ompi_osc_pt2pt_component_t {
  54     
  55     ompi_osc_base_component_t super;
  56 
  57     
  58     opal_mutex_t lock;
  59 
  60     
  61     opal_hash_table_t modules;
  62 
  63     
  64     int module_count;
  65 
  66     
  67     int receive_count;
  68 
  69     
  70     opal_free_list_t frags;
  71 
  72     
  73     opal_free_list_t requests;
  74 
  75     
  76     unsigned int buffer_size;
  77 
  78     
  79     opal_mutex_t pending_operations_lock;
  80 
  81     
  82     opal_list_t pending_operations;
  83 
  84     
  85     opal_list_t pending_receives;
  86 
  87     
  88     opal_mutex_t pending_receives_lock;
  89 
  90     
  91     bool progress_enable;
  92 };
  93 typedef struct ompi_osc_pt2pt_component_t ompi_osc_pt2pt_component_t;
  94 
  95 enum {
  96     
  97     OMPI_OSC_PT2PT_PEER_FLAG_UNEX = 1,
  98     
  99     OMPI_OSC_PT2PT_PEER_FLAG_EAGER = 2,
 100     
 101     OMPI_OSC_PT2PT_PEER_FLAG_LOCK = 4,
 102 };
 103 
 104 
 105 struct ompi_osc_pt2pt_peer_t {
 106     
 107     opal_object_t super;
 108 
 109     
 110     int rank;
 111 
 112     
 113     opal_atomic_intptr_t active_frag;
 114 
 115     
 116     opal_mutex_t lock;
 117 
 118     
 119     opal_list_t queued_frags;
 120 
 121     
 122     opal_atomic_int32_t passive_incoming_frag_count;
 123 
 124     
 125     opal_atomic_int32_t flags;
 126 };
 127 typedef struct ompi_osc_pt2pt_peer_t ompi_osc_pt2pt_peer_t;
 128 
 129 OBJ_CLASS_DECLARATION(ompi_osc_pt2pt_peer_t);
 130 
 131 static inline bool ompi_osc_pt2pt_peer_locked (ompi_osc_pt2pt_peer_t *peer)
 132 {
 133     return !!(peer->flags & OMPI_OSC_PT2PT_PEER_FLAG_LOCK);
 134 }
 135 
 136 static inline bool ompi_osc_pt2pt_peer_unex (ompi_osc_pt2pt_peer_t *peer)
 137 {
 138     return !!(peer->flags & OMPI_OSC_PT2PT_PEER_FLAG_UNEX);
 139 }
 140 
 141 static inline bool ompi_osc_pt2pt_peer_eager_active (ompi_osc_pt2pt_peer_t *peer)
 142 {
 143     return !!(peer->flags & OMPI_OSC_PT2PT_PEER_FLAG_EAGER);
 144 }
 145 
 146 static inline void ompi_osc_pt2pt_peer_set_flag (ompi_osc_pt2pt_peer_t *peer, int32_t flag, bool value)
 147 {
 148     if (value) {
 149         OPAL_ATOMIC_OR_FETCH32 (&peer->flags, flag);
 150     } else {
 151         OPAL_ATOMIC_AND_FETCH32 (&peer->flags, ~flag);
 152     }
 153 }
 154 
 155 static inline void ompi_osc_pt2pt_peer_set_locked (ompi_osc_pt2pt_peer_t *peer, bool value)
 156 {
 157     ompi_osc_pt2pt_peer_set_flag (peer, OMPI_OSC_PT2PT_PEER_FLAG_LOCK, value);
 158 }
 159 
 160 static inline void ompi_osc_pt2pt_peer_set_unex (ompi_osc_pt2pt_peer_t *peer, bool value)
 161 {
 162     ompi_osc_pt2pt_peer_set_flag (peer, OMPI_OSC_PT2PT_PEER_FLAG_UNEX, value);
 163 }
 164 
 165 static inline void ompi_osc_pt2pt_peer_set_eager_active (ompi_osc_pt2pt_peer_t *peer, bool value)
 166 {
 167     ompi_osc_pt2pt_peer_set_flag (peer, OMPI_OSC_PT2PT_PEER_FLAG_EAGER, value);
 168 }
 169 
 170 OBJ_CLASS_DECLARATION(ompi_osc_pt2pt_peer_t);
 171 
 172 
 173 
 174 struct ompi_osc_pt2pt_module_t {
 175     
 176     ompi_osc_base_module_t super;
 177 
 178     
 179     bool accumulate_ordering;
 180 
 181     
 182     bool no_locks;
 183 
 184     
 185     void *free_after;
 186 
 187     
 188     void *baseptr;
 189 
 190     
 191 
 192     ompi_communicator_t *comm;
 193 
 194     
 195     int disp_unit;
 196 
 197     
 198     opal_recursive_mutex_t lock;
 199 
 200     
 201     opal_condition_t cond;
 202 
 203     
 204     opal_hash_table_t peer_hash;
 205 
 206     
 207     opal_mutex_t peer_lock;
 208 
 209     
 210 
 211     opal_atomic_uint32_t *epoch_outgoing_frag_count;
 212 
 213     
 214     opal_atomic_uint32_t tag_counter;
 215 
 216     
 217     opal_atomic_int32_t outgoing_frag_count;
 218 
 219     
 220     opal_atomic_int32_t active_incoming_frag_count;
 221 
 222     
 223     unsigned int passive_target_access_epoch;
 224 
 225     
 226     ompi_osc_pt2pt_sync_t all_sync;
 227 
 228     
 229     struct ompi_group_t *pw_group;
 230 
 231     
 232 
 233     opal_atomic_int32_t num_complete_msgs;
 234 
 235     
 236 
 237     
 238 
 239     opal_atomic_int32_t lock_status;
 240 
 241     
 242     opal_mutex_t locks_pending_lock;
 243 
 244     
 245     opal_list_t locks_pending;
 246 
 247     
 248     opal_hash_table_t outstanding_locks;
 249 
 250     
 251     struct ompi_osc_pt2pt_receive_t *recv_frags;
 252 
 253     
 254     unsigned int recv_frag_count;
 255 
 256     
 257     opal_atomic_lock_t accumulate_lock;
 258 
 259     
 260     opal_list_t pending_acc;
 261 
 262     
 263     opal_mutex_t pending_acc_lock;
 264 
 265     
 266     opal_mutex_t gc_lock;
 267 
 268     
 269     opal_list_t buffer_gc;
 270 };
 271 typedef struct ompi_osc_pt2pt_module_t ompi_osc_pt2pt_module_t;
 272 OMPI_MODULE_DECLSPEC extern ompi_osc_pt2pt_component_t mca_osc_pt2pt_component;
 273 
 274 static inline ompi_osc_pt2pt_peer_t *ompi_osc_pt2pt_peer_lookup (ompi_osc_pt2pt_module_t *module,
 275                                                                  int rank)
 276 {
 277     ompi_osc_pt2pt_peer_t *peer = NULL;
 278     (void) opal_hash_table_get_value_uint32 (&module->peer_hash, rank, (void **) &peer);
 279 
 280     if (OPAL_UNLIKELY(NULL == peer)) {
 281         OPAL_THREAD_LOCK(&module->peer_lock);
 282         (void) opal_hash_table_get_value_uint32 (&module->peer_hash, rank, (void **) &peer);
 283 
 284         if (NULL == peer) {
 285             peer = OBJ_NEW(ompi_osc_pt2pt_peer_t);
 286             peer->rank = rank;
 287 
 288             (void) opal_hash_table_set_value_uint32 (&module->peer_hash, rank, (void *) peer);
 289         }
 290         OPAL_THREAD_UNLOCK(&module->peer_lock);
 291     }
 292 
 293     return peer;
 294 }
 295 
 296 
 297 struct ompi_osc_pt2pt_pending_t {
 298     opal_list_item_t super;
 299     ompi_osc_pt2pt_module_t *module;
 300     int source;
 301     ompi_osc_pt2pt_header_t header;
 302 };
 303 typedef struct ompi_osc_pt2pt_pending_t ompi_osc_pt2pt_pending_t;
 304 OBJ_CLASS_DECLARATION(ompi_osc_pt2pt_pending_t);
 305 
 306 struct ompi_osc_pt2pt_receive_t {
 307     opal_list_item_t super;
 308     ompi_osc_pt2pt_module_t *module;
 309     ompi_request_t *pml_request;
 310     void *buffer;
 311 };
 312 typedef struct ompi_osc_pt2pt_receive_t ompi_osc_pt2pt_receive_t;
 313 OBJ_CLASS_DECLARATION(ompi_osc_pt2pt_receive_t);
 314 
 315 #define GET_MODULE(win) ((ompi_osc_pt2pt_module_t*) win->w_osc_module)
 316 
 317 extern bool ompi_osc_pt2pt_no_locks;
 318 
 319 int ompi_osc_pt2pt_attach(struct ompi_win_t *win, void *base, size_t len);
 320 int ompi_osc_pt2pt_detach(struct ompi_win_t *win, const void *base);
 321 
 322 int ompi_osc_pt2pt_free(struct ompi_win_t *win);
 323 
 324 int ompi_osc_pt2pt_put(const void *origin_addr,
 325                              int origin_count,
 326                              struct ompi_datatype_t *origin_dt,
 327                              int target,
 328                              ptrdiff_t target_disp,
 329                              int target_count,
 330                              struct ompi_datatype_t *target_dt,
 331                              struct ompi_win_t *win);
 332 
 333 int ompi_osc_pt2pt_accumulate(const void *origin_addr,
 334                               int origin_count,
 335                               struct ompi_datatype_t *origin_dt,
 336                               int target,
 337                               ptrdiff_t target_disp,
 338                               int target_count,
 339                               struct ompi_datatype_t *target_dt,
 340                               struct ompi_op_t *op,
 341                               struct ompi_win_t *win);
 342 
 343 int ompi_osc_pt2pt_get(void *origin_addr,
 344                        int origin_count,
 345                        struct ompi_datatype_t *origin_dt,
 346                        int target,
 347                        ptrdiff_t target_disp,
 348                        int target_count,
 349                        struct ompi_datatype_t *target_dt,
 350                        struct ompi_win_t *win);
 351 
 352 int ompi_osc_pt2pt_compare_and_swap(const void *origin_addr,
 353                                    const void *compare_addr,
 354                                    void *result_addr,
 355                                    struct ompi_datatype_t *dt,
 356                                    int target,
 357                                    ptrdiff_t target_disp,
 358                                    struct ompi_win_t *win);
 359 
 360 int ompi_osc_pt2pt_fetch_and_op(const void *origin_addr,
 361                                void *result_addr,
 362                                struct ompi_datatype_t *dt,
 363                                int target,
 364                                ptrdiff_t target_disp,
 365                                struct ompi_op_t *op,
 366                                struct ompi_win_t *win);
 367 
 368 int ompi_osc_pt2pt_get_accumulate(const void *origin_addr,
 369                                  int origin_count,
 370                                  struct ompi_datatype_t *origin_datatype,
 371                                  void *result_addr,
 372                                  int result_count,
 373                                  struct ompi_datatype_t *result_datatype,
 374                                  int target_rank,
 375                                  MPI_Aint target_disp,
 376                                  int target_count,
 377                                  struct ompi_datatype_t *target_datatype,
 378                                  struct ompi_op_t *op,
 379                                  struct ompi_win_t *win);
 380 
 381 int ompi_osc_pt2pt_rput(const void *origin_addr,
 382                        int origin_count,
 383                        struct ompi_datatype_t *origin_dt,
 384                        int target,
 385                        ptrdiff_t target_disp,
 386                        int target_count,
 387                        struct ompi_datatype_t *target_dt,
 388                        struct ompi_win_t *win,
 389                        struct ompi_request_t **request);
 390 
 391 int ompi_osc_pt2pt_rget(void *origin_addr,
 392                        int origin_count,
 393                        struct ompi_datatype_t *origin_dt,
 394                        int target,
 395                        ptrdiff_t target_disp,
 396                        int target_count,
 397                        struct ompi_datatype_t *target_dt,
 398                        struct ompi_win_t *win,
 399                        struct ompi_request_t **request);
 400 
 401 int ompi_osc_pt2pt_raccumulate(const void *origin_addr,
 402                               int origin_count,
 403                               struct ompi_datatype_t *origin_dt,
 404                               int target,
 405                               ptrdiff_t target_disp,
 406                               int target_count,
 407                               struct ompi_datatype_t *target_dt,
 408                               struct ompi_op_t *op,
 409                               struct ompi_win_t *win,
 410                               struct ompi_request_t **request);
 411 
 412 int ompi_osc_pt2pt_rget_accumulate(const void *origin_addr,
 413                                   int origin_count,
 414                                   struct ompi_datatype_t *origin_datatype,
 415                                   void *result_addr,
 416                                   int result_count,
 417                                   struct ompi_datatype_t *result_datatype,
 418                                   int target_rank,
 419                                   MPI_Aint target_disp,
 420                                   int target_count,
 421                                   struct ompi_datatype_t *target_datatype,
 422                                   struct ompi_op_t *op,
 423                                   struct ompi_win_t *win,
 424                                   struct ompi_request_t **request);
 425 
 426 int ompi_osc_pt2pt_fence(int assert, struct ompi_win_t *win);
 427 
 428 
 429 void osc_pt2pt_incoming_post (ompi_osc_pt2pt_module_t *module, int source);
 430 
 431 
 432 void osc_pt2pt_incoming_complete (ompi_osc_pt2pt_module_t *module, int source, int frag_count);
 433 
 434 int ompi_osc_pt2pt_start(struct ompi_group_t *group,
 435                         int assert,
 436                         struct ompi_win_t *win);
 437 int ompi_osc_pt2pt_complete(struct ompi_win_t *win);
 438 
 439 int ompi_osc_pt2pt_post(struct ompi_group_t *group,
 440                               int assert,
 441                               struct ompi_win_t *win);
 442 
 443 int ompi_osc_pt2pt_wait(struct ompi_win_t *win);
 444 
 445 int ompi_osc_pt2pt_test(struct ompi_win_t *win,
 446                               int *flag);
 447 
 448 int ompi_osc_pt2pt_lock(int lock_type,
 449                               int target,
 450                               int assert,
 451                               struct ompi_win_t *win);
 452 
 453 int ompi_osc_pt2pt_unlock(int target,
 454                                 struct ompi_win_t *win);
 455 
 456 int ompi_osc_pt2pt_lock_all(int assert,
 457                            struct ompi_win_t *win);
 458 
 459 int ompi_osc_pt2pt_unlock_all(struct ompi_win_t *win);
 460 
 461 int ompi_osc_pt2pt_sync(struct ompi_win_t *win);
 462 
 463 int ompi_osc_pt2pt_flush(int target,
 464                         struct ompi_win_t *win);
 465 int ompi_osc_pt2pt_flush_all(struct ompi_win_t *win);
 466 int ompi_osc_pt2pt_flush_local(int target,
 467                               struct ompi_win_t *win);
 468 int ompi_osc_pt2pt_flush_local_all(struct ompi_win_t *win);
 469 
 470 int ompi_osc_pt2pt_set_info(struct ompi_win_t *win, struct opal_info_t *info);
 471 int ompi_osc_pt2pt_get_info(struct ompi_win_t *win, struct opal_info_t **info_used);
 472 
 473 int ompi_osc_pt2pt_component_irecv(ompi_osc_pt2pt_module_t *module,
 474                                   void *buf,
 475                                   size_t count,
 476                                   struct ompi_datatype_t *datatype,
 477                                   int src,
 478                                   int tag,
 479                                   struct ompi_communicator_t *comm);
 480 
 481 int ompi_osc_pt2pt_lock_remote (ompi_osc_pt2pt_module_t *module, int target, ompi_osc_pt2pt_sync_t *lock);
 482 
 483 
 484 
 485 
 486 
 487 
 488 
 489 
 490 
 491 
 492 
 493 int ompi_osc_pt2pt_progress_pending_acc (ompi_osc_pt2pt_module_t *module);
 494 
 495 
 496 
 497 
 498 
 499 
 500 
 501 
 502 
 503 
 504 
 505 
 506 
 507 
 508 
 509 static inline void mark_incoming_completion (ompi_osc_pt2pt_module_t *module, int source)
 510 {
 511     int32_t new_value;
 512 
 513     if (MPI_PROC_NULL == source) {
 514         OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output,
 515                              "mark_incoming_completion marking active incoming complete. module %p, count = %d",
 516                              (void *) module, (int) module->active_incoming_frag_count + 1));
 517         new_value = OPAL_THREAD_ADD_FETCH32(&module->active_incoming_frag_count, 1);
 518         if (new_value >= 0) {
 519             OPAL_THREAD_LOCK(&module->lock);
 520             opal_condition_broadcast(&module->cond);
 521             OPAL_THREAD_UNLOCK(&module->lock);
 522         }
 523     } else {
 524         ompi_osc_pt2pt_peer_t *peer = ompi_osc_pt2pt_peer_lookup (module, source);
 525 
 526         OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output,
 527                              "mark_incoming_completion marking passive incoming complete. module %p, source = %d, count = %d",
 528                              (void *) module, source, (int) peer->passive_incoming_frag_count + 1));
 529         new_value = OPAL_THREAD_ADD_FETCH32((opal_atomic_int32_t *) &peer->passive_incoming_frag_count, 1);
 530         if (0 == new_value) {
 531             OPAL_THREAD_LOCK(&module->lock);
 532             opal_condition_broadcast(&module->cond);
 533             OPAL_THREAD_UNLOCK(&module->lock);
 534         }
 535     }
 536 }
 537 
 538 
 539 
 540 
 541 
 542 
 543 
 544 
 545 
 546 
 547 
 548 
 549 
 550 
 551 static inline void mark_outgoing_completion (ompi_osc_pt2pt_module_t *module)
 552 {
 553     int32_t new_value = OPAL_THREAD_ADD_FETCH32((opal_atomic_int32_t *) &module->outgoing_frag_count, 1);
 554     OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output,
 555                          "mark_outgoing_completion: outgoing_frag_count = %d", new_value));
 556     if (new_value >= 0) {
 557         OPAL_THREAD_LOCK(&module->lock);
 558         opal_condition_broadcast(&module->cond);
 559         OPAL_THREAD_UNLOCK(&module->lock);
 560     }
 561 }
 562 
 563 
 564 
 565 
 566 
 567 
 568 
 569 
 570 
 571 
 572 
 573 
 574 
 575 static inline void ompi_osc_signal_outgoing (ompi_osc_pt2pt_module_t *module, int target, int count)
 576 {
 577     OPAL_THREAD_ADD_FETCH32((opal_atomic_int32_t *) &module->outgoing_frag_count, -count);
 578     if (MPI_PROC_NULL != target) {
 579         OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output,
 580                              "ompi_osc_signal_outgoing_passive: target = %d, count = %d, total = %d", target,
 581                              count, module->epoch_outgoing_frag_count[target] + count));
 582         OPAL_THREAD_ADD_FETCH32((opal_atomic_int32_t *) (module->epoch_outgoing_frag_count + target), count);
 583     }
 584 }
 585 
 586 
 587 
 588 
 589 
 590 
 591 
 592 
 593 
 594 
 595 
 596 
 597 
 598 
 599 
 600 
 601 
 602 
 603 static inline void osc_pt2pt_copy_on_recv (void *target, void *source, size_t source_len, ompi_proc_t *proc,
 604                                           int count, ompi_datatype_t *datatype)
 605 {
 606     opal_convertor_t convertor;
 607     uint32_t iov_count = 1;
 608     struct iovec iov;
 609     size_t max_data;
 610 
 611     
 612     OBJ_CONSTRUCT(&convertor, opal_convertor_t);
 613 
 614     
 615     opal_convertor_copy_and_prepare_for_recv(proc->super.proc_convertor, &datatype->super, count, target,
 616                                              0, &convertor);
 617 
 618     iov.iov_len  = source_len;
 619     iov.iov_base = (IOVBASE_TYPE *) source;
 620     max_data     = iov.iov_len;
 621     MEMCHECKER(memchecker_convertor_call(&opal_memchecker_base_mem_defined, &convertor));
 622 
 623     opal_convertor_unpack (&convertor, &iov, &iov_count, &max_data);
 624 
 625     MEMCHECKER(memchecker_convertor_call(&opal_memchecker_base_mem_noaccess, &convertor));
 626 
 627     OBJ_DESTRUCT(&convertor);
 628 }
 629 
 630 
 631 
 632 
 633 
 634 
 635 
 636 
 637 
 638 
 639 
 640 
 641 
 642 
 643 
 644 
 645 
 646 
 647 static inline void osc_pt2pt_copy_for_send (void *target, size_t target_len, const void *source, ompi_proc_t *proc,
 648                                            int count, ompi_datatype_t *datatype)
 649 {
 650     opal_convertor_t convertor;
 651     uint32_t iov_count = 1;
 652     struct iovec iov;
 653     size_t max_data;
 654 
 655     OBJ_CONSTRUCT(&convertor, opal_convertor_t);
 656 
 657     opal_convertor_copy_and_prepare_for_send(proc->super.proc_convertor, &datatype->super,
 658                                              count, source, 0, &convertor);
 659 
 660     iov.iov_len = target_len;
 661     iov.iov_base = (IOVBASE_TYPE *) target;
 662     opal_convertor_pack(&convertor, &iov, &iov_count, &max_data);
 663 
 664     OBJ_DESTRUCT(&convertor);
 665 }
 666 
 667 
 668 
 669 
 670 
 671 
 672 
 673 
 674 
 675 
 676 static inline void osc_pt2pt_gc_clean (ompi_osc_pt2pt_module_t *module)
 677 {
 678     opal_list_item_t *item;
 679 
 680     OPAL_THREAD_LOCK(&module->gc_lock);
 681     while (NULL != (item = opal_list_remove_first (&module->buffer_gc))) {
 682         OBJ_RELEASE(item);
 683     }
 684     OPAL_THREAD_UNLOCK(&module->gc_lock);
 685 }
 686 
 687 static inline void osc_pt2pt_gc_add_buffer (ompi_osc_pt2pt_module_t *module, opal_list_item_t *buffer)
 688 {
 689     OPAL_THREAD_SCOPED_LOCK(&module->gc_lock,
 690                             opal_list_append (&module->buffer_gc, buffer));
 691 }
 692 
 693 static inline void osc_pt2pt_add_pending (ompi_osc_pt2pt_pending_t *pending)
 694 {
 695     OPAL_THREAD_SCOPED_LOCK(&mca_osc_pt2pt_component.pending_operations_lock,
 696                             opal_list_append (&mca_osc_pt2pt_component.pending_operations, &pending->super));
 697 }
 698 
 699 #define OSC_PT2PT_FRAG_TAG   0x10000
 700 #define OSC_PT2PT_FRAG_MASK  0x0ffff
 701 
 702 
 703 
 704 
 705 
 706 
 707 
 708 
 709 
 710 
 711 
 712 
 713 
 714 
 715 static inline int get_tag(ompi_osc_pt2pt_module_t *module)
 716 {
 717     
 718 
 719 
 720     int32_t tmp = OPAL_THREAD_ADD_FETCH32((opal_atomic_int32_t *) &module->tag_counter, 4);
 721     return (tmp & OSC_PT2PT_FRAG_MASK) | !!(module->passive_target_access_epoch);
 722 }
 723 
 724 
 725 
 726 
 727 
 728 
 729 
 730 
 731 static inline int tag_to_target(int tag)
 732 {
 733     
 734     return tag + 0;
 735 }
 736 
 737 
 738 
 739 
 740 
 741 
 742 
 743 
 744 static inline int tag_to_origin(int tag)
 745 {
 746     
 747     return tag + 2;
 748 }
 749 
 750 
 751 
 752 
 753 
 754 
 755 
 756 
 757 
 758 
 759 
 760 
 761 
 762 
 763 
 764 
 765 
 766 static inline int ompi_osc_pt2pt_accumulate_lock (ompi_osc_pt2pt_module_t *module)
 767 {
 768     while (opal_atomic_trylock (&module->accumulate_lock)) {
 769         opal_progress ();
 770     }
 771 
 772     return 0;
 773 }
 774 
 775 
 776 
 777 
 778 
 779 
 780 
 781 
 782 
 783 
 784 
 785 
 786 
 787 
 788 static inline int ompi_osc_pt2pt_accumulate_trylock (ompi_osc_pt2pt_module_t *module)
 789 {
 790     return opal_atomic_trylock (&module->accumulate_lock);
 791 }
 792 
 793 
 794 
 795 
 796 
 797 
 798 static inline bool ompi_osc_pt2pt_in_passive_epoch (ompi_osc_pt2pt_module_t *module)
 799 {
 800     return 0 != module->passive_target_access_epoch;
 801 }
 802 
 803 
 804 
 805 
 806 
 807 
 808 
 809 
 810 
 811 
 812 
 813 static inline void ompi_osc_pt2pt_accumulate_unlock (ompi_osc_pt2pt_module_t *module)
 814 {
 815     opal_atomic_unlock (&module->accumulate_lock);
 816     if (0 != opal_list_get_size (&module->pending_acc)) {
 817         ompi_osc_pt2pt_progress_pending_acc (module);
 818     }
 819 }
 820 
 821 
 822 
 823 
 824 
 825 
 826 
 827 
 828 
 829 
 830 
 831 
 832 static inline ompi_osc_pt2pt_sync_t *ompi_osc_pt2pt_module_lock_find (ompi_osc_pt2pt_module_t *module, int target,
 833                                                                       ompi_osc_pt2pt_peer_t **peer)
 834 {
 835     ompi_osc_pt2pt_sync_t *outstanding_lock = NULL;
 836 
 837     (void) opal_hash_table_get_value_uint32 (&module->outstanding_locks, (uint32_t) target, (void **) &outstanding_lock);
 838     if (NULL != outstanding_lock && peer) {
 839         *peer = outstanding_lock->peer_list.peer;
 840     }
 841 
 842     return outstanding_lock;
 843 }
 844 
 845 
 846 
 847 
 848 
 849 
 850 
 851 
 852 
 853 
 854 static inline void ompi_osc_pt2pt_module_lock_insert (struct ompi_osc_pt2pt_module_t *module, ompi_osc_pt2pt_sync_t *lock)
 855 {
 856     (void) opal_hash_table_set_value_uint32 (&module->outstanding_locks, (uint32_t) lock->sync.lock.target, (void *) lock);
 857 }
 858 
 859 
 860 
 861 
 862 
 863 
 864 
 865 
 866 
 867 
 868 
 869 static inline void ompi_osc_pt2pt_module_lock_remove (struct ompi_osc_pt2pt_module_t *module, ompi_osc_pt2pt_sync_t *lock)
 870 {
 871 
 872     (void) opal_hash_table_remove_value_uint32 (&module->outstanding_locks, (uint32_t) lock->sync.lock.target);
 873 }
 874 
 875 
 876 
 877 
 878 
 879 
 880 
 881 
 882 
 883 
 884 
 885 
 886 
 887 
 888 static inline ompi_osc_pt2pt_sync_t *ompi_osc_pt2pt_module_sync_lookup (ompi_osc_pt2pt_module_t *module, int target,
 889                                                                         struct ompi_osc_pt2pt_peer_t **peer)
 890 {
 891     ompi_osc_pt2pt_peer_t *tmp;
 892 
 893     if (NULL == peer) {
 894         peer = &tmp;
 895     }
 896 
 897     OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output,
 898                          "osc/pt2pt: looking for synchronization object for target %d", target));
 899 
 900     switch (module->all_sync.type) {
 901     case OMPI_OSC_PT2PT_SYNC_TYPE_NONE:
 902         if (!module->no_locks) {
 903             return ompi_osc_pt2pt_module_lock_find (module, target, peer);
 904         }
 905 
 906         return NULL;
 907     case OMPI_OSC_PT2PT_SYNC_TYPE_FENCE:
 908     case OMPI_OSC_PT2PT_SYNC_TYPE_LOCK:
 909         OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output,
 910                              "osc/pt2pt: found fence/lock_all access epoch for target %d", target));
 911 
 912         
 913         module->all_sync.epoch_active = true;
 914         *peer = ompi_osc_pt2pt_peer_lookup (module, target);
 915         if (OMPI_OSC_PT2PT_SYNC_TYPE_LOCK == module->all_sync.type && !ompi_osc_pt2pt_peer_locked (*peer)) {
 916             (void) ompi_osc_pt2pt_lock_remote (module, target, &module->all_sync);
 917         }
 918 
 919         return &module->all_sync;
 920     case OMPI_OSC_PT2PT_SYNC_TYPE_PSCW:
 921         if (ompi_osc_pt2pt_sync_pscw_peer (module, target, peer)) {
 922             OPAL_OUTPUT_VERBOSE((50, ompi_osc_base_framework.framework_output,
 923                                  "osc/pt2pt: found PSCW access epoch target for %d", target));
 924             return &module->all_sync;
 925         }
 926     }
 927 
 928     return NULL;
 929 }
 930 
 931 
 932 
 933 
 934 
 935 
 936 
 937 
 938 
 939 
 940 
 941 static inline bool ompi_osc_pt2pt_access_epoch_active (ompi_osc_pt2pt_module_t *module)
 942 {
 943     return (module->all_sync.epoch_active || ompi_osc_pt2pt_in_passive_epoch (module));
 944 }
 945 
 946 static inline bool ompi_osc_pt2pt_peer_sends_active (ompi_osc_pt2pt_module_t *module, int rank)
 947 {
 948     ompi_osc_pt2pt_sync_t *sync;
 949     ompi_osc_pt2pt_peer_t *peer;
 950 
 951     sync = ompi_osc_pt2pt_module_sync_lookup (module, rank, &peer);
 952     if (!sync) {
 953         return false;
 954     }
 955 
 956     return sync->eager_send_active || ompi_osc_pt2pt_peer_eager_active (peer);
 957 }
 958 
 959 END_C_DECLS
 960 
 961 #endif