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