X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/c5a48995c0e24c9ae38c3d14203388523c565a5b..3aa62b6a4755ba871847a5f86473c0e651c9d661:/src/smpi/smpi_win.cpp diff --git a/src/smpi/smpi_win.cpp b/src/smpi/smpi_win.cpp index 9333f02732..f5e573dfb8 100644 --- a/src/smpi/smpi_win.cpp +++ b/src/smpi/smpi_win.cpp @@ -32,6 +32,7 @@ Win::Win(void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm) if(rank_==0){ bar_ = MSG_barrier_init(comm_size); } + mode_=0; comm->add_rma_win(this); @@ -273,14 +274,15 @@ int Win::accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_da void* recv_addr = static_cast(static_cast(recv_win->base_) + target_disp * recv_win->disp_unit_); XBT_DEBUG("Entering MPI_Accumulate to %d", target_rank); - //As the tag will be used for ordering of the operations, add count to it + //As the tag will be used for ordering of the operations, substract count from it (to avoid collisions with other SMPI tags, SMPI_RMA_TAG is set below all the other ones we use ) //prepare send_request + MPI_Request sreq = Request::rma_send_init(origin_addr, origin_count, origin_datatype, - smpi_process()->index(), comm_->group()->index(target_rank), SMPI_RMA_TAG+3+count_, comm_, op); + smpi_process()->index(), comm_->group()->index(target_rank), SMPI_RMA_TAG-3-count_, comm_, op); //prepare receiver request MPI_Request rreq = Request::rma_recv_init(recv_addr, target_count, target_datatype, - smpi_process()->index(), comm_->group()->index(target_rank), SMPI_RMA_TAG+3+count_, recv_win->comm_, op); + smpi_process()->index(), comm_->group()->index(target_rank), SMPI_RMA_TAG-3-count_, recv_win->comm_, op); count_++; //push request to receiver's win @@ -435,34 +437,43 @@ int Win::wait(){ } int Win::lock(int lock_type, int rank, int assert){ - MPI_Win target_win = connected_wins_[rank]; + if(opened_!=0) + return MPI_ERR_WIN; - int finished = finish_comms(); - XBT_DEBUG("Win_lock - Finished %d RMA calls", finished); + MPI_Win target_win = connected_wins_[rank]; - //window already locked, we have to wait - if (lock_type == MPI_LOCK_EXCLUSIVE) + if ((lock_type == MPI_LOCK_EXCLUSIVE && target_win->mode_ != MPI_LOCK_SHARED)|| target_win->mode_ == MPI_LOCK_EXCLUSIVE){ xbt_mutex_acquire(target_win->lock_mut_); + target_win->mode_+= lock_type;//add the lock_type to differentiate case when we are switching from EXCLUSIVE to SHARED (no release needed in the unlock) + if(lock_type == MPI_LOCK_SHARED){//the window used to be exclusive, it's now shared. + xbt_mutex_release(target_win->lock_mut_); + } + } else if(!(target_win->mode_==MPI_LOCK_SHARED && lock_type == MPI_LOCK_EXCLUSIVE)) + target_win->mode_+= lock_type; // don't set to exclusive if it's already shared - xbt_mutex_acquire(target_win->mut_); target_win->lockers_.push_back(comm_->rank()); - xbt_mutex_release(target_win->mut_); + + int finished = finish_comms(); + XBT_DEBUG("Win_lock %d - Finished %d RMA calls", rank, finished); return MPI_SUCCESS; } int Win::unlock(int rank){ + if(opened_!=0) + return MPI_ERR_WIN; + MPI_Win target_win = connected_wins_[rank]; + int target_mode = target_win->mode_; + target_win->mode_= 0; + target_win->lockers_.remove(comm_->rank()); + if (target_mode==MPI_LOCK_EXCLUSIVE){ + xbt_mutex_release(target_win->lock_mut_); + } int finished = finish_comms(); - XBT_DEBUG("Win_unlock - Finished %d RMA calls", finished); - - xbt_mutex_acquire(target_win->mut_); - target_win->lockers_.remove(comm_->rank()); - xbt_mutex_release(target_win->mut_); + XBT_DEBUG("Win_unlock %d - Finished %d RMA calls", rank, finished); - xbt_mutex_try_acquire(target_win->lock_mut_); - xbt_mutex_release(target_win->lock_mut_); return MPI_SUCCESS; } @@ -472,11 +483,11 @@ Win* Win::f2c(int id){ int Win::finish_comms(){ + xbt_mutex_acquire(mut_); //Finish own requests std::vector *reqqs = requests_; int size = static_cast(reqqs->size()); if (size > 0) { - xbt_mutex_acquire(mut_); // start all requests that have been prepared by another process for (const auto& req : *reqqs) { if (req && (req->flags() & PREPARED)) @@ -486,9 +497,8 @@ int Win::finish_comms(){ MPI_Request* treqs = &(*reqqs)[0]; Request::waitall(size, treqs, MPI_STATUSES_IGNORE); reqqs->clear(); - xbt_mutex_release(mut_); } - + xbt_mutex_release(mut_); return size; }