Changeset 10419 in vbox
- Timestamp:
- Jul 9, 2008 1:46:17 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 33078
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r10418 r10419 321 321 generic/RTMpGetCurFrequency-generic.cpp \ 322 322 generic/RTMpGetMaxFrequency-generic.cpp \ 323 r3/linux/mp-linux.cpp \ 323 324 r3/linux/sched-linux.cpp \ 324 325 r3/linux/time-linux.cpp \ … … 333 334 r3/posix/process-posix.cpp \ 334 335 r3/posix/rand-posix.cpp \ 335 r3/posix/RTMpGetCount-posix.cpp \336 336 r3/posix/RTTimeNow-posix.cpp \ 337 337 r3/posix/semrw-posix.cpp \ -
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 -
trunk/src/VBox/Runtime/testcase/Makefile.kmk
r10048 r10419 72 72 tstLog \ 73 73 tstMove \ 74 tstMp-1 \ 74 75 tstNoCrt-1 \ 75 76 tstPath \ … … 246 247 tstMove_SOURCES = tstMove.cpp 247 248 249 tstMp-1_SOURCES = tstMp-1.cpp 250 248 251 tstNoCrt-1_DEFS = RT_WITHOUT_NOCRT_WRAPPER_ALIASES 249 252 tstNoCrt-1_SOURCES = \ -
trunk/src/VBox/Runtime/testcase/tstMp-1.cpp
r10405 r10419 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT Testcase - IPv4.3 * IPRT Testcase - RTMp. 4 4 */ 5 5 … … 33 33 * Header Files * 34 34 *******************************************************************************/ 35 #include <iprt/cidr.h> 35 #include <iprt/mp.h> 36 #include <iprt/cpuset.h> 36 37 #include <iprt/err.h> 37 38 #include <iprt/stream.h> … … 42 43 * Defined Constants And Macros * 43 44 *******************************************************************************/ 44 #define CHECKNETWORK(string, expected_result, expected_network, expected_netmask) \45 do { \46 RTIPV4ADDR network, netmask; \47 int result = RTCidrStrToIPv4(string, &network, &netmask); \48 if (expected_result && !result) \49 { \50 g_cErrors++; \51 RTPrintf("%s, %d: %s: expected %Vrc got %Vrc\n", \52 __FUNCTION__, __LINE__, string, expected_result, result); \53 } \54 else if ( expected_result != result \55 || ( result == VINF_SUCCESS \56 && ( expected_network != network \57 || expected_netmask != netmask))) \58 { \59 g_cErrors++; \60 RTPrintf("%s, %d: '%s': expected %Vrc got %Vrc, expected network %08x got %08x, expected netmask %08x got %08x\n", \61 __FUNCTION__, __LINE__, string, expected_result, result, expected_network, network, expected_netmask, netmask); \62 } \63 } while (0)64 65 45 66 46 /******************************************************************************* … … 73 53 { 74 54 RTR3Init(); 75 CHECKNETWORK("10.0.0/24", VINF_SUCCESS, 0x0A000000, 0xFFFFFF00); 76 CHECKNETWORK("10.0.0/8", VINF_SUCCESS, 0x0A000000, 0xFF000000); 77 CHECKNETWORK("10.0.0./24", VERR_INVALID_PARAMETER, 0, 0); 78 CHECKNETWORK("0.1.0/24", VERR_INVALID_PARAMETER, 0, 0); 79 CHECKNETWORK("10.255.0.0/24", VERR_INVALID_PARAMETER, 0, 0); 80 CHECKNETWORK("10.1234.0.0/24", VERR_INVALID_PARAMETER, 0, 0); 81 CHECKNETWORK("10.256.0.0/24", VERR_INVALID_PARAMETER, 0, 0); 82 CHECKNETWORK("10.0.0/3", VERR_INVALID_PARAMETER, 0, 0); 83 CHECKNETWORK("10.1.2.3/8", VINF_SUCCESS, 0x0A010203, 0xFF000000); 84 CHECKNETWORK("10.0.0/29", VERR_INVALID_PARAMETER, 0, 0); 85 CHECKNETWORK("10.0.0/240", VERR_INVALID_PARAMETER, 0, 0); 86 CHECKNETWORK("10.0.0/24.", VERR_INVALID_PARAMETER, 0, 0); 87 CHECKNETWORK("10.1.2/16", VINF_SUCCESS, 0x0A010200, 0xFFFF0000); 88 CHECKNETWORK("1.2.3.4", VINF_SUCCESS, 0x01020304, 0xFFFFFFFF); 55 RTPrintf("tstMp-1: TESTING...\n"); 56 57 #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) || defined(RT_OS_LINUX) 58 /* 59 * Present and possible CPUs. 60 */ 61 RTCPUID cCpus = RTMpGetCount(); 62 if (cCpus > 0) 63 RTPrintf("tstMp-1: RTMpGetCount -> %d\n", (int)cCpus); 64 else 65 { 66 RTPrintf("tstMp-1: FAILURE: RTMpGetCount -> %d\n", (int)cCpus); 67 g_cErrors++; 68 cCpus = 1; 69 } 70 71 RTCPUSET Set; 72 PRTCPUSET pSet = RTMpGetSet(&Set); 73 if (pSet == &Set) 74 { 75 if ((RTCPUID)RTCpuSetCount(&Set) != cCpus) 76 { 77 RTPrintf("tstMp-1: FAILURE: RTMpGetSet returned a set with a different cpu count; %d, expected %d\n", 78 RTCpuSetCount(&Set), cCpus); 79 g_cErrors++; 80 } 81 RTPrintf("tstMp-1: Possible CPU mask:\n"); 82 for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) 83 { 84 if (RTCpuSetIsMemberByIndex(&Set, iCpu)) 85 { 86 RTPrintf("tstMp-1: %2d - id %d\n", iCpu, RTMpCpuIdFromSetIndex(iCpu)); 87 if (!RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(iCpu))) 88 { 89 RTPrintf("tstMp-1: FAILURE: Cpu with index %d is returned by RTCpuSet but not RTMpIsCpuPossible!\n", iCpu); 90 g_cErrors++; 91 } 92 } 93 else if (RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(iCpu))) 94 { 95 RTPrintf("tstMp-1: FAILURE: Cpu with index %d is returned by RTMpIsCpuPossible but not RTCpuSet!\n", iCpu); 96 g_cErrors++; 97 } 98 } 99 } 100 else 101 { 102 RTPrintf("tstMp-1: FAILURE: RTMpGetSet -> %p, expected %p\n", pSet, &Set); 103 g_cErrors++; 104 RTCpuSetEmpty(&Set); 105 RTCpuSetAdd(&Set, RTMpCpuIdFromSetIndex(0)); 106 } 107 108 /* 109 * Online CPUs. 110 */ 111 RTCPUID cCpusOnline = RTMpGetOnlineCount(); 112 if (cCpusOnline > 0) 113 { 114 if (cCpusOnline <= cCpus) 115 RTPrintf("tstMp-1: RTMpGetOnlineCount -> %d\n", (int)cCpusOnline); 116 else 117 { 118 RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineCount -> %d, expected <= %d\n", (int)cCpusOnline, (int)cCpus); 119 g_cErrors++; 120 cCpusOnline = cCpus; 121 } 122 } 123 else 124 { 125 RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineCount -> %d\n", (int)cCpusOnline); 126 g_cErrors++; 127 cCpusOnline = 1; 128 } 129 130 RTCPUSET SetOnline; 131 pSet = RTMpGetOnlineSet(&SetOnline); 132 if (pSet == &SetOnline) 133 { 134 if (RTCpuSetCount(&SetOnline) <= 0) 135 { 136 RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineSet returned an empty set!\n"); 137 g_cErrors++; 138 } 139 else if ((RTCPUID)RTCpuSetCount(&SetOnline) > cCpus) 140 { 141 RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineSet returned a too high value; %d, expected <= %d\n", 142 RTCpuSetCount(&SetOnline), cCpus); 143 g_cErrors++; 144 } 145 RTPrintf("tstMp-1: Online CPU mask:\n"); 146 for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) 147 if (RTCpuSetIsMemberByIndex(&SetOnline, iCpu)) 148 { 149 RTPrintf("tstMp-1: %2d - id %d\n", iCpu, RTMpCpuIdFromSetIndex(iCpu)); 150 if (!RTCpuSetIsMemberByIndex(&Set, iCpu)) 151 { 152 RTPrintf("tstMp-1: FAILURE: online cpu with index %2d is not a member of the possible cpu set!\n", iCpu); 153 g_cErrors++; 154 } 155 } 156 157 /* There isn't any sane way of testing RTMpIsCpuOnline really... :-/ */ 158 } 159 else 160 { 161 RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineSet -> %p, expected %p\n", pSet, &Set); 162 g_cErrors++; 163 } 164 165 #else 166 RTPrintf("tstMp-1: SKIPPED - RTMp is not implemented on this host OS.\n"); 167 #endif 168 89 169 if (!g_cErrors) 90 RTPrintf("tst Ip: SUCCESS\n", g_cErrors);170 RTPrintf("tstMp-1: SUCCESS\n", g_cErrors); 91 171 else 92 RTPrintf("tst Ip: FAILURE - %d errors\n", g_cErrors);172 RTPrintf("tstMp-1: FAILURE - %d errors\n", g_cErrors); 93 173 return !!g_cErrors; 94 174 }
Note:
See TracChangeset
for help on using the changeset viewer.