]> git.sesse.net Git - vlc/blobdiff - src/misc/cpu.c
Use var_Inherit* instead of var_CreateGet*.
[vlc] / src / misc / cpu.c
index 3b0d278999938d58f9901aa9a9afba9181d3140c..e630e9b60263f6069ea075b8403d491779bfb043 100644 (file)
 #else
 #include <errno.h>
 #endif
+#include <assert.h>
 
 #include "libvlc.h"
 
-#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__))
+#if defined(__APPLE__)
 #include <sys/sysctl.h>
 #endif
 
+#if defined(__OpenBSD__)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <machine/cpu.h>
+#endif
+
+#if defined(__SunOS)
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/processor.h>
+#include <sys/pset.h>
+#endif
+
 #if defined( __i386__ ) || defined( __x86_64__ ) || defined( __powerpc__ ) \
  || defined( __ppc__ ) || defined( __ppc64__ ) || defined( __powerpc64__ )
 # ifndef WIN32
@@ -258,8 +272,12 @@ out:
 #elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __powerpc64__ ) \
     || defined( __ppc64__ )
 
-#   if defined(__APPLE__)
+#   if defined(__APPLE__) || defined(__OpenBSD__)
+#   if defined(__OpenBSD__)
+    int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
+#   else
     int selectors[2] = { CTL_HW, HW_VECTORUNIT };
+#   endif
     int i_has_altivec = 0;
     size_t i_length = sizeof( i_has_altivec );
     int i_error = sysctl( selectors, 2, &i_has_altivec, &i_length, NULL, 0);
@@ -318,6 +336,71 @@ const struct
 #endif
 };
 
+/**
+ * Return the number of available logical CPU.
+ */
+unsigned vlc_GetCPUCount(void)
+{
+#if defined(WIN32) && !defined(UNDER_CE)
+    DWORD process_mask;
+    DWORD system_mask;
+    if (!GetProcessAffinityMask(GetCurrentProcess(), &process_mask, &system_mask))
+        return 1;
+
+    unsigned count = 0;
+    while (system_mask) {
+        count++;
+        system_mask >>= 1;
+    }
+    return count;
+#elif defined(HAVE_SCHED_GETAFFINITY)
+    cpu_set_t cpu;
+    CPU_ZERO(&cpu);
+    if (sched_getaffinity(0, sizeof(cpu), &cpu) < 0)
+        return 1;
+    unsigned count = 0;
+    for (unsigned i = 0; i < CPU_SETSIZE; i++)
+        count += CPU_ISSET(i, &cpu) != 0;
+    return count;
+#elif defined(__APPLE__)
+    int count;
+    size_t size = sizeof(count) ;
+    if (sysctlbyname("hw.ncpu", &count, &size, NULL, 0))
+        return 1; /* Failure */
+    return count;
+#elif defined(__OpenBSD__)
+    int selectors[2] = { CTL_HW, HW_NCPU };
+    int count;
+    size_t size = sizeof(count) ;
+    if (sysctl(selectors, 2, &count, &size, NULL, 0))
+        return 1; /* Failure */
+    return count;
+#elif defined(__SunOS)
+    unsigned count = 0;
+    int type;
+    u_int numcpus;
+    processorid_t *cpulist;
+    processor_info_t cpuinfo;
+    cpulist = malloc(sizeof(processorid_t) * sysconf(_SC_NPROCESSORS_MAX));
+    if (!cpulist) return 1;
+    if (pset_info(PS_MYID, &type, &numcpus, cpulist)==0)
+    {
+        for (u_int i = 0; i < numcpus; i++)
+        {
+            if (!processor_info(cpulist[i], &cpuinfo))
+                count += (cpuinfo.pi_state == P_ONLINE)?1:0;
+        }
+    } else {
+        count = sysconf(_SC_NPROCESSORS_ONLN);
+    }
+    free(cpulist);
+    return (count>0)?count:1;
+#else
+#   warning "vlc_GetCPUCount is not implemented for your platform"
+    return 1;
+#endif
+}
+
 /**
  * Check if a directory name contains usable plugins w.r.t. the hardware
  * capabilities. Loading a plugin when the hardware has insufficient
@@ -367,3 +450,32 @@ void *vlc_memset (void *tgt, int c, size_t n)
 {
     return pf_vlc_memset (tgt, c, n);
 }
+
+/**
+ * Returned an aligned pointer on newly allocated memory.
+ * \param alignment must be a power of 2 and a multiple of sizeof(void*)
+ * \param size is the size of the usable memory returned.
+ *
+ * It must not be freed directly, *base must.
+ */
+void *vlc_memalign(void **base, size_t alignment, size_t size)
+{
+    assert(alignment >= sizeof(void*));
+    for (size_t t = alignment; t > 1; t >>= 1)
+        assert((t&1) == 0);
+#if defined(HAVE_POSIX_MEMALIGN)
+    if (posix_memalign(base, alignment, size)) {
+        *base = NULL;
+        return NULL;
+    }
+    return *base;
+#elif defined(HAVE_MEMALIGN)
+    return *base = memalign(alignment, size);
+#else
+    unsigned char *p = *base = malloc(size + alignment - 1);
+    if (!p)
+        return NULL;
+    return (void*)((uintptr_t)(p + alignment - 1) & ~(alignment - 1));
+#endif
+}
+