00001 #ifndef _GNU_SOURCE
00002 #define _GNU_SOURCE
00003 #endif
00004 #include <sys/uio.h>
00005
00006
00007 int CmiInitCma() {
00008 char buffer = '0';
00009 int cma_works = 0;
00010 int fd;
00011
00012
00013 fd = open("/proc/sys/kernel/yama/ptrace_scope", O_RDONLY);
00014 if (0 <= fd) {
00015 if (read (fd, &buffer, 1) != 1) {
00016 CmiAbort("CMA> reading /proc/sys/kernel/yama/ptrace_scope failed!");
00017 }
00018 close(fd);
00019 }
00020
00021 if('0' != buffer) {
00022 #if defined PR_SET_PTRACER
00023
00024 int ret = prctl (PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
00025 if (0 == ret) {
00026 cma_works = 1;
00027 }
00028 #endif
00029 } else {
00030 cma_works = 1;
00031 }
00032 return cma_works;
00033 }
00034
00035
00036 void CmiDisplayCMAThresholds(int cma_min_threshold, int cma_max_threshold) {
00037 if(_Cmi_mynode == 0) {
00038 if(cma_min_threshold > cma_max_threshold) {
00039 CmiAbort("CMA size thresholds incorrect! Values should satisfy cma_min_threshold <= cma_min_threshold condition");
00040 }
00041 CmiPrintf("Charm++> CMA enabled for within node transfers of messages(sized between %d & %d bytes)\n", cma_min_threshold, cma_max_threshold);
00042 }
00043 }
00044
00045
00046
00047
00048 int readShmCma(
00049 pid_t remote_pid,
00050 struct iovec *local,
00051 struct iovec *remote,
00052 int numOps,
00053 size_t total_bytes) {
00054
00055 int nread = process_vm_readv(remote_pid, local, numOps, remote, numOps, 0);
00056 if(nread != total_bytes) {
00057 CmiAbort("process_vm_readv failed!\n");
00058 return errno;
00059 }
00060 return 0;
00061 }
00062
00063
00064
00065
00066 int writeShmCma(
00067 pid_t remote_pid,
00068 struct iovec *local,
00069 struct iovec *remote,
00070 int numOps,
00071 size_t total_bytes) {
00072
00073 int nread = process_vm_writev(remote_pid, local, numOps, remote, numOps, 0);
00074 if(nread != total_bytes) {
00075 CmiAbort("process_vm_writev failed!\n");
00076 return errno;
00077 }
00078 return 0;
00079 }
00080
00081
00082 typedef struct _cma_src_buffer_info {
00083 int srcPE;
00084 pid_t srcPid;
00085 void *srcAddr;
00086 int size;
00087 }CmaSrcBufferInfo_t;
00088
00089
00090
00091
00092 void handleOneCmaMdMsg(int *sizePtr, char **msgPtr) {
00093 struct iovec local, remote;
00094 char *destAddr;
00095
00096
00097 CmaSrcBufferInfo_t *bufInfo = (CmaSrcBufferInfo_t *)(*msgPtr + CmiMsgHeaderSizeBytes);
00098
00099
00100 destAddr = (char *)CmiAlloc(bufInfo->size);
00101
00102 local.iov_base = (void *)destAddr;
00103 local.iov_len = bufInfo->size;
00104
00105 remote.iov_base = bufInfo->srcAddr;
00106 remote.iov_len = bufInfo->size;
00107
00108
00109 readShmCma(bufInfo->srcPid,
00110 &local,
00111 &remote,
00112 1,
00113 bufInfo->size);
00114
00115
00116
00117 CMI_CMA_MSGTYPE(*msgPtr) = CMK_CMA_ACK_MSG;
00118
00119 CmiInterSendNetworkFunc(bufInfo->srcPE,
00120 CmiMyPartition(),
00121 CmiMsgHeaderSizeBytes + sizeof(CmaSrcBufferInfo_t),
00122 *msgPtr,
00123 P2P_SYNC);
00124
00125
00126 *msgPtr = destAddr;
00127
00128 *sizePtr = local.iov_len;
00129 }
00130
00131
00132
00133
00134 void handleOneCmaAckMsg(int size, void *msg) {
00135
00136
00137 CmaSrcBufferInfo_t *bufInfo = (CmaSrcBufferInfo_t *)((char *)msg + CmiMsgHeaderSizeBytes);
00138
00139
00140 CmiFree(bufInfo->srcAddr);
00141
00142
00143 CmiFree(msg);
00144 }
00145
00146
00147
00148
00149 void CmiSendMessageCma(char **msgPtr, int *sizePtr) {
00150
00151
00152
00153 char *cmaBufMdMsg = (char *)CmiAlloc(CmiMsgHeaderSizeBytes + sizeof(CmaSrcBufferInfo_t));
00154 CmaSrcBufferInfo_t *bufInfo = (CmaSrcBufferInfo_t *)(cmaBufMdMsg + CmiMsgHeaderSizeBytes);
00155 bufInfo->srcPE = CmiMyPe();
00156 bufInfo->srcPid = getpid();
00157 bufInfo->srcAddr = *msgPtr;
00158 bufInfo->size = *sizePtr;
00159
00160
00161 CMI_CMA_MSGTYPE(cmaBufMdMsg) = CMK_CMA_MD_MSG;
00162
00163
00164 *sizePtr = CmiMsgHeaderSizeBytes + sizeof(CmaSrcBufferInfo_t);
00165
00166
00167 *msgPtr = (char *)cmaBufMdMsg;
00168 }