-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/pt2pt/bsendutil.c
-: 0:Graph:bsendutil.gcno
-: 0:Data:bsendutil.gcda
-: 0:Runs:856
-: 0:Programs:280
-: 1:/* -*- MODE: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: * (C) 2001 by Argonne National Laboratory.
-: 4: * See COPYRIGHT in top-level directory.
-: 5: */
-: 6:
-: 7:#include "mpiimpl.h"
-: 8:#include "mpibsend.h"
-: 9:#include "bsendutil.h"
-: 10:
-: 11:/*
-: 12: * Miscellaneous comments
-: 13: * By storing total_size along with "size available for messages", we
-: 14: * avoid any complexities associated with alignment, since we must
-: 15: * ensure that each KPIR_Bsend_data_t structure is properly aligned
-: 16: * (i.e., we can't simply do (sizeof(MPIR_Bsend_data_t) + size) to get
-: 17: * total_size).
-: 18: *
-: 19: * Function Summary
-: 20: * MPIR_Bsend_attach - Performs the work of MPI_Buffer_attach
-: 21: * MPIR_Bsend_detach - Performs the work of MPI_Buffer_detach
-: 22: * MPIR_Bsend_isend - Essentially performs an MPI_Ibsend. Returns
-: 23: * an MPID_Request that is also stored internally in the
-: 24: * corresponding MPIR_Bsend_data_t entry
-: 25: * MPIR_Bsend_free_segment - Free a buffer that is no longer needed,
-: 26: * merging with adjacent segments
-: 27: * MPIR_Bsend_check_active - Check for completion of any pending sends
-: 28: * for bsends (all bsends, both MPI_Ibsend and MPI_Bsend,
-: 29: * are internally converted into Isends on the data
-: 30: * in the Bsend buffer)
-: 31: * MPIR_Bsend_retry_pending - Routine for future use to handle the
-: 32: * case where an Isend cannot be initiated.
-: 33: * MPIR_Bsend_find_buffer - Find a buffer in the bsend buffer large
-: 34: * enough for the message. However, does not acquire that
-: 35: * buffer (see MPIR_Bsend_take_buffer)
-: 36: * MPIR_Bsend_take_buffer - Find and acquire a buffer for a message
-: 37: * MPIR_Bsend_finalize - Finalize handler when Bsend routines are used
-: 38: * MPIR_Bsend_dump - Debugging routine to print the contents of the control
-: 39: * information in the bsend buffer (the MPIR_Bsend_data_t entries)
-: 40: */
-: 41:
-: 42:#ifdef USE_DBG_LOGGING
-: 43:static void MPIR_Bsend_dump( void );
-: 44:#endif
-: 45:
-: 46:#define BSENDDATA_HEADER_TRUE_SIZE (sizeof(MPIR_Bsend_data_t) - sizeof(double))
-: 47:
-: 48:/* BsendBuffer is the structure that describes the overall Bsend buffer */
-: 49:/*
-: 50: * We use separate buffer and origbuffer because we may need to align
-: 51: * the buffer (we *could* always memcopy the header to an aligned region,
-: 52: * but it is simpler to just align it internally. This does increase the
-: 53: * BSEND_OVERHEAD, but that is already relatively large. We could instead
-: 54: * make sure that the initial header was set at an aligned location (
-: 55: * taking advantage of the "alignpad"), but this would require more changes.
-: 56: */
-: 57:static struct BsendBuffer {
-: 58: void *buffer; /* Pointer to the begining of the user-
-: 59: provided buffer */
-: 60: int buffer_size; /* Size of the user-provided buffer */
-: 61: void *origbuffer; /* Pointer to the buffer provided by
-: 62: the user */
-: 63: int origbuffer_size; /* Size of the buffer as provided
-: 64: by the user */
-: 65: MPIR_Bsend_data_t *avail; /* Pointer to the first available block
-: 66: of space */
-: 67: MPIR_Bsend_data_t *pending; /* Pointer to the first message that
-: 68: could not be sent because of a
-: 69: resource limit (e.g., no requests
-: 70: available) */
-: 71: MPIR_Bsend_data_t *active; /* Pointer to the first active (sending)
-: 72: message */
-: 73:} BsendBuffer = { 0, 0, 0, 0, 0, 0, 0 };
-: 74:
-: 75:static int initialized = 0; /* keep track of the first call to any
-: 76: bsend routine */
-: 77:
-: 78:/* Forward references */
-: 79:static void MPIR_Bsend_retry_pending( void );
-: 80:static void MPIR_Bsend_check_active ( void );
-: 81:static MPIR_Bsend_data_t *MPIR_Bsend_find_buffer( int );
-: 82:static void MPIR_Bsend_take_buffer( MPIR_Bsend_data_t *, int );
-: 83:static int MPIR_Bsend_finalize( void * );
-: 84:
-: 85:/*
-: 86: * Attach a buffer. This checks for the error conditions and then
-: 87: * initialized the avail buffer.
-: 88: */
-: 89:#undef FUNCNAME
-: 90:#define FUNCNAME MPIR_Bsend_attach
-: 91:#undef FCNAME
-: 92:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 93:int MPIR_Bsend_attach( void *buffer, int buffer_size )
45987: 94:{
-: 95: MPIR_Bsend_data_t *p;
-: 96: long offset;
-: 97:
|
-: 98:# ifdef HAVE_ERROR_CHECKING
-: 99: {
-: 100: MPID_BEGIN_ERROR_CHECKS;
-: 101: {
45987: 102: if (BsendBuffer.buffer) {
2: 103: return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
-: 104: "MPIR_Bsend_attach", __LINE__, MPI_ERR_BUFFER,
-: 105: "**bufexists", 0 );
-: 106: }
45985: 107: if (buffer_size < MPI_BSEND_OVERHEAD) {
-: 108: /* MPI_ERR_OTHER is another valid choice for this error,
-: 109: but the Intel test wants MPI_ERR_BUFFER, and it seems
-: 110: to violate the principle of least surprise to not use
-: 111: MPI_ERR_BUFFER for errors with the Buffer */
#####: 112: return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
-: 113: "MPIR_Bsend_attach", __LINE__, MPI_ERR_BUFFER,
-: 114: "**bsendbufsmall",
-: 115: "**bsendbufsmall %d %d", buffer_size, MPI_BSEND_OVERHEAD );
-: 116: }
-: 117: }
-: 118: MPID_END_ERROR_CHECKS;
-: 119: }
-: 120:# endif /* HAVE_ERROR_CHECKING */
-: 121:
|
45985: 122: if (!initialized) {
168: 123: initialized = 1;
168: 124: MPIR_Add_finalize( MPIR_Bsend_finalize, (void *)0, 10 );
-: 125: }
-: 126:
45985: 127: BsendBuffer.origbuffer = buffer;
45985: 128: BsendBuffer.origbuffer_size = buffer_size;
45985: 129: BsendBuffer.buffer = buffer;
45985: 130: BsendBuffer.buffer_size = buffer_size;
45985: 131: offset = ((long)buffer) % sizeof(void *);
45985: 132: if (offset) {
-: 133: /* Make sure that the buffer that we use is aligned for pointers,
-: 134: because the code assumes that */
10: 135: offset = sizeof(void *) - offset;
10: 136: buffer = (char *)buffer + offset;
10: 137: BsendBuffer.buffer = buffer;
10: 138: BsendBuffer.buffer_size -= offset;
-: 139: }
45985: 140: BsendBuffer.avail = buffer;
45985: 141: BsendBuffer.pending = 0;
45985: 142: BsendBuffer.active = 0;
-: 143:
-: 144: /* Set the first block */
45985: 145: p = (MPIR_Bsend_data_t *)buffer;
45985: 146: p->size = buffer_size - BSENDDATA_HEADER_TRUE_SIZE;
45985: 147: p->total_size = buffer_size;
45985: 148: p->next = p->prev = 0;
45985: 149: p->msg.msgbuf = (char *)p + BSENDDATA_HEADER_TRUE_SIZE;
-: 150:
45985: 151: return MPI_SUCCESS;
-: 152:}
-: 153:
-: 154:/*
-: 155: * Detach a buffer. This routine must wait until any pending bsends
-: 156: * are complete.
-: 157: */
-: 158:#undef FUNCNAME
-: 159:#define FUNCNAME MPIR_Bsend_detach
-: 160:#undef FCNAME
-: 161:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 162:int MPIR_Bsend_detach( void *bufferp, int *size )
45995: 163:{
45995: 164: if (BsendBuffer.pending) {
-: 165: /* FIXME: This is the wrong error text (notimpl) */
|
#####: 166: return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
-: 167: "MPIR_Bsend_detach", __LINE__, MPI_ERR_OTHER, "**notimpl", 0 );
-: 168: }
|
45995: 169: if (BsendBuffer.active) {
-: 170: /* Loop through each active element and wait on it */
45897: 171: MPIR_Bsend_data_t *p = BsendBuffer.active;
45897: 172: MPIU_THREADPRIV_DECL;
-: 173:
45897: 174: MPIU_THREADPRIV_GET;
-: 175:
45897: 176: MPIR_Nest_incr();
154658: 177: while (p) {
62864: 178: MPI_Request r = p->request->handle;
62864: 179: NMPI_Wait( &r, MPI_STATUS_IGNORE );
62864: 180: p = p->next;
-: 181: }
45897: 182: MPIR_Nest_decr();
-: 183: }
-: 184:
-: 185:/* Note that this works even when the buffer does not exist */
45995: 186: *(void **) bufferp = BsendBuffer.origbuffer;
45995: 187: *size = BsendBuffer.origbuffer_size;
45995: 188: BsendBuffer.origbuffer = NULL;
45995: 189: BsendBuffer.origbuffer_size = 0;
45995: 190: BsendBuffer.buffer = 0;
45995: 191: BsendBuffer.buffer_size = 0;
45995: 192: BsendBuffer.avail = 0;
45995: 193: BsendBuffer.active = 0;
45995: 194: BsendBuffer.pending = 0;
-: 195:
45995: 196: return MPI_SUCCESS;
-: 197:}
-: 198:
-: 199:/*
-: 200: * Initiate an ibsend. We'll used this for Bsend as well.
-: 201: */
-: 202:#undef FUNCNAME
-: 203:#define FUNCNAME MPIR_Bsend_isend
-: 204:#undef FCNAME
-: 205:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 206:int MPIR_Bsend_isend( void *buf, int count, MPI_Datatype dtype,
-: 207: int dest, int tag, MPID_Comm *comm_ptr,
-: 208: MPIR_Bsend_kind_t kind, MPID_Request **request )
193584: 209:{
-: 210: MPIR_Bsend_data_t *p;
-: 211: MPIR_Bsend_msg_t *msg;
-: 212: int packsize, mpi_errno, pass;
193584: 213: MPIU_THREADPRIV_DECL;
-: 214:
-: 215: /* Find a free segment and copy the data into it. If we could
-: 216: have, we would already have used tBsend to send the message with
-: 217: no copying.
-: 218:
-: 219: We may want to decide here whether we need to pack at all
-: 220: or if we can just use (a MPIU_Memcpy) of the buffer.
-: 221: */
-: 222:
193584: 223: MPIU_THREADPRIV_GET;
193584: 224: MPIR_Nest_incr();
-: 225:
-: 226: /* We check the active buffer first. This helps avoid storage
-: 227: fragmentation */
193584: 228: MPIR_Bsend_check_active();
-: 229:
193584: 230: if (dtype != MPI_PACKED)
-: 231: {
193584: 232: (void)NMPI_Pack_size( count, dtype, comm_ptr->handle, &packsize );
-: 233: }
-: 234: else
-: 235: {
|
#####: 236: packsize = count;
-: 237: }
-: 238:
-: 239: MPIU_DBG_MSG_D(BSEND,TYPICAL,"looking for buffer of size %d", packsize);
-: 240: /*
-: 241: * Use two passes. Each pass is the same; between the two passes,
-: 242: * attempt to complete any active requests, and start any pending
-: 243: * ones. If the message can be initiated in the first pass,
-: 244: * do not perform the second pass.
-: 245: */
|
199401: 246: for (pass = 0; pass < 2; pass++) {
-: 247:
199401: 248: p = MPIR_Bsend_find_buffer( packsize );
199401: 249: if (p) {
-: 250: MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,
-: 251: "found buffer of size %d with address %p",packsize,p));
-: 252: /* Found a segment */
-: 253:
187778: 254: msg = &p->msg;
-: 255:
-: 256: /* Pack the data into the buffer */
-: 257: /* We may want to optimize for the special case of
-: 258: either primative or contiguous types, and just
-: 259: use MPIU_Memcpy and the provided datatype */
187778: 260: msg->count = 0;
187778: 261: if (dtype != MPI_PACKED)
-: 262: {
187778: 263: (void)NMPI_Pack( buf, count, dtype, p->msg.msgbuf, packsize,
-: 264: &p->msg.count, comm_ptr->handle );
-: 265: }
-: 266: else
-: 267: {
|
#####: 268: MPIU_Memcpy(p->msg.msgbuf, buf, count);
#####: 269: p->msg.count = count;
-: 270: }
-: 271: /* Try to send the message. We must use MPID_Isend
-: 272: because this call must not block */
|
187778: 273: mpi_errno = MPID_Isend(msg->msgbuf, msg->count, MPI_PACKED,
-: 274: dest, tag, comm_ptr,
-: 275: MPID_CONTEXT_INTRA_PT2PT, &p->request );
187778: 276: if (p->request) {
-: 277: MPIU_DBG_MSG_FMT(BSEND,TYPICAL,
-: 278: (MPIU_DBG_FDEST,"saving request %p in %p",p->request,p));
-: 279: /* An optimization is to check to see if the
-: 280: data has already been sent. The original code
-: 281: to do this was commented out and probably did not match
-: 282: the current request internals */
187778: 283: MPIR_Bsend_take_buffer( p, p->msg.count );
187778: 284: p->kind = kind;
187778: 285: *request = p->request;
-: 286: }
-: 287: else {
|
-: 288: /* --BEGIN ERROR HANDLING-- */
#####: 289: if (mpi_errno) {
#####: 290: MPIU_Internal_error_printf ("Bsend internal error: isend returned err = %d", mpi_errno );
-: 291: }
-: 292: /* --END ERROR HANDLING-- */
-: 293: /* If the error is "request not available", we should
-: 294: put this on the pending list. This will depend on
-: 295: how we signal failure to send. */
-: 296: }
-: 297: break;
-: 298: }
-: 299: /* If we found a buffer or we're in the seccond pass, then break.
-: 300: Note that the test on phere is redundant, as the code breaks
-: 301: out of the loop in the test above if a block p is found. */
|
11623: 302: if (p || pass == 1) break;
-: 303: MPIU_DBG_MSG(BSEND,TYPICAL,"Could not find storage, checking active");
-: 304: /* Try to complete some pending bsends */
5817: 305: MPIR_Bsend_check_active( );
-: 306: /* Give priority to any pending operations */
5817: 307: MPIR_Bsend_retry_pending( );
-: 308: }
193584: 309: MPIR_Nest_decr();
-: 310:
193584: 311: if (!p) {
-: 312: /* Return error for no buffer space found */
-: 313: /* Generate a traceback of the allocated space, explaining why
-: 314: packsize could not be found */
-: 315: MPIU_DBG_MSG(BSEND,TYPICAL,"Could not find space; dumping arena" );
-: 316: MPIU_DBG_STMT(BSEND,TYPICAL,MPIR_Bsend_dump());
-: 317:
|
5806: 318: return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIR_Bsend_isend", __LINE__, MPI_ERR_BUFFER, "**bufbsend",
-: 319: "**bufbsend %d %d", packsize,
-: 320: BsendBuffer.buffer_size );
-: 321: }
-: 322: else {
|
187778: 323: return MPI_SUCCESS;
-: 324: }
-: 325:}
-: 326:
-: 327:/*
-: 328: * The following routines are used to manage the allocation of bsend segments
-: 329: * in the user buffer. These routines handle, for example, merging segments
-: 330: * when an active segment that is adjacent to a free segment becomes free.
-: 331: *
-: 332: */
-: 333:
-: 334:/* Add block p to the free list. Merge into adjacent blocks. Used only
-: 335: within the check_active */
-: 336:/* begin:nested */
-: 337:#undef FUNCNAME
-: 338:#define FUNCNAME MPIR_Bsend_free_segment
-: 339:#undef FCNAME
-: 340:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 341:static void MPIR_Bsend_free_segment( MPIR_Bsend_data_t *p )
124914: 342:{
124914: 343: MPIR_Bsend_data_t *prev = p->prev, *avail = BsendBuffer.avail, *avail_prev;
-: 344:
-: 345: MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,
-: 346: "Freeing bsend segment at %p of size %d, next at %p",
-: 347: p,p->size, ((char *)p)+p->total_size));
-: 348:
-: 349: MPIU_DBG_MSG_D(BSEND,TYPICAL,
-: 350: "At the begining of free_segment with size %d:", p->total_size );
-: 351: MPIU_DBG_STMT(BSEND,TYPICAL,MPIR_Bsend_dump());
-: 352:
-: 353: /* Remove the segment from the active list */
124914: 354: if (prev) {
-: 355: MPIU_DBG_MSG(BSEND,TYPICAL,"free segment is within active list");
54: 356: prev->next = p->next;
-: 357: }
-: 358: else {
-: 359: /* p was at the head of the active list */
-: 360: MPIU_DBG_MSG(BSEND,TYPICAL,"free segment is head of active list");
124860: 361: BsendBuffer.active = p->next;
-: 362: /* The next test sets the prev pointer to null */
-: 363: }
124914: 364: if (p->next) {
36500: 365: p->next->prev = prev;
-: 366: }
-: 367:
-: 368: MPIU_DBG_STMT(BSEND,VERBOSE,MPIR_Bsend_dump());
-: 369:
-: 370: /* Merge into the avail list */
-: 371: /* Find avail_prev, avail, such that p is between them.
-: 372: either may be null if p is at either end of the list */
124914: 373: avail_prev = 0;
249843: 374: while (avail) {
124317: 375: if (avail > p) {
124302: 376: break;
-: 377: }
15: 378: avail_prev = avail;
15: 379: avail = avail->next;
-: 380: }
-: 381:
-: 382: /* Try to merge p with the next block */
124914: 383: if (avail) {
124302: 384: if ((char *)p + p->total_size == (char *)avail) {
124273: 385: p->total_size += avail->total_size;
124273: 386: p->size = p->total_size - BSENDDATA_HEADER_TRUE_SIZE;
124273: 387: p->next = avail->next;
124273: 388: if (avail->next) avail->next->prev = p;
124273: 389: avail = 0;
-: 390: }
-: 391: else {
29: 392: p->next = avail;
29: 393: avail->prev = p;
-: 394: }
-: 395: }
-: 396: else {
612: 397: p->next = 0;
-: 398: }
-: 399: /* Try to merge p with the previous block */
124914: 400: if (avail_prev) {
15: 401: if ((char *)avail_prev + avail_prev->total_size == (char *)p) {
7: 402: avail_prev->total_size += p->total_size;
7: 403: avail_prev->size = avail_prev->total_size - BSENDDATA_HEADER_TRUE_SIZE;
7: 404: avail_prev->next = p->next;
7: 405: if (p->next) p->next->prev = avail_prev;
-: 406: }
-: 407: else {
8: 408: avail_prev->next = p;
8: 409: p->prev = avail_prev;
-: 410: }
-: 411: }
-: 412: else {
-: 413: /* p is the new head of the list */
124899: 414: BsendBuffer.avail = p;
124899: 415: p->prev = 0;
-: 416: }
-: 417:
-: 418: MPIU_DBG_MSG(BSEND,TYPICAL,"At the end of free_segment:" );
-: 419: MPIU_DBG_STMT(BSEND,TYPICAL,MPIR_Bsend_dump());
124914: 420:}
-: 421:/* end:nested */
-: 422:/*
-: 423: * The following routine tests for completion of active sends and
-: 424: * frees the related storage
-: 425: *
-: 426: * To make it easier to identify the source of the request, we keep
-: 427: * track of the type of MPI routine (ibsend, bsend, or bsend_init/start)
-: 428: * that created the bsend entry.
-: 429: */
-: 430:#undef FUNCNAME
-: 431:#define FUNCNAME MPIR_Bsend_check_active
-: 432:#undef FCNAME
-: 433:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 434:static void MPIR_Bsend_check_active( void )
199401: 435:{
199401: 436: MPIR_Bsend_data_t *active = BsendBuffer.active, *next_active;
-: 437:
-: 438: MPIU_DBG_MSG_P(BSEND,TYPICAL,"Checking active starting at %p", active);
603992: 439: while (active) {
205190: 440: MPI_Request r = active->request->handle;
-: 441: int flag;
-: 442:
205190: 443: next_active = active->next;
-: 444:
205190: 445: if (active->kind == IBSEND) {
-: 446: /* We handle ibsend specially to allow for the user
-: 447: to attempt and cancel the request. Also, to allow
-: 448: for a cancel attempt (which must be attempted before
-: 449: a successful test or wait), we only start
-: 450: testing when the user has successfully released
-: 451: the request (it is a grequest, the free call will do it) */
126198: 452: flag = 0;
-: 453: /* XXX DJG FIXME-MT should we be checking this? */
126198: 454: if (MPIU_Object_get_ref(active->request) == 1) {
71197: 455: NMPI_Test(&r, &flag, MPI_STATUS_IGNORE );
-: 456: }
-: 457: else {
-: 458: /* We need to invoke the progress engine in case we
-: 459: need to advance other, incomplete communication. */
-: 460: MPID_Progress_state progress_state;
55001: 461: MPID_Progress_start(&progress_state);
55001: 462: MPID_Progress_test( );
-: 463: MPID_Progress_end(&progress_state);
-: 464: }
-: 465: }
-: 466: else {
78992: 467: NMPI_Test( &r, &flag, MPI_STATUS_IGNORE );
-: 468: }
205190: 469: if (flag) {
-: 470: /* We're done. Remove this segment */
-: 471: MPIU_DBG_MSG_P(BSEND,TYPICAL,"Removing segment %p", active);
124914: 472: MPIR_Bsend_free_segment( active );
-: 473: }
205190: 474: active = next_active;
-: 475: MPIU_DBG_MSG_P(BSEND,TYPICAL,"Next active is %p",active);
-: 476: }
199401: 477:}
-: 478:
-: 479:/*
-: 480: * FIXME : For each pending item (that is, items that we couldn't even start sending),
-: 481: * try to get them going.
-: 482: */
-: 483:static void MPIR_Bsend_retry_pending( void )
5817: 484:{
5817: 485: MPIR_Bsend_data_t *pending = BsendBuffer.pending, *next_pending;
-: 486:
11634: 487: while (pending) {
|
#####: 488: next_pending = pending->next;
-: 489: /* Retry sending this item */
-: 490: /* FIXME */
#####: 491: pending = next_pending;
-: 492: }
|
5817: 493:}
-: 494:
-: 495:/*
-: 496: * Find a slot in the avail buffer that can hold size bytes. Does *not*
-: 497: * remove the slot from the avail buffer (see MPIR_Bsend_take_buffer)
-: 498: */
-: 499:static MPIR_Bsend_data_t *MPIR_Bsend_find_buffer( int size )
199401: 500:{
199401: 501: MPIR_Bsend_data_t *p = BsendBuffer.avail;
-: 502:
398814: 503: while (p) {
187790: 504: if (p->size >= size) {
187778: 505: return p;
-: 506: }
12: 507: p = p->next;
-: 508: }
11623: 509: return 0;
-: 510:}
-: 511:
-: 512:/* This is the minimum number of bytes that a segment must be able to
-: 513: hold. */
-: 514:#define MIN_BUFFER_BLOCK 8
-: 515:/*
-: 516: * Carve off size bytes from buffer p and leave the remainder
-: 517: * on the avail list. Handle the head/tail cases.
-: 518: * If there isn't enough left of p, remove the entire segment from
-: 519: * the avail list.
-: 520: */
-: 521:static void MPIR_Bsend_take_buffer( MPIR_Bsend_data_t *p, int size )
187778: 522:{
-: 523: MPIR_Bsend_data_t *prev;
-: 524: int alloc_size;
-: 525:
-: 526: /* Compute the remaining size. This must include any padding
-: 527: that must be added to make the new block properly aligned */
187778: 528: alloc_size = size;
187778: 529: if (alloc_size & 0x7)
20891: 530: alloc_size += (8 - (alloc_size & 0x7));
-: 531: /* alloc_size is the amount of space (out of size) that we will
-: 532: allocate for this buffer. */
-: 533:
-: 534: MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,
-: 535: "Taking %d bytes from a block with %d bytes\n",
-: 536: alloc_size, p->total_size ));
-: 537:
-: 538: /* Is there enough space left to create a new block? */
187778: 539: if (alloc_size + (int)BSENDDATA_HEADER_TRUE_SIZE + MIN_BUFFER_BLOCK <= p->size) {
-: 540: /* Yes, the available space (p->size) is large enough to
-: 541: carve out a new block */
-: 542: MPIR_Bsend_data_t *newp;
-: 543:
-: 544: MPIU_DBG_MSG_P(BSEND,TYPICAL,"Breaking block into used and allocated at %p", p );
186541: 545: newp = (MPIR_Bsend_data_t *)( (char *)p + BSENDDATA_HEADER_TRUE_SIZE +
-: 546: alloc_size );
186541: 547: newp->total_size = p->total_size - alloc_size -
-: 548: BSENDDATA_HEADER_TRUE_SIZE;
186541: 549: newp->size = newp->total_size - BSENDDATA_HEADER_TRUE_SIZE;
186541: 550: newp->msg.msgbuf = (char *)newp + BSENDDATA_HEADER_TRUE_SIZE;
-: 551:
-: 552: /* Insert this new block after p (we'll remove p from the avail list
-: 553: next) */
186541: 554: newp->next = p->next;
186541: 555: newp->prev = p;
186541: 556: if (p->next) {
5: 557: p->next->prev = newp;
-: 558: }
186541: 559: p->next = newp;
186541: 560: p->total_size = (char *)newp - (char*)p;
186541: 561: p->size = p->total_size - BSENDDATA_HEADER_TRUE_SIZE;
-: 562:
-: 563: MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,
-: 564: "broken blocks p (%d) and new (%d)\n",
-: 565: p->total_size, newp->total_size ));
-: 566: }
-: 567:
-: 568: /* Remove p from the avail list and add it to the active list */
187778: 569: prev = p->prev;
187778: 570: if (prev) {
|
#####: 571: prev->next = p->next;
-: 572: }
-: 573: else {
|
187778: 574: BsendBuffer.avail = p->next;
-: 575: }
-: 576:
187778: 577: if (p->next) {
186563: 578: p->next->prev = p->prev;
-: 579: }
-: 580:
187778: 581: if (BsendBuffer.active) {
53496: 582: BsendBuffer.active->prev = p;
-: 583: }
187778: 584: p->next = BsendBuffer.active;
187778: 585: p->prev = 0;
187778: 586: BsendBuffer.active = p;
-: 587:
-: 588: MPIU_DBG_MSG_P(BSEND,VERBOSE,"segment %p now head of active",p);
-: 589: MPIU_DBG_MSG(BSEND,TYPICAL,"At end of take buffer" );
-: 590: MPIU_DBG_STMT(BSEND,TYPICAL,MPIR_Bsend_dump());
187778: 591:}
-: 592:
-: 593:static int MPIR_Bsend_finalize( void *p ATTRIBUTE((unused)) )
168: 594:{
-: 595: void *b;
-: 596: int s;
-: 597:
-: 598: MPIU_UNREFERENCED_ARG(p);
-: 599:
168: 600: if (BsendBuffer.buffer) {
-: 601: /* Use detach to complete any communication */
4: 602: MPIR_Bsend_detach( &b, &s );
-: 603: }
168: 604: return 0;
-: 605:}
-: 606:
-: 607:/*
-: 608: * These routines are defined only if debug logging is enabled
-: 609: */
-: 610:#ifdef USE_DBG_LOGGING
-: 611:static void MPIR_Bsend_dump( void )
-: 612:{
-: 613: MPIR_Bsend_data_t *a = BsendBuffer.avail;
-: 614:
-: 615: MPIU_DBG_MSG_D(BSEND,TYPICAL,"Total size is %d",BsendBuffer.buffer_size );
-: 616: MPIU_DBG_MSG(BSEND,TYPICAL,"Avail list is:" );
-: 617: while (a) {
-: 618: MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,
-: 619: "[%p] totalsize = %d(%x)", a, a->total_size,
-: 620: a->total_size ));
-: 621: if (a == a->next) {
-: 622: MPIU_DBG_MSG(BSEND,TYPICAL,
-: 623: "@@@Corrupt list; avail block points at itself" );
-: 624: break;
-: 625: }
-: 626: a = a->next;
-: 627: }
-: 628:
-: 629: MPIU_DBG_MSG(BSEND,TYPICAL,"Active list is:" );
-: 630: a = BsendBuffer.active;
-: 631: while (a) {
-: 632: MPIU_DBG_MSG_FMT(BSEND,TYPICAL,(MPIU_DBG_FDEST,
-: 633: "[%p] totalsize = %d(%x)", a, a->total_size,
-: 634: a->total_size ));
-: 635: if (a == a->next) {
-: 636: MPIU_DBG_MSG(BSEND,TYPICAL,
-: 637: "@@@Corrupt list; active block points at itself" );
-: 638: break;
-: 639: }
-: 640: a = a->next;
-: 641: }
-: 642: MPIU_DBG_MSG(BSEND,TYPICAL,"end of list" );
-: 643:}
-: 644:#endif
|