Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(360)

Side by Side Diff: runtime/vm/cpuinfo_linux.cc

Issue 120723003: Refactors CPU feature detection. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Cleanup Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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_LINUX)
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) {
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_LINUX)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698