OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include "vm/globals.h" | |
6 #if defined(TARGET_OS_ANDROID) | |
7 | |
8 #include "vm/cpuinfo.h" | |
9 | |
10 #include <ctype.h> // NOLINT | |
11 #include <string.h> // NOLINT | |
12 | |
13 #include "platform/assert.h" | |
14 | |
15 namespace dart { | |
16 | |
17 char* CpuInfo::data_ = NULL; | |
18 intptr_t CpuInfo::datalen_ = 0; | |
19 | |
20 void CpuInfo::Read() { | |
21 // Get the size of the cpuinfo file by reading it until the end. This is | |
22 // required because files under /proc do not always return a valid size | |
23 // when using fseek(0, SEEK_END) + ftell(). Nor can they be mmap()-ed. | |
24 static const char PATHNAME[] = "/proc/cpuinfo"; | |
25 FILE* fp = fopen(PATHNAME, "r"); | |
26 if (fp != NULL) { | |
27 for (;;) { | |
28 char buffer[256]; | |
29 size_t n = fread(buffer, 1, sizeof(buffer), fp); | |
30 if (n == 0) { | |
31 break; | |
32 } | |
33 datalen_ += n; | |
34 } | |
35 fclose(fp); | |
36 } | |
37 | |
38 // Read the contents of the cpuinfo file. | |
39 data_ = new char[datalen_ + 1]; | |
40 fp = fopen(PATHNAME, "r"); | |
41 if (fp != NULL) { | |
42 for (intptr_t offset = 0; offset < datalen_; ) { | |
43 size_t n = fread(data_ + offset, 1, datalen_ - offset, fp); | |
44 if (n == 0) { | |
45 break; | |
46 } | |
47 offset += n; | |
48 } | |
49 fclose(fp); | |
50 } | |
51 | |
52 // Zero-terminate the data. | |
53 data_[datalen_] = '\0'; | |
54 } | |
55 | |
56 | |
57 static char* FieldStart(char* data, const char* field) { | |
58 // Look for first field occurrence, and ensure it starts the line. | |
59 size_t fieldlen = strlen(field); | |
60 char* p = data; | |
61 for (;;) { | |
62 p = strstr(p, field); | |
63 if (p == NULL) { | |
64 return NULL; | |
65 } | |
66 if (p == data || p[-1] == '\n') { | |
67 break; | |
68 } | |
69 p += fieldlen; | |
70 } | |
71 | |
72 // Skip to the first colon followed by a space. | |
73 p = strchr(p + fieldlen, ':'); | |
74 if (p == NULL || !isspace(p[1])) { | |
75 return NULL; | |
76 } | |
77 p += 2; | |
78 | |
79 return p; | |
80 } | |
81 | |
82 | |
83 bool CpuInfo::FieldContains(const char* field, const char* search_string) { | |
84 ASSERT(data_ != NULL); | |
85 ASSERT(search_string != NULL); | |
86 | |
87 char *p = FieldStart(data_, field); | |
88 if (p == NULL) { | |
89 return false; | |
90 } | |
91 | |
92 // Find the end of the line. | |
93 char* q = strchr(p, '\n'); | |
94 if (q == NULL) { | |
95 q = data_ + datalen_; | |
96 } | |
97 | |
98 char saved_end = *q; | |
99 *q = '\0'; | |
100 bool ret = (strcasestr(p, search_string) != NULL); | |
101 *q = saved_end; | |
102 | |
103 return ret; | |
104 } | |
105 | |
106 | |
107 // Extract the content of a the first occurrence of a given field in | |
108 // the content of the cpuinfo file and return it as a heap-allocated | |
109 // string that must be freed by the caller using delete[]. | |
110 // Return NULL if not found. | |
111 intptr_t CpuInfo::ExtractField( | |
112 const char* field, char* dest, const intptr_t dest_len) { | |
Cutch
2014/01/02 19:39:19
Should the OS specific code populate a field table
| |
113 ASSERT(field != NULL); | |
114 ASSERT(data_ != NULL); | |
115 | |
116 char* p = FieldStart(data_, field); | |
117 if (p == NULL) { | |
118 if (dest != NULL) { | |
119 dest[0] = '\0'; | |
120 } | |
121 return 0; | |
122 } | |
123 | |
124 // Find the end of the line. | |
125 char* q = strchr(p, '\n'); | |
126 if (q == NULL) { | |
127 q = data_ + datalen_; | |
128 } | |
129 | |
130 intptr_t len = (dest_len < (q - p + 1)) ? (dest_len - 1) : q - p; | |
131 if (dest != NULL) { | |
132 // Copy the line into dest, leaving enough room for a null-terminator. | |
133 char saved_end = *q; | |
134 *q = '\0'; | |
135 strncpy(dest, p, len); | |
136 dest[len] = '\0'; | |
137 *q = saved_end; | |
138 } | |
139 | |
140 return len; | |
141 } | |
142 | |
143 | |
144 bool CpuInfo::HasField(const char* field) { | |
145 ASSERT(field != NULL); | |
146 ASSERT(data_ != NULL); | |
147 intptr_t len = ExtractField(field, NULL, 0); | |
148 return (len != 0); | |
149 } | |
150 | |
151 | |
152 intptr_t CpuInfo::GetCpuModel(char* dest, const intptr_t dest_len) { | |
153 #if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) | |
154 ASSERT(HasField("model name")); | |
155 return ExtractField("model name", dest, dest_len); | |
156 #elif defined(HOST_ARCH_ARM) | |
157 ASSERT(HasField("Hardware")); | |
158 return ExtractField("Hardware", dest, dest_len); | |
159 #elif defined(HOST_ARCH_MIPS) | |
160 ASSERT(HasField("cpu model")); | |
161 return ExtractField("cpu model", dest, dest_len); | |
162 #else | |
163 #error Unrecognized target architecture | |
164 #endif | |
165 } | |
166 | |
167 } // namespace dart | |
168 | |
169 #endif // defined(TARGET_OS_ANDROID) | |
OLD | NEW |