Commit 886b1d8d authored by Xin Zhao's avatar Xin Zhao
Browse files

Use window pool to manage lock requests

No reviewer.
parent 89d8f6c1
......@@ -19,35 +19,46 @@ MPIR_T_PVAR_DOUBLE_TIMER_DECL_EXTERN(RMA, rma_winlock_getlocallock);
#define FUNCNAME MPIDI_CH3I_Win_lock_entry_alloc
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
static inline int MPIDI_CH3I_Win_lock_entry_alloc(MPID_Win * win_ptr,
MPIDI_CH3_Pkt_t *pkt,
MPIDI_Win_lock_queue **lock_entry)
static inline MPIDI_Win_lock_queue *MPIDI_CH3I_Win_lock_entry_alloc(MPID_Win * win_ptr,
MPIDI_CH3_Pkt_t *pkt)
{
MPIDI_Win_lock_queue *new_ptr = NULL;
int mpi_errno = MPI_SUCCESS;
/* FIXME: we should use a lock entry queue to manage all this. */
if (win_ptr->lock_entry_pool != NULL) {
new_ptr = win_ptr->lock_entry_pool;
MPL_LL_DELETE(win_ptr->lock_entry_pool, win_ptr->lock_entry_pool_tail, new_ptr);
}
/* allocate lock queue entry */
MPIR_T_PVAR_TIMER_START(RMA, rma_lockqueue_alloc);
new_ptr = (MPIDI_Win_lock_queue *) MPIU_Malloc(sizeof(MPIDI_Win_lock_queue));
MPIR_T_PVAR_TIMER_END(RMA, rma_lockqueue_alloc);
if (!new_ptr) {
MPIU_ERR_SETANDJUMP1(mpi_errno, MPI_ERR_OTHER, "**nomem", "**nomem %s",
"MPIDI_Win_lock_queue");
if (new_ptr != NULL) {
new_ptr->next = NULL;
new_ptr->pkt = (*pkt);
new_ptr->data = NULL;
new_ptr->all_data_recved = 0;
}
new_ptr->next = NULL;
new_ptr->pkt = (*pkt);
new_ptr->data = NULL;
new_ptr->all_data_recved = 0;
return new_ptr;
}
/* MPIDI_CH3I_Win_lock_entry_free(): put a lock queue entry back to
* the global pool. */
#undef FUNCNAME
#define FUNCNAME MPIDI_CH3I_Win_lock_entry_free
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
static inline int MPIDI_CH3I_Win_lock_entry_free(MPID_Win * win_ptr,
MPIDI_Win_lock_queue *lock_entry)
{
int mpi_errno = MPI_SUCCESS;
if (lock_entry->data != NULL) {
MPIU_Free(lock_entry->data);
}
(*lock_entry) = new_ptr;
/* use PREPEND when return objects back to the pool
in order to improve cache performance */
MPL_LL_PREPEND(win_ptr->lock_entry_pool, win_ptr->lock_entry_pool_tail, lock_entry);
fn_exit:
return mpi_errno;
fn_fail:
goto fn_exit;
}
#endif /* MPID_RMA_ISSUE_H_INCLUDED */
......@@ -350,6 +350,9 @@ extern MPIDI_RMA_Pkt_orderings_t *MPIDI_RMA_Pkt_orderings;
int outstanding_locks; /* when issuing multiple lock requests in \
MPI_WIN_LOCK_ALL, this counter keeps track \
of number of locks not being granted yet. */ \
struct MPIDI_Win_lock_queue *lock_entry_pool_start; \
struct MPIDI_Win_lock_queue *lock_entry_pool; \
struct MPIDI_Win_lock_queue *lock_entry_pool_tail; \
#ifdef MPIDI_CH3_WIN_DECL
#define MPID_DEV_WIN_DECL \
......
......@@ -235,9 +235,11 @@ static inline int enqueue_lock_origin(MPID_Win *win_ptr, MPIDI_VC_t *vc,
(*reqp) = NULL;
mpi_errno = MPIDI_CH3I_Win_lock_entry_alloc(win_ptr, pkt, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
MPIU_Assert(new_ptr != NULL);
new_ptr = MPIDI_CH3I_Win_lock_entry_alloc(win_ptr, pkt);
if (new_ptr == NULL) {
/* FIXME: we run out of resources of lock requests, needs to
send LOCK DISCARDED packet back to origin */
}
MPL_LL_APPEND(win_ptr->lock_queue, win_ptr->lock_queue_tail, new_ptr);
if (pkt->type == MPIDI_CH3_PKT_LOCK ||
......@@ -386,9 +388,11 @@ static inline int acquire_local_lock(MPID_Win * win_ptr, int lock_type)
lock_pkt->lock_type = lock_type;
lock_pkt->origin_rank = win_ptr->comm_ptr->rank;
mpi_errno = MPIDI_CH3I_Win_lock_entry_alloc(win_ptr, &pkt, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
MPIU_Assert(new_ptr != NULL);
new_ptr = MPIDI_CH3I_Win_lock_entry_alloc(win_ptr, &pkt);
if (new_ptr == NULL) {
/* FIXME: we run out of resources of lock requests, needs to
send LOCK DISCARDED packet back to origin */
}
MPL_LL_APPEND(win_ptr->lock_queue, win_ptr->lock_queue_tail, new_ptr);
new_ptr->all_data_recved = 1;
......
......@@ -1417,13 +1417,12 @@ int MPIDI_CH3I_Release_lock(MPID_Win *win_ptr)
mpi_errno = perform_op_in_lock_queue(win_ptr, lock_entry);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
/* free data buffer in lock queue entry */
if (lock_entry->data != NULL)
MPIU_Free(lock_entry->data);
/* dequeue entry from lock queue */
MPL_LL_DELETE(win_ptr->lock_queue, win_ptr->lock_queue_tail, lock_entry);
MPIU_Free(lock_entry);
/* free this entry */
mpi_errno = MPIDI_CH3I_Win_lock_entry_free(win_ptr, lock_entry);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
/* if the granted lock is exclusive,
no need to continue */
......@@ -1482,13 +1481,12 @@ int MPIDI_CH3_ReqHandler_PiggybackLockOpRecvComplete( MPIDI_VC_t *vc,
mpi_errno = perform_op_in_lock_queue(win_ptr, lock_queue_entry);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
/* free data buffer in lock queue entry */
if (lock_queue_entry->data != NULL)
MPIU_Free(lock_queue_entry->data);
/* dequeue entry from lock queue */
MPL_LL_DELETE(win_ptr->lock_queue, win_ptr->lock_queue_tail, lock_queue_entry);
MPIU_Free(lock_queue_entry);
/* free this entry */
mpi_errno = MPIDI_CH3I_Win_lock_entry_free(win_ptr, lock_queue_entry);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
/* If try acquiring lock failed, just leave the lock queue entry in the queue with
all_data_recved marked as 1, release_lock() function will traverse the queue
......
......@@ -290,7 +290,7 @@ static int win_init(MPI_Aint size, int disp_unit, int create_flavor, int model,
MPID_Comm *win_comm_ptr;
int win_target_pool_size;
MPIDI_RMA_Win_list_t *win_elem;
MPIU_CHKPMEM_DECL(4);
MPIU_CHKPMEM_DECL(5);
MPIDI_STATE_DECL(MPID_STATE_WIN_INIT);
MPIDI_FUNC_ENTER(MPID_STATE_WIN_INIT);
......@@ -385,6 +385,18 @@ static int win_init(MPI_Aint size, int disp_unit, int create_flavor, int model,
(*win_ptr)->slots[i].target_list_tail = NULL;
}
/* FIXME: we can optimize by letting the user to pass WIN INFO hint if they will not use passive target,
in such case we do not need to allocate window pool for lock entries. */
MPIU_CHKPMEM_MALLOC((*win_ptr)->lock_entry_pool_start, struct MPIDI_Win_lock_queue *,
sizeof(MPIDI_Win_lock_queue) * MPIR_CVAR_CH3_RMA_LOCK_ENTRY_WIN_POOL_SIZE,
mpi_errno, "RMA lock entry pool");
(*win_ptr)->lock_entry_pool = NULL;
(*win_ptr)->lock_entry_pool_tail = NULL;
for (i = 0; i < MPIR_CVAR_CH3_RMA_LOCK_ENTRY_WIN_POOL_SIZE; i++) {
MPL_LL_APPEND((*win_ptr)->lock_entry_pool, (*win_ptr)->lock_entry_pool_tail,
&((*win_ptr)->lock_entry_pool_start[i]));
}
MPID_WIN_FTABLE_SET_DEFAULTS(win_ptr);
/* enqueue window into the global list */
......
......@@ -63,6 +63,30 @@ cvars:
targets) that stores information about RMA targets that
could not be issued immediatly. Requires a positive value.
- name : MPIR_CVAR_CH3_RMA_LOCK_ENTRY_WIN_POOL_SIZE
category : CH3
type : int
default : 256
class : none
verbosity : MPI_T_VERBOSITY_USER_BASIC
scope : MPI_T_SCOPE_ALL_EQ
description : >-
Size of the window-private RMA lock entries pool (in number of
lock entries) that stores information about RMA lock requests that
could not be satisfied immediatly. Requires a positive value.
- name : MPIR_CVAR_CH3_RMA_LOCK_ENTRY_GLOBAL_POOL_SIZE
category : CH3
type : int
default : 16384
class : none
verbosity : MPI_T_VERBOSITY_USER_BASIC
scope : MPI_T_SCOPE_ALL_EQ
description : >-
Size of the Global RMA lock entries pool (in number of
lock entries) that stores information about RMA lock requests that
could not be satisfied immediatly. Requires a positive value.
=== END_MPI_T_CVAR_INFO_BLOCK ===
*/
......@@ -214,6 +238,7 @@ int MPIDI_Win_free(MPID_Win ** win_ptr)
MPIU_Free((*win_ptr)->op_pool_start);
MPIU_Free((*win_ptr)->target_pool_start);
MPIU_Free((*win_ptr)->slots);
MPIU_Free((*win_ptr)->lock_entry_pool_start);
/* Free the attached buffer for windows created with MPI_Win_allocate() */
if ((*win_ptr)->create_flavor == MPI_WIN_FLAVOR_ALLOCATE ||
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment