| 1 | // tMachine.cpp  |
| 2 | //  |
| 3 | // Hardware ans OS access functions like querying supported instruction sets, number or cores, and computer name/ip  |
| 4 | // accessors.  |
| 5 | //  |
| 6 | // Copyright (c) 2004-2006, 2017, 2019, 2020 Tristan Grimmer.  |
| 7 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby  |
| 8 | // granted, provided that the above copyright notice and this permission notice appear in all copies.  |
| 9 | //  |
| 10 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL  |
| 11 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,  |
| 12 | // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  |
| 13 | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR  |
| 14 | // PERFORMANCE OF THIS SOFTWARE.  |
| 15 |   |
| 16 | #ifdef PLATFORM_WINDOWS  |
| 17 | #include <Windows.h>  |
| 18 | #include <intrin.h>  |
| 19 | #else  |
| 20 | #include <unistd.h>  |
| 21 | #include <limits.h>  |
| 22 | #include <sys/sysinfo.h>  |
| 23 | #endif  |
| 24 | #include <cstdlib>  |
| 25 | #include "Foundation/tStandard.h"  |
| 26 | #include "System/tFile.h"  |
| 27 | #include "System/tMachine.h"  |
| 28 |   |
| 29 |   |
| 30 | bool tSystem::tSupportsSSE()  |
| 31 | {  |
| 32 | #ifdef PLATFORM_WINDOWS  |
| 33 | int cpuInfo[4];  |
| 34 | int infoType = 1;  |
| 35 | __cpuid(cpuInfo, infoType);  |
| 36 |   |
| 37 | int features = cpuInfo[3];  |
| 38 |   |
| 39 | // SSE feature bit is 25.  |
| 40 | if (features & (1 << 25))  |
| 41 | return true;  |
| 42 | else  |
| 43 | return false;  |
| 44 | #elif defined(PLATFORM_LINUX)  |
| 45 | // @todo Implement  |
| 46 | return true;  |
| 47 | #endif  |
| 48 | }  |
| 49 |   |
| 50 |   |
| 51 | bool tSystem::tSupportsSSE2()  |
| 52 | {  |
| 53 | #ifdef PLATFORM_WINDOWS  |
| 54 | int cpuInfo[4];  |
| 55 | int infoType = 1;  |
| 56 | __cpuid(cpuInfo, infoType);  |
| 57 |   |
| 58 | int features = cpuInfo[3];  |
| 59 |   |
| 60 | // SSE2 feature bit is 26.  |
| 61 | if (features & (1 << 26))  |
| 62 | return true;  |
| 63 | else  |
| 64 | return false;  |
| 65 |   |
| 66 | #elif defined(PLATFORM_LINUX)  |
| 67 | // @todo Implement  |
| 68 | return true;  |
| 69 | #endif  |
| 70 | }  |
| 71 |   |
| 72 |   |
| 73 | tString tSystem::tGetCompName()  |
| 74 | {  |
| 75 | #ifdef PLATFORM_WINDOWS  |
| 76 | char name[128];  |
| 77 | ulong nameSize = 128;  |
| 78 |   |
| 79 | WinBool success = GetComputerName(name, &nameSize);  |
| 80 | if (success)  |
| 81 | return name;  |
| 82 |   |
| 83 | #else  |
| 84 | char hostname[HOST_NAME_MAX];  |
| 85 | int err = gethostname(hostname, HOST_NAME_MAX);  |
| 86 | if (!err)  |
| 87 | return hostname;  |
| 88 |   |
| 89 | #endif  |
| 90 | return tString();  |
| 91 | }  |
| 92 |   |
| 93 |   |
| 94 | tString tSystem::tGetEnvVar(const tString& envVarName)  |
| 95 | {  |
| 96 | if (envVarName.IsEmpty())  |
| 97 | return tString();  |
| 98 | return tString(std::getenv(envVarName.ConstText()));  |
| 99 | }  |
| 100 |   |
| 101 |   |
| 102 | int tSystem::tGetNumCores()  |
| 103 | {  |
| 104 | // Lets cache this value as it never changes.  |
| 105 | static int numCores = 0;  |
| 106 | if (numCores > 0)  |
| 107 | return numCores;  |
| 108 |   |
| 109 | #ifdef PLATFORM_WINDOWS  |
| 110 | SYSTEM_INFO sysinfo;  |
| 111 | tStd::tMemset(&sysinfo, 0, sizeof(sysinfo));  |
| 112 | GetSystemInfo(&sysinfo);  |
| 113 |   |
| 114 | // dwNumberOfProcessors is unsigned, so can't say just > 0.  |
| 115 | if ((sysinfo.dwNumberOfProcessors == 0) || (sysinfo.dwNumberOfProcessors == -1))  |
| 116 | numCores = 1;  |
| 117 | else  |
| 118 | numCores = sysinfo.dwNumberOfProcessors;  |
| 119 |   |
| 120 | #else  |
| 121 | numCores = get_nprocs_conf();  |
| 122 | if (numCores < 1)  |
| 123 | numCores = 1;  |
| 124 |   |
| 125 | #endif  |
| 126 | return numCores;  |
| 127 | }  |
| 128 |   |
| 129 |   |
| 130 | bool tSystem::tOpenSystemFileExplorer(const tString& dir, const tString& file)  |
| 131 | {  |
| 132 | #ifdef PLATFORM_WINDOWS  |
| 133 | tString fullName = dir + file;  |
| 134 | HWND hWnd = ::GetActiveWindow();  |
| 135 |   |
| 136 | // Just open an explorer window if the dir is invalid.  |
| 137 | if (!tSystem::tDirExists(dir))  |
| 138 | {  |
| 139 | // 20D04FE0-3AEA-1069-A2D8-08002B30309D is the CLSID of "This PC" on Windows.  |
| 140 | ShellExecute(hWnd, "open" , "explorer" , "/n,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" , 0, SW_SHOWNORMAL);  |
| 141 | return false;  |
| 142 | }  |
| 143 |   |
| 144 | if (tSystem::tFileExists(fullName))  |
| 145 | {  |
| 146 | fullName.Replace('/', '\\');  |
| 147 | tString options;  |
| 148 | tsPrintf(options, "/select,\"%s\"" , fullName.Chars());  |
| 149 | ShellExecute(hWnd, "open" , "explorer" , options.ConstText(), 0, SW_SHOWNORMAL);  |
| 150 | }  |
| 151 | else  |
| 152 | {  |
| 153 | ShellExecute(hWnd, "open" , dir.ConstText(), 0, dir.ConstText(), SW_SHOWNORMAL);  |
| 154 | }  |
| 155 | return true;  |
| 156 |   |
| 157 | #elif defined(PLATFORM_LINUX)  |
| 158 | if (!tFileExists("/usr/bin/nautilus" ))  |
| 159 | return false;  |
| 160 |   |
| 161 | tString sysStr;  |
| 162 | tsPrintf(sysStr, "/usr/bin/nautilus %s%s" , dir.Chars(), file.Chars());  |
| 163 | system(sysStr.ConstText());  |
| 164 | return true;  |
| 165 |   |
| 166 | #else  |
| 167 | return false;  |
| 168 |   |
| 169 | #endif  |
| 170 | }  |
| 171 |   |
| 172 |   |
| 173 | bool tSystem::tOpenSystemFileExplorer(const tString& fullFilename)  |
| 174 | {  |
| 175 | return tOpenSystemFileExplorer(tSystem::tGetDir(fullFilename), tSystem::tGetFileName(fullFilename));  |
| 176 | }  |
| 177 | |