⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsendutil.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    MPIR_Nest_decr();        if (!p) {	/* Return error for no buffer space found */	/* Generate a traceback of the allocated space, explaining why	   packsize could not be found */	MPIU_DBG_MSG(BSEND,TYPICAL,"Could not find space; dumping arena" );	MPIU_DBG_STMT(BSEND,TYPICAL,MPIR_Bsend_dump());	return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIR_Bsend_isend", __LINE__, MPI_ERR_BUFFER, "**bufbsend", 				     "**bufbsend %d %d", packsize, 				     BsendBuffer.buffer_size );    }    else {	return MPI_SUCCESS;    }}/* * The following routines are used to manage the allocation of bsend segments * in the user buffer.  These routines handle, for example, merging segments * when an active segment that is adjacent to a free segment becomes free. * *//* Add block p to the free list. Merge into adjacent blocks.  Used only    within the check_active *//* begin:nested */static void MPIR_Bsend_free_segment( BsendData_t *p ){    BsendData_t *prev = p->prev, *avail = BsendBuffer.avail, *avail_prev;    MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,                 "Freeing bsend segment at %p of size %d, next at %p",		 p,p->size, ((char *)p)+p->total_size));    MPIU_DBG_MSG_D(BSEND,TYPICAL,	     "At the begining of free_segment with size %d:", p->total_size );    MPIU_DBG_STMT(BSEND,TYPICAL,MPIR_Bsend_dump());    /* Remove the segment from the active list */    if (prev) {	MPIU_DBG_MSG(BSEND,TYPICAL,"free segment is within active list");	prev->next = p->next;    }    else {	/* p was at the head of the active list */	MPIU_DBG_MSG(BSEND,TYPICAL,"free segment is head of active list");	BsendBuffer.active = p->next;	/* The next test sets the prev pointer to null */    }    if (p->next) {	p->next->prev = prev;    }    MPIU_DBG_STMT(BSEND,VERBOSE,MPIR_Bsend_dump());    /* Merge into the avail list */    /* Find avail_prev, avail, such that p is between them.       either may be null if p is at either end of the list */    avail_prev = 0;    while (avail) {	if (avail > p) {	    break;	}	avail_prev = avail;	avail      = avail->next;    }    /* Try to merge p with the next block */    if (avail) {	if ((char *)p + p->total_size == (char *)avail) {	    p->total_size += avail->total_size;	    p->size       = p->total_size - BSENDDATA_HEADER_TRUE_SIZE;	    p->next = avail->next;	    if (avail->next) avail->next->prev = p;	    avail = 0;	}	else {	    p->next = avail;	    avail->prev = p;	}    }    else {	p->next = 0;    }    /* Try to merge p with the previous block */    if (avail_prev) {	if ((char *)avail_prev + avail_prev->total_size == (char *)p) {	    avail_prev->total_size += p->total_size;	    avail_prev->size       = avail_prev->total_size - BSENDDATA_HEADER_TRUE_SIZE;	    avail_prev->next = p->next;	    if (p->next) p->next->prev = avail_prev;	}	else {	    avail_prev->next = p;	    p->prev          = avail_prev;	}    }    else {	/* p is the new head of the list */	BsendBuffer.avail = p;	p->prev           = 0;    }    MPIU_DBG_MSG(BSEND,TYPICAL,"At the end of free_segment:" );    MPIU_DBG_STMT(BSEND,TYPICAL,MPIR_Bsend_dump());}/* end:nested *//*  * The following routine tests for completion of active sends and  * frees the related storage * * To make it easier to identify the source of the request, we keep * track of the type of MPI routine (ibsend, bsend, or bsend_init/start) * that created the bsend entry. */static void MPIR_Bsend_check_active( void ){    BsendData_t *active = BsendBuffer.active, *next_active;    MPIU_DBG_MSG_P(BSEND,TYPICAL,"Checking active starting at %p", active);    while (active) {	MPI_Request r = active->request->handle;	int         flag;		next_active = active->next;	if (active->kind == IBSEND) {	    /* We handle ibsend specially to allow for the user	       to attempt and cancel the request. Also, to allow	       for a cancel attempt (which must be attempted before	       a successful test or wait), we only start	       testing when the user has successfully released	       the request (it is a grequest, the free call will do it) */	    flag = 0;	    if (active->request->ref_count == 1) {		NMPI_Test(&r, &flag, MPI_STATUS_IGNORE );	    }	    else {		/* We need to invoke the progress engine in case we 		 need to advance other, incomplete communication.  */		MPID_Progress_state progress_state;		MPID_Progress_start(&progress_state);		MPID_Progress_test( );		MPID_Progress_end(&progress_state);	    }	}	else {	    NMPI_Test( &r, &flag, MPI_STATUS_IGNORE );	}	if (flag) {	    /* We're done.  Remove this segment */	    MPIU_DBG_MSG_P(BSEND,TYPICAL,"Removing segment %p", active);	    MPIR_Bsend_free_segment( active );	}	active = next_active;	MPIU_DBG_MSG_P(BSEND,TYPICAL,"Next active is %p",active);    }}/*  * FIXME : For each pending item (that is, items that we couldn't even start sending), * try to get them going.   */static void MPIR_Bsend_retry_pending( void ){    BsendData_t *pending = BsendBuffer.pending, *next_pending;    while (pending) {	next_pending = pending->next;	/* Retry sending this item */	/* FIXME */	pending = next_pending;    }}/*  * Find a slot in the avail buffer that can hold size bytes.  Does *not* * remove the slot from the avail buffer (see MPIR_Bsend_take_buffer)  */static BsendData_t *MPIR_Bsend_find_buffer( int size ){    BsendData_t *p = BsendBuffer.avail;    while (p) {	if (p->size >= size) { 	    return p;	}	p = p->next;    }    return 0;}/* This is the minimum number of bytes that a segment must be able to   hold. */#define MIN_BUFFER_BLOCK 8/* * Carve off size bytes from buffer p and leave the remainder * on the avail list.  Handle the head/tail cases.  * If there isn't enough left of p, remove the entire segment from * the avail list. */static void MPIR_Bsend_take_buffer( BsendData_t *p, int size  ){    BsendData_t *prev;    int         alloc_size;    /* Compute the remaining size.  This must include any padding        that must be added to make the new block properly aligned */    alloc_size = size;    if (alloc_size & 0x7) 	alloc_size += (8 - (alloc_size & 0x7));    /* alloc_size is the amount of space (out of size) that we will        allocate for this buffer. */    MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,			    "Taking %d bytes from a block with %d bytes\n", 				    alloc_size, p->total_size ));    /* Is there enough space left to create a new block? */    if (alloc_size + (int)BSENDDATA_HEADER_TRUE_SIZE + MIN_BUFFER_BLOCK <= p->size) {	/* Yes, the available space (p->size) is large enough to 	   carve out a new block */	BsendData_t *newp;		MPIU_DBG_MSG_P(BSEND,TYPICAL,"Breaking block into used and allocated at %p", p );	newp = (BsendData_t *)( (char *)p + BSENDDATA_HEADER_TRUE_SIZE + 				alloc_size );	newp->total_size = p->total_size - alloc_size - 	    BSENDDATA_HEADER_TRUE_SIZE;	newp->size = newp->total_size - BSENDDATA_HEADER_TRUE_SIZE;	newp->msg.msgbuf = (char *)newp + BSENDDATA_HEADER_TRUE_SIZE;	/* Insert this new block after p (we'll remove p from the avail list	   next) */	newp->next = p->next;	newp->prev = p;	if (p->next) {	    p->next->prev = newp;	}	p->next       = newp;	p->total_size = (char *)newp - (char*)p;	p->size       = p->total_size - BSENDDATA_HEADER_TRUE_SIZE;	MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,		   "broken blocks p (%d) and new (%d)\n",		    p->total_size, newp->total_size ));    }    /* Remove p from the avail list and add it to the active list */    prev = p->prev;    if (prev) {	prev->next = p->next;    }    else {	BsendBuffer.avail = p->next;    }    if (p->next) {	p->next->prev = p->prev;    }	    if (BsendBuffer.active) {	BsendBuffer.active->prev = p;    }    p->next	       = BsendBuffer.active;    p->prev	       = 0;    BsendBuffer.active = p;    MPIU_DBG_MSG_P(BSEND,VERBOSE,"segment %p now head of active",p);     MPIU_DBG_MSG(BSEND,TYPICAL,"At end of take buffer" );    MPIU_DBG_STMT(BSEND,TYPICAL,MPIR_Bsend_dump());}/* Ignore p */static int MPIR_Bsend_finalize( void *p ){    void *b;    int  s;    MPIU_UNREFERENCED_ARG(p);    if (BsendBuffer.buffer) {	/* Use detach to complete any communication */	MPIR_Bsend_detach( &b, &s );    }    return 0;}/*  * These routines are defined only if debug logging is enabled */#ifdef USE_DBG_LOGGINGstatic void MPIR_Bsend_dump( void ){    BsendData_t *a = BsendBuffer.avail;    MPIU_DBG_MSG_D(BSEND,TYPICAL,"Total size is %d",BsendBuffer.buffer_size );    MPIU_DBG_MSG(BSEND,TYPICAL,"Avail list is:" );    while (a) {	MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,				"[%p] totalsize = %d(%x)", a, a->total_size, 					a->total_size ));	if (a == a->next) {	    MPIU_DBG_MSG(BSEND,TYPICAL,			 "@@@Corrupt list; avail block points at itself" );	    break;	}	a = a->next;    }        MPIU_DBG_MSG(BSEND,TYPICAL,"Active list is:" );    a = BsendBuffer.active;    while (a) {	MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,				"[%p] totalsize = %d(%x)", a, a->total_size, 					a->total_size ));	if (a == a->next) {	    MPIU_DBG_MSG(BSEND,TYPICAL,			 "@@@Corrupt list; active block points at itself" );	    break;	}	a = a->next;    }    MPIU_DBG_MSG(BSEND,TYPICAL,"end of list" );}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -