00001 #include <string.h>
00002 #include <stdio.h>
00003 #include <spu_mfcio.h>
00004
00005 #include <moc.h>
00006 #include <spu/moc_datatype_spu.h>
00007 #include <internal/imoc.h>
00008 #include <internal/imoc_macros.h>
00009 #include <internal/spu/imoc_dma_spu.h>
00010 #include <internal/spu/imoc_core_spu.h>
00011
00012 int MOC_ISsend(void* buf, int count, MOC_Datatype datatype, int dest, int tag,
00013 MOC_Comm comm, MOC_Request *request)
00014 {
00015 int queue_index, msg_id, bytecount, err;
00016 moc_message_envelope_t queue_copy[node_handle.queue_size] __attribute__((__aligned__(16)));
00017
00018 uint32_t tag_id;
00019
00020 if (((datatype & 0xF0) >> 4) == 0)
00021 bytecount = count;
00022 else
00023 bytecount = count * (((datatype & 0xF0) >> 4) * 2);
00024
00025 request->request_type = MOC_REQ_TYPE_ISSEND;
00026 request->request_data.issend_request.isFinished = 1;
00027 request->request_data.issend_request.source = node_handle.rank;
00028 request->request_data.issend_request.tag = tag;
00029 request->request_data.issend_request.message_size = bytecount;
00030
00031 IMOC_TEST_PROC_NULL(dest)
00032 IMOC_TEST_PROC_SELF(dest)
00033 IMOC_TEST_BYTECOUNT(bytecount)
00034
00035 if (bytecount != 0)
00036 {
00037 IMOC_TEST_BUFFER(buf)
00038 if (bytecount > 16)
00039 IMOC_TEST_ALIGNMENT(buf)
00040 }
00041 IMOC_TEST_RANK(dest)
00042 IMOC_TEST_TAG_SEND(tag)
00043 IMOC_TEST_COMM_SEND(comm)
00044
00045 if ((tag_id = mfc_tag_reserve()) == MFC_TAG_INVALID)
00046 {
00047 return MOC_ERR_INTERN;
00048 }
00049
00050 mfc_get(queue_copy, IMOC_EA_REMOTE_QUEUE(dest),
00051 sizeof(moc_message_envelope_t) * node_handle.queue_size, tag_id, 0,
00052 0);
00053 mfc_write_tag_mask(1 << tag_id);
00054 mfc_read_tag_status_all();
00055
00056 err = IMOC_getFreeEntry(queue_copy, tag, comm, 0, &queue_index);
00057 if (err)
00058 return err;
00059
00060 err = IMOC_getFreeMID(&msg_id);
00061 if (err)
00062 return err;
00063
00064
00065 if (bytecount <= 8)
00066 {
00067
00068 queue_copy[queue_index].flags.bits.channel = IMOC_MESSAGE_CHANNEL_ENV;
00069
00070
00071 queue_copy[queue_index].flags.bits.signal_back = 1;
00072 queue_copy[queue_index].flags.bits.in_mm = 0;
00073 memcpy(&queue_copy[queue_index].message_address, buf, bytecount);
00074 }
00075 else
00076 {
00077 queue_copy[queue_index].flags.bits.channel = IMOC_MESSAGE_CHANNEL_DMA;
00078 queue_copy[queue_index].flags.bits.signal_back = 1;
00079 queue_copy[queue_index].flags.bits.in_mm = 0;
00080 queue_copy[queue_index].message_address = node_handle.ls_base
00081 + (uint32_t) buf;
00082 }
00083
00084
00085 queue_copy[queue_index].communicator = comm;
00086 queue_copy[queue_index].datatype = datatype;
00087 queue_copy[queue_index].id = msg_id;
00088 queue_copy[queue_index].size = bytecount;
00089 queue_copy[queue_index].tag = tag;
00090 queue_copy[queue_index].flags.bits.collaborative = 0;
00091 queue_copy[queue_index].flags.bits.special = 0;
00092 queue_copy[queue_index].flags.bits.valid = 1;
00093 queue_copy[queue_index].flags.bits.keep_valid = 1;
00094
00095
00096 node_handle.status_array_base[msg_id].flags.bits.valid = 1;
00097 node_handle.status_array_base[msg_id].flags.bits.outstanding = 1;
00098
00099 mfc_put(&queue_copy[queue_index], IMOC_EA_REMOTE_QUEUE_ENTRY(dest,
00100 queue_index), sizeof(moc_message_envelope_t), tag_id, 0, 0);
00101 mfc_write_tag_mask(1 << tag_id);
00102 mfc_read_tag_status_all();
00103 mfc_tag_release(tag_id);
00104
00105 request->request_data.issend_request.isFinished = 0;
00106 request->request_data.issend_request.mid = msg_id;
00107
00108 return MOC_SUCCESS;
00109 }
00110