static void findStartsWith(FILE *my_file,char *starts, char *buffer){ int starts_len = strlen(starts); int match = 1; do { ReadFileLine(buffer, BUFFER_SIZE, my_file); match = strncmp(starts, buffer, starts_len); } while (match != 0); }
void AsyncStream::SendThreadName(void) { ThreadNamePacket packet = {0}; char name[64] = {0}; #if defined(OVR_CAPTURE_ANDROID) char commpath[64] = {0}; sprintf(commpath, "/proc/%d/task/%d/comm", getpid(), gettid()); ReadFileLine(commpath, name, sizeof(name)); #elif defined(OVR_CAPTURE_DARWIN) pthread_getname_np(pthread_self(), name, sizeof(name)); #endif if(name[0]) { WritePacket(packet, name, strlen(name)); } }
const char *GetAName(const char *szNameFile) { // always eat the Random-value, so having or not having a Names.txt makes no difference int iName = Random(1000); FILE *hNamefile; if (!szNameFile) return "Clonk"; if (!(hNamefile=fopen(szNameFile,"r"))) return "Clonk"; for (int iCnt=0; iCnt<iName; iCnt++) AdvanceFileLine(hNamefile); GetANameBuffer[0]=0; int iLoops=0; do { if (!ReadFileLine(hNamefile,GetANameBuffer,C4MaxName)) { rewind(hNamefile); iLoops++; } } while ((iLoops<2) && (!GetANameBuffer[0] || (GetANameBuffer[0]=='#') || (GetANameBuffer[0]==' '))); fclose(hNamefile); if (iLoops>=2) return "Clonk"; return GetANameBuffer; }
int main(int argc, char *argv[]){ int i=0, j, k=0, line_count,l, p, q, x, y, targetCore; char c; char *inFileName; char outFileName[100]; FILE *pInFile; char conFile[100]; FILE *pConFile,*pOutFile; mod_prec* iAppArray= NULL; int simStep = 0, inputFromFile = 0, initSteps,total_simulation_steps; float simTime = 0; cellState **cellPtr; cellCompParams *cellParamsPtr; int seedvar; char tempbuf[100]; mod_prec iApp; mod_prec *gcal; int *init_steps; long double seconds; int simulation_array_ID,target_cell; sprintf(outFileName,"InferiorOlive_Output.txt"); sprintf(conFile,"cellConnections.txt"); IO_NETWORK_SIZE = atoi(argv[1]); /* compute how many grid cells * are assigned to each core */ cellCount= IO_NETWORK_SIZE; /* Process command line arguments * Case argc = 2 then a one-pulse input is stimulated. * Otherwise we receive input from a specified file in argv[2] and simulation runs accordingly * in the case of inputFromFile, we will also need a buffer to hold the stimulus * for each cell on each step */ if(argc == 2) { inputFromFile = 0; } else if(argc == 3) { inputFromFile = 1; inFileName = argv[2]; pInFile = fopen(inFileName,"r"); if(pInFile==NULL) { printf("Error: Couldn't open %s\n", inFileName); exit(EXIT_FAILURE); } iAppArray= (mod_prec*) malloc(cellCount*(sizeof(mod_prec))); } else { printf("Error: Too many arguments.\nUsage: ./InferiorOlive <dimNW> <Iapp_input_file> or ./InferiorOlive <dimNW>\n"); exit(EXIT_FAILURE); } /* PRINTING is true in case we want to write the * output to a specified file (outFileName) */ if (PRINTING) { pOutFile = fopen(outFileName,"w+"); if(pOutFile==NULL){ printf("Error: Couldn't create %s\n", outFileName); exit(EXIT_FAILURE); } sprintf(tempbuf, "#simSteps Time(ms) Input(Iapp) Output(V_axon)"); fputs(tempbuf, pOutFile); } /* CellPtr is a 2-D array of size 2*CellCount * and containd cell states used in every simulation * step accordingly */ cellPtr = malloc(2*sizeof(cellState *)); if(cellPtr==NULL){ printf("Error: Couldn't malloc for cellPtr\n"); exit(EXIT_FAILURE); } cellPtr[0] = malloc(cellCount*sizeof(cellState)); cellPtr[1] = malloc(cellCount*sizeof(cellState)); if ((!cellPtr[0])||(!cellPtr[1])) { printf("Error: Couldn't malloc the array for cellStates\n"); exit(EXIT_FAILURE); } /* cellCompParams struct is used to update a cell state. * It contains the current flowing to this specific cell * voltages from communicating cells , and pointers to the previous * cell state and to the next cell state * We allocate cellCount cellCompParams for all the core's cells * Pointer to previous and next states are pointers to CellPtr[0] and CellPtr[1] * elements. */ cellParamsPtr = malloc(cellCount*sizeof(cellCompParams)); if(cellParamsPtr==NULL){ printf("Error: Couldn't malloc for cellParamsPtr\n"); exit(EXIT_FAILURE); } for (i=0;i<cellCount;i++) //initial amount of neighbours for each cell is 0 (bug fix in case the cell stays isolated) cellParamsPtr[i].total_amount_of_neighbours = 0; int line_counter; mod_prec cond_value; pConFile = fopen(conFile, "r"); if(pConFile==NULL){ printf("Error: Couldn't create %s\n", conFile); exit(EXIT_FAILURE); } //handle connectivity file parsing so that each cell knows what it needs for (line_counter=0;line_counter<IO_NETWORK_SIZE;line_counter++) { for (i=0; i<IO_NETWORK_SIZE; i++) { fscanf(pConFile, "%lf ", &cond_value); if (cond_value==0) //this connection is considered not existing if conductance = 0 ; else { //part of the code handling RECEIVING and noting which of my cells needs input from which other cells, from ANY core if (cellParamsPtr[i].total_amount_of_neighbours == 0) { //if this is the first neighbour, initialize buffers cellParamsPtr[i].neighVdend = NULL; cellParamsPtr[i].neighConductances = NULL; cellParamsPtr[i].neighId = NULL; } cellParamsPtr[i].neighId = allocate_space_int(cellParamsPtr[i].neighId, cellParamsPtr[i].total_amount_of_neighbours); cellParamsPtr[i].neighId[cellParamsPtr[i].total_amount_of_neighbours] = line_counter;//which cell sends this voltage to us (GLOBAL ID) cellParamsPtr[i].neighConductances = allocate_space_mod(cellParamsPtr[i].neighConductances, cellParamsPtr[i].total_amount_of_neighbours); cellParamsPtr[i].neighConductances[cellParamsPtr[i].total_amount_of_neighbours] = cond_value; //what conductance we use to calculate its impact cellParamsPtr[i].neighVdend = allocate_space_mod(cellParamsPtr[i].neighVdend, cellParamsPtr[i].total_amount_of_neighbours); //allocate space for storing this voltage cellParamsPtr[i].total_amount_of_neighbours++; // } } } } /* Initialise cellPtr[0] with appropriate values. */ initState(cellPtr[0]); if (PRINTING) { for (i=0;i<cellCount;i++) { sprintf(tempbuf, "%d ", cellPtr[0][i].cellID); fputs(tempbuf, pOutFile); } sprintf(tempbuf, "\n"); fputs(tempbuf, pOutFile); } //Initialize g_CaL seedvar = time(NULL); srand(seedvar); for(i=0;i<cellCount;i++){ cellPtr[1][i].soma.g_CaL = cellPtr[0][i].soma.g_CaL; if (RAND_INIT) { cellPtr[0][i].soma.g_CaL = 0.6+(0.2*(rand()%100)/100); cellPtr[1][i].soma.g_CaL = cellPtr[0][i].soma.g_CaL; } } //random initialization process if (RAND_INIT) { for(i=0;i<cellCount;i++) { initSteps = rand()%(int)ceil(100/DELTA); initSteps = initSteps | 0x00000001;//make it odd, so that the final state is in prevCellState for(j=0;j<initSteps;j++){ //Arrange inputs cellParamsPtr[i].iAppIn = 0;//No stimulus cellParamsPtr[i].prevCellState = &cellPtr[j%2][i]; cellParamsPtr[i].newCellState = &cellPtr[(j%2)^1][i]; CompDend(&cellParamsPtr[i], 1); CompSoma(&cellParamsPtr[i]); CompAxon(&cellParamsPtr[i]); } } } /* start of the simulation * In case we want to read the stimulus from file inputFromFile = true */ if(inputFromFile){ simStep = 0; /* Read full lines until end of file. * Every iteration (line) is one simulation step. */ while(ReadFileLine(pInFile, iAppArray)) { simulation_array_ID = simStep%2; if (PRINTING) { sprintf(tempbuf, "%d %.2f ", (simStep+1), simStep*0.05); // start @ 1 because skipping initial values fputs(tempbuf, pOutFile); } /* Perform_Communication() performs the inter core * core dendrite communication with connected cells * See definition for more details */ perform_communication_step(cellParamsPtr, cellPtr[simulation_array_ID]); for (target_cell=0;target_cell<cellCount;target_cell++) { cellParamsPtr[target_cell].iAppIn = iAppArray[target_cell]; cellParamsPtr[target_cell].prevCellState = &cellPtr[simulation_array_ID][target_cell]; cellParamsPtr[target_cell].newCellState = &cellPtr[simulation_array_ID^1][target_cell]; CompDend(&cellParamsPtr[target_cell], 0); CompSoma(&cellParamsPtr[target_cell]); CompAxon(&cellParamsPtr[target_cell]); if (PRINTING) { sprintf(tempbuf, "%.16f ", cellPtr[(simulation_array_ID)^1][target_cell].axon.V_axon); fputs(tempbuf, pOutFile); } } if (PRINTING) { sprintf(tempbuf, "\n"); fputs(tempbuf,pOutFile); } simStep++; } } else { simTime = SIMTIME; total_simulation_steps = (int)(simTime/DELTA); for(simStep=0;simStep<total_simulation_steps;simStep++) { simulation_array_ID = simStep%2; if ((simStep>=20000)&&(simStep<20500-1)) iApp = 6; else iApp = 0; if (PRINTING) { sprintf(tempbuf, " %d %.2f ", simStep+1, iApp); fputs(tempbuf, pOutFile); } /* Perform_Communication() performs the inter core * core dendrite communication with connected cells * See definition for more details */ perform_communication_step(cellParamsPtr, cellPtr[simulation_array_ID]); for (target_cell=0;target_cell<cellCount;target_cell++) { /* we simulate a hardcoded input pulse here * that differs from step to step */ cellParamsPtr[target_cell].iAppIn = iApp; cellParamsPtr[target_cell].prevCellState = &cellPtr[simulation_array_ID][target_cell]; cellParamsPtr[target_cell].newCellState = &cellPtr[simulation_array_ID^1][target_cell]; CompDend(&cellParamsPtr[target_cell], 0); CompSoma(&cellParamsPtr[target_cell]); CompAxon(&cellParamsPtr[target_cell]); if (PRINTING) { sprintf(tempbuf, "%d : %.8f ", target_cell+1, cellPtr[(simulation_array_ID)^1][target_cell].axon.V_axon); fputs(tempbuf, pOutFile); } } if (PRINTING) { sprintf(tempbuf, "\n"); fputs(tempbuf, pOutFile); } } simStep = total_simulation_steps; //so that simStep in the end has the exact value of how many steps we had in this sim, regardless of input method (useful to know which cellPtr has what) } /* Free memory and close files */ if (PRINTSTATE) { char resultFileName[50]; sprintf(resultFileName, "results/lastStateDump.txt"); printState(cellPtr[simStep%2], resultFileName); //simStep%2 here should refer to the cellPtr which has the last state of the network that we calculated } free(cellPtr[0]); free(cellPtr[1]); free(cellPtr); free(cellParamsPtr); if (PRINTING) { fclose (pOutFile); chmod(outFileName,0x01B6); } fclose(pConFile); if(inputFromFile) fclose (pInFile); return 0; }
void StandardSensors::OnThreadExecute(void) { // Pre-load what files we can... reduces open/close overhead (which is significant) // Setup CPU Clocks Support... FileHandle cpuOnlineFiles[g_maxCpus]; FileHandle cpuFreqFiles[g_maxCpus]; for(unsigned int i=0; i<g_maxCpus; i++) { cpuOnlineFiles[i] = cpuFreqFiles[i] = NullFileHandle; } if(CheckConnectionFlag(Enable_CPU_Zones)) { for(unsigned int i=0; i<g_maxCpus; i++) { const CpuSensorDesc &desc = g_cpuDescs[i]; cpuOnlineFiles[i] = OpenFile(desc.onlinePath); cpuFreqFiles[i] = NullFileHandle; if(cpuOnlineFiles[i] != NullFileHandle) { const int maxFreq = ReadIntFile(desc.maxFreqPath); SensorSetRange(desc.label, 0, (float)maxFreq, Sensor_Interp_Nearest, Sensor_Unit_KHz); } } } // Setup GPU Clocks Support... FileHandle gpuFreqFile = NullFileHandle; if(CheckConnectionFlag(Enable_GPU_Clocks)) { gpuFreqFile = OpenFile("/sys/class/kgsl/kgsl-3d0/gpuclk"); } if(gpuFreqFile != NullFileHandle) { const int maxFreq = ReadIntFile("/sys/class/kgsl/kgsl-3d0/max_gpuclk"); SensorSetRange(g_gpuLabel, 0, (float)maxFreq, Sensor_Interp_Nearest, Sensor_Unit_Hz); } // Setup Memory Clocks Support... FileHandle memFreqFile = NullFileHandle; //memFreqFile = OpenFile("/sys/class/devfreq/0.qcom,cpubw/cur_freq"); if(memFreqFile != NullFileHandle) { const int maxFreq = ReadIntFile("/sys/class/devfreq/0.qcom,cpubw/max_freq"); SensorSetRange(g_memLabel, 0, (float)maxFreq, Sensor_Interp_Nearest, Sensor_Unit_MByte_Second); } // Setup thermal sensors... static const unsigned int maxThermalSensors = 20; static ThermalSensorDesc thermalDescs[maxThermalSensors]; FileHandle thermalFiles[maxThermalSensors]; for(unsigned int i=0; i<maxThermalSensors; i++) { thermalFiles[i] = NullFileHandle; } if(CheckConnectionFlag(Enable_Thermal_Sensors)) { for(unsigned int i=0; i<maxThermalSensors; i++) { ThermalSensorDesc &desc = thermalDescs[i]; char typePath[64] = {0}; char tempPath[64] = {0}; char modePath[64] = {0}; sprintf(typePath, "/sys/devices/virtual/thermal/thermal_zone%d/type", i); sprintf(tempPath, "/sys/devices/virtual/thermal/thermal_zone%d/temp", i); sprintf(modePath, "/sys/devices/virtual/thermal/thermal_zone%d/mode", i); // If either of these files don't exist, then we got to the end of the thermal zone list... if(!CheckFileExists(typePath) || !CheckFileExists(tempPath)) break; // check to see if the zone is disabled... its okay if there is no mode file... char mode[16] = {0}; if(ReadFileLine(modePath, mode, sizeof(mode))>0 && !strcmp(mode, "disabled")) continue; if(!desc.initialized) { // Read the sensor name in... ReadFileLine(typePath, desc.name, sizeof(desc.name)); // Initialize the Label... desc.initialized = desc.label.ConditionalInit(desc.name); } // Finally... open the file. thermalFiles[i] = OpenFile(tempPath); if(thermalFiles[i] != NullFileHandle) { // by default 0 to 100 degrees... SensorSetRange(desc.label, 0, 100, Sensor_Interp_Linear); } } } // For clocks, we store the last value and only send updates when it changes since we // use blocking chart rendering. int lastCpuFreq[g_maxCpus] = {0}; int lastGpuFreq = 0; int lastMemValue = 0; unsigned int sampleCount = 0; while(!QuitSignaled() && IsConnected()) { // Sample CPU Frequencies... for(unsigned int i=0; i<g_maxCpus; i++) { // If the 'online' file can't be found, then we just assume this CPU doesn't even exist if(cpuOnlineFiles[i] == NullFileHandle) continue; const CpuSensorDesc &desc = g_cpuDescs[i]; const bool online = ReadIntFile(desc.onlinePath); if(online && cpuFreqFiles[i]==NullFileHandle) { // Open the frequency file if we are online and its not already open... cpuFreqFiles[i] = OpenFile(desc.freqPath); } else if(!online && cpuFreqFiles[i]!=NullFileHandle) { // close the frequency file if we are no longer online CloseFile(cpuFreqFiles[i]); cpuFreqFiles[i] = NullFileHandle; } const int freq = cpuFreqFiles[i]==NullFileHandle ? 0 : ReadIntFile(cpuFreqFiles[i]); if(freq != lastCpuFreq[i]) { // Convert from KHz to Hz SensorSetValue(desc.label, (float)freq); lastCpuFreq[i] = freq; } ThreadYield(); } // Sample GPU Frequency... if(gpuFreqFile != NullFileHandle) { const int freq = ReadIntFile(gpuFreqFile); if(freq != lastGpuFreq) { SensorSetValue(g_gpuLabel, (float)freq); lastGpuFreq = freq; } } // Sample Memory Bandwidth if(memFreqFile != NullFileHandle) { const int value = ReadIntFile(memFreqFile); if(value != lastMemValue) { SensorSetValue(g_memLabel, (float)value); lastMemValue = value; } } // Sample thermal sensors... if((sampleCount&15) == 0) // sample temperature at a much lower frequency as clocks... thermals don't change that fast. { for(unsigned int i=0; i<maxThermalSensors; i++) { FileHandle file = thermalFiles[i]; if(file != NullFileHandle) { SensorSetValue(thermalDescs[i].label, (float)ReadIntFile(file)); } } ThreadYield(); } // Sleep 5ms between samples... ThreadSleepMicroseconds(5000); sampleCount++; } // Close down cached file handles... for(unsigned int i=0; i<g_maxCpus; i++) { if(cpuOnlineFiles[i] != NullFileHandle) CloseFile(cpuOnlineFiles[i]); if(cpuFreqFiles[i] != NullFileHandle) CloseFile(cpuFreqFiles[i]); } if(gpuFreqFile != NullFileHandle) CloseFile(gpuFreqFile); if(memFreqFile != NullFileHandle) CloseFile(memFreqFile); for(unsigned int i=0; i<maxThermalSensors; i++) { if(thermalFiles[i] != NullFileHandle) CloseFile(thermalFiles[i]); } }
int main(int argc, char *argv[]){ FILE *pFileBase=NULL, *pFileTest=NULL; char fileBaseName[100]; char fileTestName[100]; float error, relative_error, max_error=0.0; float stored_v1, stored_v2; int index, line, stored_line, stored_index; int empty_results=1; if (argc!=2) { printf("Checker Error: Incorrect arguments.\nUsage: ./checker <nw_size>\n"); exit(EXIT_FAILURE); } int nw_size = atoi(argv[1]); float* matrixBase = (float*) calloc(nw_size, sizeof(float)); float* matrixTest = (float*) calloc(nw_size, sizeof(float)); sprintf(fileBaseName,"InferiorOlive_Output_Baseline.txt"); sprintf(fileTestName,"InferiorOlive_Output.txt"); pFileBase = fopen(fileBaseName,"r"); if (pFileBase==NULL) { printf("\nCould not locate baseline results file for regression test.\n"); exit(EXIT_FAILURE); } pFileTest = fopen(fileTestName,"r"); if (pFileTest==NULL) { printf("\nCould not locate build test results.\nCheck whether the new build compiles and runs properly.\n"); exit(EXIT_FAILURE); } line=1; while ((ReadFileLine(pFileBase, &matrixBase[0], nw_size))&&(ReadFileLine(pFileTest, &matrixTest[0], nw_size))) { for (index=0; index<nw_size; index++) { error = fabsf(matrixBase[index]-matrixTest[index]); relative_error = fabsf(error/matrixBase[index]); if (relative_error > max_error) { max_error = relative_error; stored_v1 = matrixBase[index]; stored_v2 = matrixTest[index]; stored_line = line; stored_index = index; } } line++; empty_results=0; } if (empty_results) { printf("Build test results file empty.\nCheck whether the new build compiles and runs properly.\n"); } else if (max_error>0.01) { printf("\nWarning! Maximum error found: %0.4f%%.\n", max_error*100); printf("Maximum discrepancy was found at line %d, neuron %d:\n", stored_line, stored_index); printf("Correct value: %0.8f - Runtime value: %0.8f.", stored_v1, stored_v2); } else { printf("\nCheck was passed successfully!\n"); } fclose(pFileBase); fclose(pFileTest); return 1; }
int main (int argc, char *argv[]) { int c; int ListProj=0, ListFolder=0; long DelUpload=0, DelFolder=0, DelLicense=0; int Scheduler=0; /* should it run from the scheduler? */ int GotArg=0; char *agent_desc = "Deletes upload. Other list/delete options available from the command line."; while((c = getopt(argc,argv,"ifF:lL:sTuU:v")) != -1) { switch(c) { case 'i': DB = DBopen(); if (!DB) { fprintf(stderr,"ERROR: Unable to open DB\n"); exit(-1); } GetAgentKey(DB, basename(argv[0]), 0, SVN_REV, agent_desc); DBclose(DB); return(0); case 'f': ListFolder=1; GotArg=1; break; case 'F': DelFolder=atol(optarg); GotArg=1; break; case 'L': DelLicense=atol(optarg); GotArg=1; break; case 'l': ListProj=1; GotArg=1; break; case 's': Scheduler=1; GotArg=1; break; case 'T': Test++; break; case 'u': ListProj=1; GotArg=1; break; case 'U': DelUpload=atol(optarg); GotArg=1; break; case 'v': Verbose++; break; default: Usage(argv[0]); exit(-1); } } if (!GotArg) { Usage(argv[0]); exit(-1); } DB = DBopen(); if (!DB) { fprintf(stderr,"ERROR: Unable to open DB\n"); exit(-1); } GetAgentKey(DB, basename(argv[0]), 0, SVN_REV, agent_desc); signal(SIGALRM,ShowHeartbeat); if (ListProj) ListUploads(); if (ListFolder) ListFolders(); alarm(60); /* from this point on, handle the alarm */ if (DelUpload) { DeleteUpload(DelUpload); } if (DelFolder) { DeleteFolder(DelFolder); } if (DelLicense) { DeleteLicense(DelLicense); } /* process from the scheduler */ if (Scheduler) { while(ReadFileLine(stdin) >= 0) ; } DBclose(DB); return(0); } /* main() */
void StandardSensors::OnThreadExecute(void) { SetThreadName("CaptureSensors"); // Pre-load what files we can... reduces open/close overhead (which is significant) // Setup CPU Clocks Support... static const UInt32 maxCpus = 8; static SensorLabelDesc cpuDescs[maxCpus]; FileHandle cpuOnlineFiles[maxCpus]; FileHandle cpuFreqFiles[maxCpus]; for(UInt32 i=0; i<maxCpus; i++) { cpuOnlineFiles[i] = cpuFreqFiles[i] = NullFileHandle; SensorLabelDesc &desc = cpuDescs[i]; FormatString(desc.name, sizeof(desc.name), "CPU%u Clocks", i); desc.label.ConditionalInit(desc.name); } if(CheckConnectionFlag(Enable_CPU_Zones)) { int maxFreq = 0; for(UInt32 i=0; i<maxCpus; i++) { char onlinePath[64] = {0}; FormatString(onlinePath, sizeof(onlinePath), "/sys/devices/system/cpu/cpu%u/online", i); cpuOnlineFiles[i] = OpenFile(onlinePath); cpuFreqFiles[i] = NullFileHandle; if(cpuOnlineFiles[i] != NullFileHandle) { char maxFreqPath[64] = {0}; FormatString(maxFreqPath, sizeof(maxFreqPath), "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_max_freq", i); maxFreq = std::max(maxFreq, ReadIntFile(maxFreqPath)); } } for(UInt32 i=0; i<maxCpus; i++) { const SensorLabelDesc &desc = cpuDescs[i]; SensorSetRange(desc.label, 0, (float)maxFreq, Sensor_Interp_Nearest, Sensor_Unit_KHz); } } // Setup GPU Clocks Support... FileHandle gpuFreqFile = NullFileHandle; if(CheckConnectionFlag(Enable_GPU_Clocks)) { if(gpuFreqFile == NullFileHandle) // Adreno { gpuFreqFile = OpenFile("/sys/class/kgsl/kgsl-3d0/gpuclk"); if(gpuFreqFile != NullFileHandle) { const int maxFreq = ReadIntFile("/sys/class/kgsl/kgsl-3d0/max_gpuclk"); SensorSetRange(g_gpuLabel, 0, (float)maxFreq, Sensor_Interp_Nearest, Sensor_Unit_Hz); } } if(gpuFreqFile == NullFileHandle) // Mali { gpuFreqFile = OpenFile("/sys/devices/14ac0000.mali/clock"); if(gpuFreqFile != NullFileHandle) { // TODO: query max GPU clocks on Mali, for now hacked to what we know the S6 is SensorSetRange(g_gpuLabel, 0, 0, Sensor_Interp_Nearest, Sensor_Unit_MHz); } } } // Setup Memory Clocks Support... FileHandle memFreqFile = NullFileHandle; //memFreqFile = OpenFile("/sys/class/devfreq/0.qcom,cpubw/cur_freq"); if(memFreqFile != NullFileHandle) { const int maxFreq = ReadIntFile("/sys/class/devfreq/0.qcom,cpubw/max_freq"); SensorSetRange(g_memLabel, 0, (float)maxFreq, Sensor_Interp_Nearest, Sensor_Unit_MByte_Second); } // Setup thermal sensors... static const UInt32 maxThermalSensors = 20; static SensorLabelDesc thermalDescs[maxThermalSensors]; FileHandle thermalFiles[maxThermalSensors]; for(UInt32 i=0; i<maxThermalSensors; i++) { thermalFiles[i] = NullFileHandle; } if(CheckConnectionFlag(Enable_Thermal_Sensors)) { for(UInt32 i=0; i<maxThermalSensors; i++) { SensorLabelDesc &desc = thermalDescs[i]; char typePath[64] = {0}; char tempPath[64] = {0}; char tripPointPath[64] = {0}; FormatString(typePath, sizeof(typePath), "/sys/devices/virtual/thermal/thermal_zone%u/type", i); FormatString(tempPath, sizeof(tempPath), "/sys/devices/virtual/thermal/thermal_zone%u/temp", i); FormatString(tripPointPath, sizeof(tripPointPath), "/sys/devices/virtual/thermal/thermal_zone%u/trip_point_0_temp", i); // If either of these files don't exist, then we got to the end of the thermal zone list... if(!CheckFileExists(typePath) || !CheckFileExists(tempPath) || !CheckFileExists(tripPointPath)) break; // Initialize the Label... if(ReadFileLine(typePath, desc.name, sizeof(desc.name)) <= 0) continue; // failed to read sensor name... desc.label.ConditionalInit(desc.name); char modePath[64] = {0}; FormatString(modePath, sizeof(modePath), "/sys/devices/virtual/thermal/thermal_zone%d/mode", i); // check to see if the zone is disabled... its okay if there is no mode file... char mode[16] = {0}; if(ReadFileLine(modePath, mode, sizeof(mode))>0 && !strcmp(mode, "disabled")) continue; // Finally... open the file. thermalFiles[i] = OpenFile(tempPath); // Check to see if the temperature file was found... if(thermalFiles[i] == NullFileHandle) continue; // Read in the critical temperature value. const int tripPoint = ReadIntFile(tripPointPath); if(tripPoint > 0) { SensorSetRange(desc.label, 0, (float)tripPoint, Sensor_Interp_Linear); } } } // For clocks, we store the last value and only send updates when it changes since we // use blocking chart rendering. int lastCpuFreq[maxCpus] = {0}; int lastGpuFreq = 0; int lastMemValue = 0; UInt32 sampleCount = 0; while(!QuitSignaled() && IsConnected()) { // Sample CPU Frequencies... for(UInt32 i=0; i<maxCpus; i++) { // If the 'online' file can't be found, then we just assume this CPU doesn't even exist if(cpuOnlineFiles[i] == NullFileHandle) continue; const SensorLabelDesc &desc = cpuDescs[i]; const bool online = ReadIntFile(cpuOnlineFiles[i]) ? true : false; if(online && cpuFreqFiles[i]==NullFileHandle) { // Open the frequency file if we are online and its not already open... char freqPath[64] = {0}; FormatString(freqPath, sizeof(freqPath), "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", i); cpuFreqFiles[i] = OpenFile(freqPath); } else if(!online && cpuFreqFiles[i]!=NullFileHandle) { // close the frequency file if we are no longer online CloseFile(cpuFreqFiles[i]); cpuFreqFiles[i] = NullFileHandle; } const int freq = cpuFreqFiles[i]==NullFileHandle ? 0 : ReadIntFile(cpuFreqFiles[i]); if(freq != lastCpuFreq[i]) { // Convert from KHz to Hz SensorSetValue(desc.label, (float)freq); lastCpuFreq[i] = freq; } ThreadYield(); } // Sample GPU Frequency... if(gpuFreqFile != NullFileHandle) { const int freq = ReadIntFile(gpuFreqFile); if(freq != lastGpuFreq) { SensorSetValue(g_gpuLabel, (float)freq); lastGpuFreq = freq; } } // Sample Memory Bandwidth if(memFreqFile != NullFileHandle) { const int value = ReadIntFile(memFreqFile); if(value != lastMemValue) { SensorSetValue(g_memLabel, (float)value); lastMemValue = value; } } // Sample thermal sensors... if((sampleCount&15) == 0) // sample temperature at a much lower frequency as clocks... thermals don't change that fast. { for(UInt32 i=0; i<maxThermalSensors; i++) { FileHandle file = thermalFiles[i]; if(file != NullFileHandle) { SensorSetValue(thermalDescs[i].label, (float)ReadIntFile(file)); } } ThreadYield(); } // Sleep 5ms between samples... ThreadSleepMicroseconds(5000); sampleCount++; } // Close down cached file handles... for(UInt32 i=0; i<maxCpus; i++) { if(cpuOnlineFiles[i] != NullFileHandle) CloseFile(cpuOnlineFiles[i]); if(cpuFreqFiles[i] != NullFileHandle) CloseFile(cpuFreqFiles[i]); } if(gpuFreqFile != NullFileHandle) CloseFile(gpuFreqFile); if(memFreqFile != NullFileHandle) CloseFile(memFreqFile); for(UInt32 i=0; i<maxThermalSensors; i++) { if(thermalFiles[i] != NullFileHandle) CloseFile(thermalFiles[i]); } }
virtual void OnThreadExecute(void) { SetThreadName("CaptureServer"); // Acquire the process name... #if defined(OVR_CAPTURE_WINDOWS) char packageName[64] = {0}; GetModuleFileNameA(NULL, packageName, sizeof(packageName)); if(!packageName[0]) { StringCopy(packageName, "Unknown", sizeof(packageName)); } #else char packageName[64] = {0}; char cmdlinepath[64] = {0}; FormatString(cmdlinepath, sizeof(cmdlinepath), "/proc/%u/cmdline", (unsigned)getpid()); if(ReadFileLine(cmdlinepath, packageName, sizeof(packageName)) <= 0) { StringCopy(packageName, "Unknown", sizeof(packageName)); } #endif while(m_listenSocket && !QuitSignaled()) { // Start auto-discovery thread... ZeroConfigHost *zeroconfig = ZeroConfigHost::Create(g_zeroConfigPort, m_listenPort, packageName); zeroconfig->Start(); // try and accept a new socket connection... SocketAddress streamAddr; m_streamSocket = m_listenSocket->Accept(streamAddr); // Once connected, shut the auto-discovery thread down. zeroconfig->Release(); // If no connection was established, something went totally wrong and we should just abort... if(!m_streamSocket) break; // Before we start sending capture data... first must exchange connection headers... // First attempt to read in the request header from the Client... ConnectionHeaderPacket clientHeader = {0}; if(!m_streamSocket->Receive(&clientHeader, sizeof(clientHeader))) { m_streamSocket->Release(); m_streamSocket = NULL; continue; } // Load our connection flags... const UInt32 connectionFlags = clientHeader.flags & g_initFlags; // Build and send return header... We *always* send the return header so that if we don't // like something (like version number or feature flags), the client has some hint as to // what we didn't like. ConnectionHeaderPacket serverHeader = {0}; serverHeader.size = sizeof(serverHeader); serverHeader.version = ConnectionHeaderPacket::s_version; serverHeader.flags = connectionFlags; if(!m_streamSocket->Send(&serverHeader, sizeof(serverHeader))) { m_streamSocket->Release(); m_streamSocket = NULL; continue; } // Check version number... if(clientHeader.version != serverHeader.version) { m_streamSocket->Release(); m_streamSocket = NULL; continue; } // Check that we have any capture features even turned on... if(!connectionFlags) { m_streamSocket->Release(); m_streamSocket = NULL; continue; } // Finally, send our packet descriptors... const PacketDescriptorHeaderPacket packetDescHeader = { g_numPacketDescs }; if(!m_streamSocket->Send(&packetDescHeader, sizeof(packetDescHeader))) { m_streamSocket->Release(); m_streamSocket = NULL; continue; } if(!m_streamSocket->Send(&g_packetDescs, sizeof(g_packetDescs))) { m_streamSocket->Release(); m_streamSocket = NULL; continue; } // Connection established! // Initialize the per-thread stream system before flipping on g_connectionFlags... AsyncStream::Init(); if(g_onConnect) { // Call back into the app to notify a connection is being established. // We intentionally do this before enabling the connection flags. g_onConnect(connectionFlags); } // Signal that we are connected! AtomicExchange(g_connectionFlags, connectionFlags); // Technically any Labels that get initialized on another thread bettween the barrier and loop // will get sent over the network twice, but OVRMonitor will handle that. g_labelLock.Lock(); for(Label *l=Label::GetHead(); l; l=l->GetNext()) { SendLabelPacket(*l); } g_labelLock.Unlock(); // Start CPU/GPU/Thermal sensors... StandardSensors stdsensors; if(CheckConnectionFlag(Enable_CPU_Clocks) || CheckConnectionFlag(Enable_GPU_Clocks) || CheckConnectionFlag(Enable_Thermal_Sensors)) { stdsensors.Start(); } // Spin as long as we are connected flushing data from our data stream... while(!QuitSignaled()) { const UInt64 flushBeginTime = GetNanoseconds(); const UInt32 waitflags = m_streamSocket->WaitFor(Socket::WaitFlag_Read | Socket::WaitFlag_Write | Socket::WaitFlag_Timeout, 2); if(waitflags & Socket::WaitFlag_Timeout) { // Connection likely failed somehow... break; } if(waitflags & Socket::WaitFlag_Read) { PacketHeader header; VarSetPacket packet; m_streamSocket->Receive((char*)&header, sizeof(header)); if (header.packetID == Packet_Var_Set) { m_streamSocket->Receive((char*)&packet, sizeof(packet)); g_varStore.Set(packet.labelID, packet.value, true); } else { Logf(Log_Warning, "OVR::Capture::RemoteServer; Received Invalid Capture Packet"); } } if(waitflags & Socket::WaitFlag_Write) { // Socket is ready to write data... so now is a good time to flush pending capture data. SocketOutStream outStream(*m_streamSocket); if(!AsyncStream::FlushAll(outStream)) { // Error occured... shutdown the connection. break; } } const UInt64 flushEndTime = GetNanoseconds(); const UInt64 flushDeltaTime = flushEndTime - flushBeginTime; const UInt64 sleepTime = 4000000; // 4ms if(flushDeltaTime < sleepTime) { // Sleep just a bit to keep the thread from killing a core and to let a good chunk of data build up ThreadSleepNanoseconds((UInt32)(sleepTime - flushDeltaTime)); } } // Clear the connection flags... AtomicExchange(g_connectionFlags, (UInt32)0); // Close down our sensor thread... stdsensors.QuitAndWait(); // Connection was closed at some point, lets clean up our socket... m_streamSocket->Shutdown(); m_streamSocket->Release(); m_streamSocket = NULL; if(g_onDisconnect) { // After the connection is fully shut down, notify the app. g_onDisconnect(); } // Clear the buffers for all AsyncStreams to guarantee that no event is // stalled waiting for room on a buffer. Then we wait until there there // are no events still writing out. AsyncStream::ClearAll(); while(AtomicGet(g_refcount) > 0) { ThreadSleepMilliseconds(1); } // Finally, release any AsyncStreams that were created during this session // now that we can safely assume there are no events actively trying to // write out to a stream. AsyncStream::Shutdown(); g_varStore.Clear(); } // while(m_listenSocket && !QuitSignaled()) }