/* This file is part of cputemp2maxfreq. Copyright (C) 2023-2024 pa4wdh cputemp2maxfreq is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License , or (at your option) any later version. cputemp2maxfreq is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cputemp2maxfreq; see the file COPYING. If not, see . */ #include #include #include #include #include #include #include #include #include #include "debug.h" #include "sysfs.h" #include "cputemp2maxfreq.h" extern struct s_config config; extern struct s_cpudata cpudata; // Add a CPU to the list void cpulist_add(char *cpu) { int newlen; newlen=cpudata.cpulist_len+1; cpudata.cpulist=reallocarray(cpudata.cpulist,(size_t) newlen,sizeof(char *)); cpudata.cpulist[cpudata.cpulist_len]=malloc(strlen(cpu)+1); strcpy(cpudata.cpulist[cpudata.cpulist_len],cpu); cpudata.cpulist[cpudata.cpulist_len][strlen(cpu)]=0; cpudata.cpulist_len=newlen; } // Validate if we found a file named cpu[0-9][0-9][0-9] int cpulist_is_cpu(char *name) { if (strncmp(name,"cpu",3)!=0) return 0; if ((name[3]<'0') || (name[3]>'9')) return 0; if (name[4]==0) return 1; if ((name[4]<'0') || (name[4]>'9')) return 0; if (name[5]==0) return 1; if ((name[5]<'0') || (name[5]>'9')) return 0; if (name[6]==0) return 1; return 0; } // Set a cpufreq parameter to a value int cpulist_find_cpus() { DIR *cpudir; struct dirent *cpu_dirent; char sysfs_file[309]; int package; sigset_t newset, oldset; DEBUG1_CPULIST("Started\n") if (cpudata.cpulist!=NULL) { DEBUG1_CPULIST("cpulist already set, free list first\n"); return -1; } cpudata.cpulist_len=0; // Block signals to prevent malloc/free race conditions sigemptyset(&newset); sigaddset(&newset,SIGTERM); sigaddset(&newset,SIGINT); sigaddset(&newset,SIGQUIT); sigprocmask(SIG_BLOCK,&newset,&oldset); // Open the CPU directory in sysfs cpudir=opendir("/sys/devices/system/cpu"); if (cpudir==NULL) { DEBUG1_CPULIST("Unable to find CPU's\n"); return -1; } cpu_dirent=readdir(cpudir); while(cpu_dirent!=NULL) { // Check if it's a CPU and it belongs to the correct physical package if (cpulist_is_cpu(cpu_dirent->d_name)) { DEBUG2_CPULIST("Found CPU %s\n",cpu_dirent->d_name); snprintf(sysfs_file,309,"/sys/devices/system/cpu/%s/topology/physical_package_id",cpu_dirent->d_name); package=(int) sysfs_read_long_int(sysfs_file); DEBUG2_CPULIST("CPU Belongs to package id %d\n",package); if ((package==config.cpu) || (config.cpu<0)) { DEBUG2_CPULIST("Add to list\n"); cpulist_add(cpu_dirent->d_name); } else { DEBUG2_CPULIST("Skip this CPU\n"); } } cpu_dirent=readdir(cpudir); } closedir(cpudir); // Restore signal mask sigprocmask(SIG_SETMASK,&oldset,NULL); DEBUG1_CPULIST("Found %d CPU's\n",config.cpulist_len); if (cpudata.cpulist_len==0) { config.logger("Warning: Found no CPU's beloning to physical CPU %d",config.cpu); } return 0; } void cpulist_free() { int count; if (cpudata.cpulist==NULL) return; int len=cpudata.cpulist_len; cpudata.cpulist_len=0; for(count=0;count