/* bulk.c - Handlers for bulk functions. */ /* see copyright.txt for usage terms */ #define TI_NO_SRCPOS #include #ifdef COMM_AM2 /* ------------------------------------------------------------------------------------ */ TI_INLINE(bulk_get_request) void bulk_get_request(tic_amtoken_t token, void *local, void *dest, juint len, Counter *ctr, tic_ptr_embedding ptr_embed) { #if defined(USE_DISTRIBUTED_GC) && !defined(USE_GC_NONE) /* specialize to only seek out gp's if we know it's an array copy with non-atomic elements * or non-atomic immutable copy. Could be handled using AM handlers that call * GC marking routines, but this has some synchronization problems. * When we pull bulk data it's almost always gp's and not lp's - the only exception is * local Titanium array descriptors, which contain a local pointer that gets pulled * over with the immutable, then expanded * Strictly speaking, we need an additional copy to make sure no other thread is modifying the * buffer between the time we scan a location and AM picks it up to be sent, but this seems * very unlikely to show up in practice and potentially damaging to performance. */ switch (ptr_embed) { case tic_no_ptrs: /* no embedded pointers - nothing necessary */ break; case tic_gp_only: dgc_ptr_esc_all_gps(local, len, 1); /* inform distributed GC that some pointers may be escaping */ break; case tic_has_ptrs: dgc_ptr_esc_all(local, len, 1); /* inform distributed GC that some pointers may be escaping */ break; } #endif #if AM2_HAS_HUGE_SEGMENTS /* AM_MaxSeg is currently too small (on now & millenium) for this to work */ tic_AMReplyXfer(1,2,(token, (jUIntPointer)(((char*)dest)-TIC_AM_SEGOFFSET), TIC_AMIDX(bulk_get_complete_reply), local, len, TIC_AMSEND_PTR(ctr))); #else tic_AMReplyI(2,4,(token, TIC_AMIDX(bulk_get_complete_reply), local, len, TIC_AMSEND_PTR(dest), TIC_AMSEND_PTR(ctr))); #endif } TIC_AMSHORT(bulk_get_request, 5, 8, (token, TIC_AMRECV_PTR32(a0), TIC_AMRECV_PTR32(a1), (juint)a2, (Counter *)TIC_AMRECV_PTR32(a3), (tic_ptr_embedding)a4), (token, TIC_AMRECV_PTR64(a0, a1), TIC_AMRECV_PTR64(a2, a3), (juint)a4, (Counter *)TIC_AMRECV_PTR64(a5, a6), (tic_ptr_embedding)a7)); /* ------------------------------------------------------------------------------------ */ #if AM2_HAS_HUGE_SEGMENTS TI_INLINE(bulk_get_complete_reply) void bulk_get_complete_reply (tic_amtoken_t token, void *buf, size_t len, Counter *ctr) { if (ctr != NULL) { __decr_ctr(ctr); } } TIC_AMLONG(bulk_get_complete_reply, 1, 2, (token,addr,nbytes, (Counter *)TIC_AMRECV_PTR32(a0) ), (token,addr,nbytes, (Counter *)TIC_AMRECV_PTR64(a0, a1))); #else TI_INLINE(bulk_get_complete_reply) void bulk_get_complete_reply (tic_amtoken_t token, void *buf, size_t len, void *destaddr, Counter *ctr) { memcpy(destaddr, buf, len); if (ctr != NULL) { __decr_ctr(ctr); } } TIC_AMMEDIUM(bulk_get_complete_reply, 2, 4, (token,addr,nbytes, TIC_AMRECV_PTR32(a0), (Counter *)TIC_AMRECV_PTR32(a1) ), (token,addr,nbytes, TIC_AMRECV_PTR64(a0, a1), (Counter *)TIC_AMRECV_PTR64(a2, a3))); #endif /* ------------------------------------------------------------------------------------ */ #if AM2_HAS_HUGE_SEGMENTS /* AM_MaxSeg is currently too small (on now & millenium) for this to work */ TI_INLINE(bulk_put_request) void bulk_put_request(tic_amtoken_t token, void *buf, size_t len, Counter *ctr) { tic_AMReply(1,2,(token, TIC_AMIDX(bulk_put_complete_reply), TIC_AMSEND_PTR(ctr))); } TIC_AMLONG(bulk_put_request, 1, 2, (token,addr,nbytes, (Counter *)TIC_AMRECV_PTR32(a0) ), (token,addr,nbytes, (Counter *)TIC_AMRECV_PTR64(a0, a1))); #else TI_INLINE(bulk_put_request) void bulk_put_request(tic_amtoken_t token, void *buf, size_t len, void *destaddr, Counter *ctr) { memcpy(destaddr, buf, len); tic_AMReply(1,2,(token, TIC_AMIDX(bulk_put_complete_reply), TIC_AMSEND_PTR(ctr))); } TIC_AMMEDIUM(bulk_put_request, 2, 4, (token,addr,nbytes, TIC_AMRECV_PTR32(a0), (Counter *)TIC_AMRECV_PTR32(a1) ), (token,addr,nbytes, TIC_AMRECV_PTR64(a0, a1), (Counter *)TIC_AMRECV_PTR64(a2, a3))); #endif /* ------------------------------------------------------------------------------------ */ TI_INLINE(bulk_put_complete_reply) void bulk_put_complete_reply(tic_amtoken_t token, Counter *ctr) { if (ctr != NULL) { __decr_ctr(ctr); } } TIC_AMSHORT(bulk_put_complete_reply, 1, 2, (token, (Counter *)TIC_AMRECV_PTR32(a0) ), (token, (Counter *)TIC_AMRECV_PTR64(a0, a1))); /* ------------------------------------------------------------------------------------ */ /* ............................ * * STOREs with explicit counter * * ............................ */ #if AM2_HAS_HUGE_SEGMENTS /* AM_MaxSeg is currently too small (on now & millenium) for this to work */ TI_INLINE(bulk_store_request) void bulk_store_request(tic_amtoken_t token, void *buf, size_t len, Counter *ctr) { __incr_ctr_size(ctr, len); TIC_NULL_REPLY(token); } TIC_AMLONG(bulk_store_request, 1, 2, (token,addr,nbytes, (Counter *)TIC_AMRECV_PTR32(a0) ), (token,addr,nbytes, (Counter *)TIC_AMRECV_PTR64(a0, a1))); #else TI_INLINE(bulk_store_request) void bulk_store_request(tic_amtoken_t token, void *buf, size_t len, void *destaddr, Counter *ctr) { memcpy(destaddr, buf, len); __incr_ctr_size(ctr, len); TIC_NULL_REPLY(token); } TIC_AMMEDIUM(bulk_store_request, 2, 4, (token,addr,nbytes, TIC_AMRECV_PTR32(a0), (Counter *)TIC_AMRECV_PTR32(a1) ), (token,addr,nbytes, TIC_AMRECV_PTR64(a0, a1), (Counter *)TIC_AMRECV_PTR64(a2, a3))); #endif /* HUGE_SEGMENTS */ #endif /* AMII */ /* STORE bulk */ void __store(jGPointer gPtr, void *lPtr, int len) { __bulk_store_ctr(gPtr, lPtr, len, TIC_TRANSLATE_CSTATIC_ADDR(&recvBytes,tobox(gPtr)), &sentBytes); } void __bulk_store_ctr(jGPointer gPtr, void *lPtr, int len, Counter *rbytes, Counter *sbytes) { int box = tobox(gPtr); void *addr = tolocal(gPtr); if(box == MYBOX) { __incr_ctr_size(sbytes, len); memcpy(addr,lPtr, len); __incr_ctr_size(rbytes, len); } #ifdef COMM_AM2 #if AM2_HAS_HUGE_SEGMENTS /* AM_MaxSeg is currently too small (on now & millenium) for this to work */ else { int i; if (len <= TIC_AM_MAX_LONG_REQUEST) { tic_AMRequestXfer(1,2,(box, (jUIntPointer)(((char*)addr)-TIC_AM_SEGOFFSET), TIC_AMIDX(bulk_store_request), (void *)lPtr, len, TIC_AMSEND_PTR(rbytes))); } else { for (i = TIC_AM_MAX_LONG_REQUEST; i < len; i += TIC_AM_MAX_LONG_REQUEST) { tic_AMRequestXfer(1,2,(box, (jUIntPointer)(((char*)addr)-TIC_AM_SEGOFFSET), TIC_AMIDX(bulk_store_request), (void *)lPtr, TIC_AM_MAX_LONG_REQUEST, TIC_AMSEND_PTR(rbytes))); (*(char **)&addr) += TIC_AM_MAX_LONG_REQUEST; (*(char **)&lPtr) += TIC_AM_MAX_LONG_REQUEST; } i -= TIC_AM_MAX_LONG_REQUEST; tic_AMRequestXfer(1,2,(box, (jUIntPointer)(((char*)addr)-TIC_AM_SEGOFFSET), TIC_AMIDX(bulk_store_request), (void *)lPtr, len - i, TIC_AMSEND_PTR(rbytes))); } __incr_ctr_size(sbytes, len); } #else else { int i; if (len <= TIC_AM_MAX_MEDIUM) { tic_AMRequestI(2,4,(box, TIC_AMIDX(bulk_store_request), (void *)lPtr, len, TIC_AMSEND_PTR(addr), TIC_AMSEND_PTR(rbytes))); } else { for (i = TIC_AM_MAX_MEDIUM; i < len; i += TIC_AM_MAX_MEDIUM) { tic_AMRequestI(2,4,(box, TIC_AMIDX(bulk_store_request), (void *)lPtr, TIC_AM_MAX_MEDIUM, TIC_AMSEND_PTR(addr), TIC_AMSEND_PTR(rbytes))); (*(char **)&addr) += TIC_AM_MAX_MEDIUM; (*(char **)&lPtr) += TIC_AM_MAX_MEDIUM; } i -= TIC_AM_MAX_MEDIUM; tic_AMRequestI(2,4,(box, TIC_AMIDX(bulk_store_request), (void *)lPtr, len - i, TIC_AMSEND_PTR(addr), TIC_AMSEND_PTR(rbytes))); } __incr_ctr_size(sbytes, len); } #endif #endif /* AMII */ }