00001 #include <string.h>
00002 #include <stdio.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_dma_ppu.h>
00009 #include <internal/ppu/imoc_core_ppu.h>
00010
00011 int MOC_Recv(void* buf, int count, MOC_Datatype datatype, int source, int tag,
00012 MOC_Comm comm, MOC_Status *status)
00013 {
00014
00015 moc_message_envelope_t* sourceQueueEntry;
00016 moc_message_status_t sourceMessageStatus __attribute__((__aligned__(16)));
00017 int bytecount, err;
00018
00019 err = 0;
00020 if (((datatype & 0xF0) >> 4) == 0)
00021 bytecount = count;
00022 else
00023 bytecount = count * (((datatype & 0xF0) >> 4) * 2);
00024
00025 status->MOC_SOURCE = source;
00026 status->message_size = bytecount;
00027
00028 IMOC_TEST_PROC_NULL(source)
00029 IMOC_TEST_PROC_SELF(source)
00030 IMOC_TEST_BYTECOUNT(bytecount)
00031
00032 if (bytecount != 0)
00033 {
00034 IMOC_TEST_BUFFER(buf)
00035 }
00036 IMOC_TEST_RANK_RECV(source)
00037 IMOC_TEST_TAG_RECV(tag)
00038 IMOC_TEST_COMM_RECV(comm)
00039
00040
00041 sourceQueueEntry = NULL;
00042 while (sourceQueueEntry == NULL)
00043 {
00044 sourceQueueEntry = IMOC_get_entry(source, tag, comm, 0, status);
00045 }
00046
00047 status->MOC_TAG = tag;
00048 status->mid = sourceQueueEntry->id;
00049
00050
00051 if (sourceQueueEntry->datatype != datatype && sourceQueueEntry->datatype
00052 !=MOC_BYTE && datatype != MOC_BYTE)
00053 {
00054 status->MOC_ERROR = MOC_ERR_TYPE;
00055 return MOC_ERR_TYPE;
00056 }
00057
00058
00059 if (sourceQueueEntry->flags.bits.channel == IMOC_MESSAGE_CHANNEL_ENV)
00060 {
00061
00062 memcpy(buf, (void*) &sourceQueueEntry->message_address, (bytecount
00063 < sourceQueueEntry->size) ? bytecount : sourceQueueEntry->size);
00064 }
00065 else
00066 if (sourceQueueEntry->flags.bits.channel == IMOC_MESSAGE_CHANNEL_DMA)
00067 {
00068
00069 if (sourceQueueEntry->flags.bits.in_mm == 1)
00070
00071 memcpy(buf, (void*) sourceQueueEntry->message_address,
00072 bytecount);
00073 else
00074 {
00075
00076 uint32_t lsa =
00077 sourceQueueEntry->message_address
00078 - moc_spu_thread_list[source
00079 - moc_ppu_thread_count].ls_base;
00080 if (bytecount != 0)
00081 {
00082 IMOC_TEST_ALIGNMENT(buf)
00083 }
00084
00085 err = IMOC_get_data(buf, lsa, bytecount, source);
00086 if (err)
00087 {
00088 return err;
00089 }
00090 }
00091 }
00092 else
00093 {
00094
00095 status->MOC_ERROR = MOC_ERR_INTERN;
00096 return MOC_ERR_INTERN;
00097 }
00098
00099 if (sourceQueueEntry->flags.bits.signal_back == 1)
00100 {
00101
00102 sourceMessageStatus.buffer_offset = 0;
00103 sourceMessageStatus.flags.value = 0;
00104 if (sourceQueueEntry->flags.bits.keep_valid)
00105 sourceMessageStatus.flags.bits.valid = 1;
00106
00107
00108
00109 memcpy(
00110 (void*) IMOC_EA_REMOTE_STATUS_ENTRY(sourceQueueEntry->id,status->MOC_SOURCE),
00111 &sourceMessageStatus, sizeof(moc_message_status_t));
00112 }
00113
00114 sourceQueueEntry->flags.value = 0;
00115
00116 status->MOC_ERROR = 0;
00117 return 0;
00118 }