aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_cpu.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-04 18:41:13 +1000
committerDavid Walter Seikel2012-01-04 18:41:13 +1000
commitdd7595a3475407a7fa96a97393bae8c5220e8762 (patch)
treee341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/eina/src/lib/eina_cpu.c
parentAdd the skeleton. (diff)
downloadSledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/eina/src/lib/eina_cpu.c')
-rw-r--r--libraries/eina/src/lib/eina_cpu.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/libraries/eina/src/lib/eina_cpu.c b/libraries/eina/src/lib/eina_cpu.c
new file mode 100644
index 0000000..8af550d
--- /dev/null
+++ b/libraries/eina/src/lib/eina_cpu.c
@@ -0,0 +1,207 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2007-2008 Jorge Luis Zapata Muga
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#ifdef EFL_HAVE_THREADS
24# ifdef _WIN32
25# define WIN32_LEAN_AND_MEAN
26# include <windows.h>
27# elif defined (__SUNPRO_C) || defined(__GNU__)
28# include <unistd.h>
29# elif defined (__FreeBSD__) || defined (__OpenBSD__) || \
30 defined (__NetBSD__) || defined (__DragonFly__) || defined (__MacOSX__) || \
31 (defined (__MACH__) && defined (__APPLE__))
32# include <unistd.h>
33# include <sys/param.h>
34# include <sys/sysctl.h>
35# elif defined (__linux__) || defined(__GLIBC__)
36# include <sched.h>
37# endif
38# ifdef EFL_HAVE_POSIX_THREADS
39# include <pthread.h>
40# endif
41
42# define TH_MAX 8
43#endif
44
45#include <stdio.h>
46#include <string.h>
47#include <errno.h>
48
49#include "eina_cpu.h"
50
51/*============================================================================*
52* Local *
53*============================================================================*/
54
55/* FIXME this ifdefs should be replaced */
56#if defined(__i386__) || defined(__x86_64__)
57/* We save ebx and restore it to be PIC compatible */
58static inline void _x86_cpuid(int op, int *a, int *b, int *c, int *d)
59{
60 asm volatile (
61#if defined(__x86_64__)
62 "pushq %%rbx \n\t" /* save %ebx */
63#else
64 "pushl %%ebx \n\t" /* save %ebx */
65#endif
66 "cpuid \n\t"
67 "movl %%ebx, %1 \n\t" /* save what cpuid just put in %ebx */
68#if defined(__x86_64__)
69 "popq %%rbx \n\t" /* restore the old %ebx */
70#else
71 "popl %%ebx \n\t" /* restore the old %ebx */
72#endif
73 : "=a" (*a), "=r" (*b), "=c" (*c), "=d" (*d)
74 : "a" (op)
75 : "cc");
76}
77
78static
79void _x86_simd(Eina_Cpu_Features *features)
80{
81 int a, b, c, d;
82
83 _x86_cpuid(1, &a, &b, &c, &d);
84 /*
85 * edx
86 * 18 = PN (Processor Number)
87 * 19 = CLFlush (Cache Line Flush)
88 * 23 = MMX
89 * 25 = SSE
90 * 26 = SSE2
91 * 28 = HTT (Hyper Threading)
92 * ecx
93 * 0 = SSE3
94 */
95 if ((d >> 23) & 1)
96 *features |= EINA_CPU_MMX;
97
98 if ((d >> 25) & 1)
99 *features |= EINA_CPU_SSE;
100
101 if ((d >> 26) & 1)
102 *features |= EINA_CPU_SSE2;
103
104 if (c & 1)
105 *features |= EINA_CPU_SSE3;
106}
107#endif
108
109/*============================================================================*
110* Global *
111*============================================================================*/
112
113/*============================================================================*
114* API *
115*============================================================================*/
116
117/* FIXME the features checks should be called when this function is called?
118 * or make it static by doing eina_cpu_init() and return a local var
119 */
120/**
121 *
122 * @return
123 */
124EAPI Eina_Cpu_Features eina_cpu_features_get(void)
125{
126 Eina_Cpu_Features ecf = 0;
127#if defined(__i386__) || defined(__x86_64__)
128 _x86_simd(&ecf);
129#endif
130 return ecf;
131}
132
133EAPI int eina_cpu_count(void)
134{
135#ifdef EFL_HAVE_THREADS
136
137# if defined (_WIN32)
138 SYSTEM_INFO sysinfo;
139
140 GetSystemInfo(&sysinfo);
141 return sysinfo.dwNumberOfProcessors;
142
143# elif defined (__SUNPRO_C) || defined(__GNU__)
144 /*
145 * _SC_NPROCESSORS_ONLN: number of processors that are online, that
146 is available when sysconf is called. The number
147 of cpu can change by admins.
148 * _SC_NPROCESSORS_CONF: maximum number of processors that are available
149 to the current OS instance. That number can be
150 change after a reboot.
151 * _SC_NPROCESSORS_MAX : maximum number of processors that are on the
152 motherboard.
153 */
154 return sysconf(_SC_NPROCESSORS_ONLN);
155
156# elif defined (__FreeBSD__) || defined (__OpenBSD__) || \
157 defined (__NetBSD__) || defined (__DragonFly__) || defined (__MacOSX__) || \
158 (defined (__MACH__) && defined (__APPLE__))
159
160 int mib[4];
161 int cpus;
162 size_t len = sizeof(cpus);
163
164 mib[0] = CTL_HW;
165#ifdef HW_AVAILCPU
166 mib[1] = HW_AVAILCPU;
167#else
168 mib[1] = HW_NCPU;
169#endif
170 sysctl(mib, 2, &cpus, &len, NULL, 0);
171 if (cpus < 1)
172 cpus = 1;
173
174 return cpus;
175
176# elif defined (__linux__) || defined(__GLIBC__)
177 cpu_set_t cpu;
178 int i;
179 static int cpus = 0;
180
181 if (cpus != 0)
182 return cpus;
183
184 CPU_ZERO(&cpu);
185 if (sched_getaffinity(0, sizeof(cpu), &cpu) != 0)
186 {
187 fprintf(stderr, "[Eina] could not get cpu affinity: %s\n",
188 strerror(errno));
189 return 1;
190 }
191
192 for (i = 0; i < TH_MAX; i++)
193 {
194 if (CPU_ISSET(i, &cpu))
195 cpus = i + 1;
196 else
197 break;
198 }
199 return cpus;
200
201# else
202# error "eina_cpu_count() error: Platform not supported"
203# endif
204#else
205 return 1;
206#endif
207}