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

📄 bsendutil.c

📁 刚才是说明 现在是安装程序在 LINUX环境下进行编程的MPICH安装文件
💻 C
📖 第 1 页 / 共 2 页
字号:
				     "**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;    DEBUG1(printf("Freeing bsend segment at %x of size %d, next at %x\n",		 p,p->size, ((char *)p)+p->total_size));#ifdef PRINT_ARENA    printf( "At the begining of free_segment with size %d:\n", p->total_size );    MPIR_Bsend_dump();#endif        /* Remove the segment from the free list */    if (prev) {	DEBUG(printf("free segment is within active list\n"));	prev->next = p->next;    }    else {	/* p was at the head of the active list */	DEBUG(printf("free segment is head of active list\n"));	BsendBuffer.active = p->next;	/* The next test sets the prev pointer to null */    }    if (p->next) {	p->next->prev = prev;    }#ifdef PRINT_AVAIL_LIST    {	BsendData_t *a = BsendBuffer.avail;	printf( "Avail list is:\n" );	while (a) {	    printf( "[%x] totalsize = %d(%x)\n", a, a->total_size, 		   a->total_size );	    a = a->next;	}    }#endif    /* 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       = p->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;    }#ifdef PRINT_ARENA    printf( "At the end of free_segment:\n" );    MPIR_Bsend_dump();#endif    }/* 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;    DEBUG(printf("Checking active starting at %x\n", active ));    while (active) {	MPI_Request r = active->request->handle;	int         flag;		next_active = active->next;	NMPI_Test( &r, &flag, MPI_STATUS_IGNORE );	if (flag) {	    /* We're done.  Remove this segment */	    DEBUG(printf("Removing segment %x\n", active ));	    MPIR_Bsend_free_segment( active );	}	active = next_active;	DEBUG(printf("Next active is %x\n",active));    }}/*  * For each pending item (that is, items that we couldn't even start sending), * try to get them going.  FIXME */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. */#ifdef PRINT_ARENA    printf( "Taking %d bytes from a block with %d bytes\n", alloc_size, 	    p->total_size );#endif    /* Is there enough space left to create a new block? */    if (alloc_size + 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;		DEBUG(printf("Breaking block into used and allocated at %x\n", 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;#ifdef PRINT_ARENA	printf( "broken blocks p (%d) and new (%d)\n",		p->total_size, newp->total_size ); fflush(stdout);#endif    }    /* 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;#ifdef PRINT_ARENA    printf( "At end of take buffer\n" );    MPIR_Bsend_dump();#endif    DEBUG(printf("segment %x now head of active\n", p ));}/* Ignore p */static int MPIR_Bsend_finalize( void *p ){    void *b;    int  s;    if (BsendBuffer.buffer) {	/* Use detach to complete any communication */	MPIR_Bsend_detach( &b, &s );    }    return 0;}#ifdef PRINT_ARENAvoid MPIR_Bsend_dump( void ){    BsendData_t *a = BsendBuffer.avail;    printf( "Total size is %d\n", BsendBuffer.buffer_size );    printf( "Avail list is:\n" );    while (a) {	printf( "[%x] totalsize = %d(%x)\n", a, a->total_size, 		a->total_size );	if (a == a->next) {	    printf( "@@@Corrupt list; avail block points at itself\n" );	    break;	}	a = a->next;    }    printf( "Active list is:\n" );    a = BsendBuffer.active;    while (a) {	printf( "[%x] totalsize = %d(%x)\n", a, a->total_size, 		a->total_size );	if (a == a->next) {	    printf( "@@@Corrupt list; active block points at itself\n" );	    break;	}	a = a->next;    }    printf( "end of list\n" );    fflush( stdout );}#endif

⌨️ 快捷键说明

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