Changeset 10419 in vbox for trunk/src/VBox/Runtime/r3/linux
- Timestamp:
- Jul 9, 2008 1:46:17 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 33078
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/linux/mp-linux.cpp
r10405 r10419 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - Multiprocessor, Windows.3 * IPRT - Multiprocessor, Linux. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2006-200 7Sun Microsystems, Inc.7 * Copyright (C) 2006-2008 Sun Microsystems, Inc. 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 34 34 *******************************************************************************/ 35 35 #define LOG_GROUP RTLOGGROUP_SYSTEM 36 #include <Windows.h> 36 #include <unistd.h> 37 #include <stdio.h> 38 #include <sys/sysctl.h> 39 #include <sys/stat.h> 40 #include <sys/fcntl.h> 41 #include <errno.h> 42 37 43 #include <iprt/mp.h> 38 44 #include <iprt/cpuset.h> 39 45 #include <iprt/assert.h> 46 #include <iprt/string.h> 47 48 49 /** @todo move the rtLinuxSysFs* bits into sysfs.cpp and sysfs.h. */ 50 51 /** 52 * Checks if a sysfs file (or directory, device, symlink, whatever) exists. 53 * 54 * @returns true / false, errno is preserved. 55 * @param pszFormat The name format, without "/sys/". 56 * @param va The format args. 57 */ 58 bool rtLinuxSysFsExistsV(const char *pszFormat, va_list va) 59 { 60 int iSavedErrno = errno; 61 62 /* 63 * Construct the filename and call stat. 64 */ 65 char szFilename[128]; 66 static const size_t cchPrefix = sizeof("/sys/") - 1; 67 strcpy(szFilename, "/sys/"); 68 size_t cch = RTStrPrintfV(&szFilename[cchPrefix], sizeof(szFilename) - cchPrefix, pszFormat, va); 69 Assert(cch < sizeof(szFilename) - cchPrefix - 1); 70 71 struct stat st; 72 bool fRet = stat(szFilename, &st) == 0; 73 74 errno = iSavedErrno; 75 return fRet; 76 } 77 78 /** 79 * Checks if a sysfs file (or directory, device, symlink, whatever) exists. 80 * 81 * @returns true / false, errno is preserved. 82 * @param pszFormat The name format, without "/sys/". 83 * @param ... The format args. 84 */ 85 bool rtLinuxSysFsExists(const char *pszFormat, ...) 86 { 87 va_list va; 88 va_start(va, pszFormat); 89 bool fRet = rtLinuxSysFsExistsV(pszFormat, va); 90 va_end(va); 91 return fRet; 92 } 93 94 95 /** 96 * Opens a sysfs file. 97 * 98 * @returns The file descriptor. -1 and errno on failure. 99 * @param pszFormat The name format, without "/sys/". 100 * @param va The format args. 101 */ 102 int rtLinuxSysFsOpenV(const char *pszFormat, va_list va) 103 { 104 /* 105 * Construct the filename and call open. 106 */ 107 char szFilename[128]; 108 static const size_t cchPrefix = sizeof("/sys/") - 1; 109 strcpy(szFilename, "/sys/"); 110 size_t cch = RTStrPrintfV(&szFilename[cchPrefix], sizeof(szFilename) - cchPrefix, pszFormat, va); 111 Assert(cch < sizeof(szFilename) - cchPrefix - 1); 112 113 return open(szFilename, O_RDONLY, 0); 114 } 115 116 117 /** 118 * Opens a sysfs file. 119 * 120 * @returns The file descriptor. -1 and errno on failure. 121 * @param pszFormat The name format, without "/sys/". 122 * @param ... The format args. 123 */ 124 int rtLinuxSysFsOpen(const char *pszFormat, ...) 125 { 126 va_list va; 127 va_start(va, pszFormat); 128 int fd = rtLinuxSysFsOpenV(pszFormat, va); 129 va_end(va); 130 return fd; 131 } 132 133 134 /** 135 * Closes a file opened with rtLinuxSysFsOpen or rtLinuxSysFsOpenV. 136 * 137 * @param fd 138 */ 139 void rtLinuxSysFsClose(int fd) 140 { 141 int iSavedErrno = errno; 142 close(fd); 143 errno = iSavedErrno; 144 } 145 146 147 /** 148 * Closes a file opened with rtLinuxSysFsOpen or rtLinuxSysFsOpenV. 149 * 150 * @returns The number of bytes read. -1 and errno on failure. 151 * @param fd The file descriptor returned by rtLinuxSysFsOpen or rtLinuxSysFsOpenV. 152 * @param pszBuf Where to store the string. 153 * @param cchBuf The size of the buffer. Must be at least 2 bytes. 154 */ 155 ssize_t rtLinuxSysFsReadStr(int fd, char *pszBuf, size_t cchBuf) 156 { 157 Assert(cchBuf > 1); 158 ssize_t cchRead = read(fd, pszBuf, cchBuf - 1); 159 pszBuf[cchRead >= 0 ? cchRead : 0] = '\0'; 160 return cchRead; 161 } 162 163 164 /** 165 * Reads a sysfs file. 166 * 167 * @returns 64-bit signed value on success, -1 and errno on failure. 168 * @param uBase The number base, 0 for autodetect. 169 * @param pszFormat The filename format, without "/sys/". 170 * @param va Format args. 171 */ 172 int64_t rtLinuxSysFsReadIntFileV(unsigned uBase, const char *pszFormat, va_list va) 173 { 174 int fd = rtLinuxSysFsOpenV(pszFormat, va); 175 if (fd == -1) 176 return -1; 177 178 int64_t i64Ret = -1; 179 char szNum[128]; 180 ssize_t cchNum = rtLinuxSysFsReadStr(fd, szNum, sizeof(szNum)); 181 if (cchNum > 0) 182 { 183 int rc = RTStrToInt64Ex(szNum, NULL, uBase, &i64Ret); 184 if (RT_FAILURE(rc)) 185 { 186 i64Ret = -1; 187 errno = -ETXTBSY; /* just something that won't happen at read / open. */ 188 } 189 } 190 else if (cchNum == 0) 191 errno = -ETXTBSY; /* just something that won't happen at read / open. */ 192 193 rtLinuxSysFsClose(fd); 194 return i64Ret; 195 } 196 197 198 /** 199 * Reads a sysfs file. 200 * 201 * @returns 64-bit signed value on success, -1 and errno on failure. 202 * @param uBase The number base, 0 for autodetect. 203 * @param pszFormat The filename format, without "/sys/". 204 * @param ... Format args. 205 */ 206 static int64_t rtLinuxSysFsReadIntFile(unsigned uBase, const char *pszFormat, ...) 207 { 208 va_list va; 209 va_start(va, pszFormat); 210 int64_t i64Ret = rtLinuxSysFsReadIntFileV(uBase, pszFormat, va); 211 va_end(va); 212 return i64Ret; 213 } 214 215 216 /** 217 * Internal worker that determins the max possible CPU count. 218 * 219 * @returns Max cpus. 220 */ 221 DECLINLINE(RTCPUID) rtMpLinuxMaxCpus(void) 222 { 223 int cMax = sysconf(_SC_NPROCESSORS_CONF); 224 Assert(cMax >= 1); 225 return cMax; 226 } 40 227 41 228 … … 44 231 RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu) 45 232 { 46 return idCpu < MAXIMUM_PROCESSORS? idCpu : -1;233 return idCpu < rtMpLinuxMaxCpus() ? idCpu : -1; 47 234 } 48 235 … … 50 237 RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu) 51 238 { 52 return (unsigned)iCpu < MAXIMUM_PROCESSORS? iCpu : NIL_RTCPUID;239 return (unsigned)iCpu < rtMpLinuxMaxCpus() ? iCpu : NIL_RTCPUID; 53 240 } 54 241 … … 56 243 RTDECL(RTCPUID) RTMpGetMaxCpuId(void) 57 244 { 58 return MAXIMUM_PROCESSORS- 1;245 return rtMpLinuxMaxCpus() - 1; 59 246 } 60 247 … … 62 249 RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu) 63 250 { 251 /** @todo check if there is a simpler interface than this... */ 252 int i = rtLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/online", (int)idCpu); 253 if ( i == -1 254 && rtLinuxSysFsExists("devices/system/cpu/cpu%d", (int)idCpu)) 255 { 256 Assert(!rtLinuxSysFsExists("devices/system/cpu/cpu%d/online", (int)idCpu)); 257 i = 1; 258 } 259 260 Assert(i == 0 || i == -1 || i == 1); 261 return i != 0 && i != -1; 262 } 263 264 265 RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu) 266 { 267 /** @todo check this up with hotplugging! */ 268 return rtLinuxSysFsExists("devices/system/cpu/cpu%d", (int)idCpu); 269 } 270 271 272 RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet) 273 { 274 RTCpuSetEmpty(pSet); 275 RTCPUID cMax = rtMpLinuxMaxCpus(); 276 for (RTCPUID idCpu = 0; idCpu < cMax; idCpu++) 277 if (RTMpIsCpuPossible(idCpu)) 278 RTCpuSetAdd(pSet, idCpu); 279 return pSet; 280 } 281 282 283 RTDECL(RTCPUID) RTMpGetCount(void) 284 { 64 285 RTCPUSET Set; 65 return RTCpuSetIsMember(RTMpGetOnlineSet(&Set), idCpu); 66 } 67 68 69 RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu) 70 { 71 RTCPUSET Set; 72 return RTCpuSetIsMember(RTMpGetSet(&Set), idCpu); 73 } 74 75 76 RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet) 77 { 78 RTCPUID idCpu = RTMpGetCount(); 286 RTMpGetSet(&Set); 287 return RTCpuSetCount(&Set); 288 } 289 290 291 RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet) 292 { 79 293 RTCpuSetEmpty(pSet); 80 while (idCpu-- > 0) 81 RTCpuSetAdd(pSet, idCpu); 294 RTCPUID cMax = rtMpLinuxMaxCpus(); 295 for (RTCPUID idCpu = 0; idCpu < cMax; idCpu++) 296 if (RTMpIsCpuOnline(idCpu)) 297 RTCpuSetAdd(pSet, idCpu); 82 298 return pSet; 83 }84 85 86 RTDECL(RTCPUID) RTMpGetCount(void)87 {88 SYSTEM_INFO SysInfo;89 GetSystemInfo(&SysInfo);90 Assert((RTCPUID)SysInfo.dwNumberOfProcessors == SysInfo.dwNumberOfProcessors);91 return SysInfo.dwNumberOfProcessors;92 }93 94 95 RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)96 {97 SYSTEM_INFO SysInfo;98 GetSystemInfo(&SysInfo);99 return RTCpuSetFromU64(pSet, SysInfo.dwActiveProcessorMask);100 299 } 101 300
Note:
See TracChangeset
for help on using the changeset viewer.