1 /* EINA - EFL data type library
2 * Copyright (C) 2007-2008 Jorge Luis Zapata Muga
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.
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.
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/>.
23 #ifdef EFL_HAVE_THREADS
25 # define WIN32_LEAN_AND_MEAN
27 # elif defined (__sun) || defined(__GNU__)
29 # elif defined (__FreeBSD__) || defined (__OpenBSD__) || \
30 defined (__NetBSD__) || defined (__DragonFly__) || defined (__MacOSX__) || \
31 (defined (__MACH__) && defined (__APPLE__))
33 # include <sys/param.h>
34 # include <sys/sysctl.h>
35 # elif defined (__linux__) || defined(__GLIBC__)
38 # ifdef EFL_HAVE_POSIX_THREADS
52 /*============================================================================*
54 *============================================================================*/
56 /* FIXME this ifdefs should be replaced */
57 #if defined(__i386__) || defined(__x86_64__)
58 /* We save ebx and restore it to be PIC compatible */
59 static inline void _x86_cpuid(int op, int *a, int *b, int *c, int *d)
62 #if defined(__x86_64__)
63 "pushq %%rbx \n\t" /* save %ebx */
65 "pushl %%ebx \n\t" /* save %ebx */
68 "movl %%ebx, %1 \n\t" /* save what cpuid just put in %ebx */
69 #if defined(__x86_64__)
70 "popq %%rbx \n\t" /* restore the old %ebx */
72 "popl %%ebx \n\t" /* restore the old %ebx */
74 : "=a" (*a), "=r" (*b), "=c" (*c), "=d" (*d)
80 void _x86_simd(Eina_Cpu_Features *features)
84 _x86_cpuid(1, &a, &b, &c, &d);
87 * 18 = PN (Processor Number)
88 * 19 = CLFlush (Cache Line Flush)
92 * 28 = HTT (Hyper Threading)
97 *features |= EINA_CPU_MMX;
100 *features |= EINA_CPU_SSE;
103 *features |= EINA_CPU_SSE2;
106 *features |= EINA_CPU_SSE3;
110 /*============================================================================*
112 *============================================================================*/
114 /*============================================================================*
116 *============================================================================*/
118 /* FIXME the features checks should be called when this function is called?
119 * or make it static by doing eina_cpu_init() and return a local var
125 EAPI Eina_Cpu_Features eina_cpu_features_get(void)
127 Eina_Cpu_Features ecf = 0;
128 #if defined(__i386__) || defined(__x86_64__)
134 static int _cpu_count = -1;
137 _eina_cpu_count_internal(void)
139 #ifdef EFL_HAVE_THREADS
141 # if defined (_WIN32)
144 GetSystemInfo(&sysinfo);
145 return sysinfo.dwNumberOfProcessors;
147 # elif defined (__sun) || defined(__GNU__)
149 * _SC_NPROCESSORS_ONLN: number of processors that are online, that
150 is available when sysconf is called. The number
151 of cpu can change by admins.
152 * _SC_NPROCESSORS_CONF: maximum number of processors that are available
153 to the current OS instance. That number can be
154 change after a reboot.
155 * _SC_NPROCESSORS_MAX : maximum number of processors that are on the
158 return sysconf(_SC_NPROCESSORS_ONLN);
160 # elif defined (__FreeBSD__) || defined (__OpenBSD__) || \
161 defined (__NetBSD__) || defined (__DragonFly__) || defined (__MacOSX__) || \
162 (defined (__MACH__) && defined (__APPLE__))
166 size_t len = sizeof(cpus);
170 mib[1] = HW_AVAILCPU;
174 sysctl(mib, 2, &cpus, &len, NULL, 0);
180 # elif defined (__linux__) || defined(__GLIBC__)
189 if (sched_getaffinity(0, sizeof(cpu), &cpu) != 0)
191 fprintf(stderr, "[Eina] could not get cpu affinity: %s\n",
196 for (i = 0; i < TH_MAX; i++)
198 if (CPU_ISSET(i, &cpu))
206 # error "eina_cpu_count() error: Platform not supported"
213 EAPI int eina_cpu_count(void)
218 void eina_cpu_count_internal(void)
220 if (getenv("EINA_CPU_FAKE"))
221 _cpu_count = atoi(getenv("EINA_CPU_FAKE"));
223 _cpu_count = _eina_cpu_count_internal();