00001 #include <stdio.h>
00002 #include <string.h>
00003
00004 #include <moc.h>
00005 #include <internal/imoc.h>
00006 #include <internal/ppu/imoc_macros_ppu.h>
00007 #include <internal/ppu/imoc_dma_ppu.h>
00008 #include <internal/ppu/imoc_core_ppu.h>
00009
00010 int MOC_Ssend(void* buf, int count, MOC_Datatype datatype, int dest, int tag,
00011 MOC_Comm comm)
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 IMOC_TEST_PROC_NULL(dest)
00024 IMOC_TEST_PROC_SELF(dest)
00025 IMOC_TEST_BYTECOUNT(bytecount)
00026
00027 if (bytecount != 0)
00028 {
00029 IMOC_TEST_BUFFER(buf)
00030 }
00031 IMOC_TEST_RANK(dest)
00032 IMOC_TEST_TAG_SEND(tag)
00033 IMOC_TEST_COMM_SEND(comm)
00034
00035
00036 if (node_handle.queue_size * sizeof(moc_message_envelope_t)
00037 > MEMCPY_GET_TRESHOLD)
00038 {
00039 err = spe_mfcio_put(
00040 moc_spu_thread_list[dest - moc_ppu_thread_count].speid,
00041 IMOC_LS_REMOTE_QUEUE(dest), queue_copy, node_handle.queue_size
00042 * sizeof(moc_message_envelope_t), 15, 0, 0);
00043 if (err)
00044 return MOC_ERR_INTERN;
00045 err = spe_mfcio_tag_status_read(moc_spu_thread_list[dest
00046 - moc_ppu_thread_count].speid, 0, SPE_TAG_ALL, &dmastatus);
00047 if (err)
00048 return MOC_ERR_INTERN;
00049 }
00050 else
00051 {
00052 memcpy(queue_copy, (void*) IMOC_EA_REMOTE_QUEUE(dest),
00053 node_handle.queue_size * sizeof(moc_message_envelope_t));
00054 }
00055
00056
00057 err = IMOC_getFreeEntry(queue_copy, tag, comm, 0, &queue_index);
00058 if (err)
00059 return err;
00060
00061
00062 err = IMOC_getFreeMID(&msg_id);
00063 if (err)
00064 return err;
00065
00066
00067 if (bytecount <= 8)
00068 {
00069 queue_copy[queue_index].flags.bits.channel = IMOC_MESSAGE_CHANNEL_ENV;
00070
00071
00072 queue_copy[queue_index].flags.bits.signal_back = 1;
00073 queue_copy[queue_index].flags.bits.in_mm = 0;
00074 memcpy(&queue_copy[queue_index].message_address, buf, bytecount);
00075 }
00076 else
00077 {
00078 IMOC_TEST_ALIGNMENT(buf)
00079 queue_copy[queue_index].flags.bits.channel = IMOC_MESSAGE_CHANNEL_DMA;
00080 queue_copy[queue_index].flags.bits.signal_back = 1;
00081 queue_copy[queue_index].flags.bits.in_mm = 1;
00082 queue_copy[queue_index].message_address = (uint64_t) buf;
00083 }
00084
00085
00086 queue_copy[queue_index].communicator = comm;
00087 queue_copy[queue_index].datatype = datatype;
00088 queue_copy[queue_index].id = msg_id;
00089 queue_copy[queue_index].size = bytecount;
00090 queue_copy[queue_index].tag = tag;
00091 queue_copy[queue_index].flags.bits.collaborative = 0;
00092 queue_copy[queue_index].flags.bits.special = 0;
00093 queue_copy[queue_index].flags.bits.valid = 1;
00094 queue_copy[queue_index].flags.bits.keep_valid = 0;
00095
00096
00097 node_handle.status_array_base[msg_id].flags.bits.valid = 1;
00098 node_handle.status_array_base[msg_id].flags.bits.outstanding = 1;
00099
00100
00101
00102 memcpy((void*) IMOC_EA_REMOTE_QUEUE_ENTRY(dest, queue_index),
00103 &queue_copy[queue_index], sizeof(moc_message_envelope_t));
00104
00105 IMOC_waitForMessageCompletion(msg_id);
00106 return MOC_SUCCESS;
00107 }