00001 #include "charm++.h"
00002 #include "ckIgetControl.h"
00003 #ifndef WIN32
00004 #include <sys/time.h>
00005 #include <sys/resource.h>
00006 #endif
00007 #include <unistd.h>
00008 #include <sys/types.h>
00009
00010 IGetControlClass TheIGetControlClass;
00011 int IGET_TOTALMEMORY = 480000000;
00012
00013 #if IGET_FLOWCONTROL==0
00014 #elif CKFUTURE_IGET
00015
00016 int getAvailMemory(int grainsize);
00017
00018 int
00019 IGetControlClass::IGetControlClass::iget_request(CkIGetID fut, void *msg,
00020 int ep, CkArrayID id, CkArrayIndex idx,
00021 void(*fptr)(CkArrayID,CkArrayIndex,void*,int,int),int msgsize)
00022 {
00023 if(msgsize>0) IGET_UNITMESSAGE=msgsize;
00024 int ret_status=1, size=1;
00025 if(iget_token>=size){
00026 iget_token-=size;
00027 iget_outstanding++;
00028
00029 }
00030 else
00031 {
00032 iget_tokenqueue_enqueue(fut,msg,ep,id,idx,fptr);
00033 ret_status = 0;
00034 }
00035 return ret_status;
00036 }
00037
00038 void
00039 IGetControlClass::iget_free(int size)
00040 {
00041 iget_token+=size;
00042 iget_outstanding--;
00043
00044 iget_tokenqueue_entry e=iget_tokenqueue_dequeue();
00045 if(e!=NULL)
00046 {
00047 iget_token-=size;
00048 iget_outstanding++;
00049
00050 (e->fptr)(e->aid, e->idx, e->m, e->ep, 0);
00051 delete e;
00052 }
00053 }
00054
00055 void
00056 IGetControlClass::iget_updateTokenNum() {
00057 double currenttime = CmiWallTimer();
00058 if(currenttime-lastupdatetime<1)
00059 return;
00060 int totalMemUsed = (int)getRSS();
00061 if(totalMemUsed<=0) return;
00062 int leftMem = IGET_TOTALMEMORY-totalMemUsed;
00063 int iget_token_new = (leftMem)/(int)IGET_UNITMESSAGE;
00064 if(leftMem<0 || iget_token_new<IGET_MINTOKENNUM) {lastupdatetime =
00065 currenttime;return;}
00066
00067 lastupdatetime = currenttime;
00068 iget_token_history = iget_token ;
00069 iget_token = iget_token_new - iget_outstanding;
00070 if(iget_token<0) iget_token=0;
00071
00072 printf("availMem %d, IGET_UNIT %d, out_standinging %d\n",
00073 (leftMem), IGET_UNITMESSAGE, iget_outstanding);
00074 printf("Update Token num from %d to %d\n", iget_token_history, iget_token);
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void
00106 IGetControlClass::iget_resend(CkIGetID fut)
00107 {
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126 int
00127 getAvailMemory(int grainsize)
00128 {
00129
00130 struct rusage ru;
00131 double a = 1;
00132 int chunk = 50*1024*1024;
00133 int subchunk = 20*1024*1024;
00134 unsigned long size = chunk;
00135 char *data = NULL, *olddata = NULL;
00136 unsigned long init_pf = 0;
00137 int pagesize = getpagesize();
00138
00139
00140
00141
00142
00143
00144
00145
00146 while (1) {
00147 olddata = data;
00148 data = (char *)realloc(data, size);
00149 if (data == NULL) break;
00150 for (int i=size-chunk; i<size; i+=pagesize) data[i]=i;
00151 for (int i=0; i<size; i+=pagesize) a += data[i];
00152 getrusage(RUSAGE_SELF, &ru);
00153 if (size == chunk)
00154 init_pf = ru.ru_majflt;
00155 else
00156 if (ru.ru_majflt > init_pf) break;
00157 size += chunk;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 free(olddata);
00178 return size;
00179 }
00180
00181 extern "C"
00182 void getAvailSysMem() {
00183 IGET_TOTALMEMORY = getAvailMemory(0);
00184 printf("total physical memory : %d\n", IGET_TOTALMEMORY);
00185 }
00186
00187 extern "C"
00188 void TokenUpdatePeriodic()
00189 {
00190 TheIGetControlClass.iget_updateTokenNum();
00191 }
00192
00193 extern "C"
00194 int getRSS()
00195 {
00196 int ret=-1, i=0;
00197 pid_t pid;
00198 char filename[128], commands[256], retstring[128];
00199 int fd;
00200 pid = getpid();
00201 sprintf(filename,"__topmem__%d", CkMyPe());
00202 sprintf(commands, "export TERM=vt100; top -b -n 1 -p %d |grep %d | awk -F' ' '{print $6}' > %s", pid,
00203 pid, filename);
00204 system(commands);
00205 i=0;
00206 while(i<10){
00207 i++;
00208 fd = open(filename, O_RDONLY);
00209 if(fd>=0) break;
00210 else
00211 printf("fileopen %s fails, try again\n", filename);
00212 }
00213 if(fd<0){
00214 printf("fileopen %s fails, abort\n", filename); return -1;
00215 }
00216 lseek(fd, 0, SEEK_SET);
00217 i=0;
00218 while(read(fd, &retstring[i], sizeof(char))>0) i++;
00219 close(fd);
00220 ret = atoi(retstring);
00221 if(i>2){
00222 if(retstring[i-2]=='m') ret *= 1024*1024;
00223 if(retstring[i-2]=='k') ret *= 1024;
00224 }
00225
00226
00227 printf("RSS %d\n",ret);
00228 return ret;
00229 }
00230
00231 #endif
00232