1// Copyright 2015 The Gemmlowp Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// internal/platform.h: a place to put platform specific code
16
17#ifndef GEMMLOWP_INTERNAL_PLATFORM_H_
18#define GEMMLOWP_INTERNAL_PLATFORM_H_
19
20#ifdef _WIN32
21#include <windows.h>
22#else
23#include <stdlib.h>
24#include <time.h>
25#include <unistd.h>
26#endif
27
28#ifdef __APPLE__
29#include <sys/time.h>
30#endif
31
32#if defined ANDROID || defined __ANDROID__
33#include <malloc.h>
34#include <android/api-level.h>
35// The 18 here should be 16, but has to be 18 for now due
36// to a Google-internal issue.
37#if __ANDROID_API__ < 18
38#define GEMMLOWP_USE_MEMALIGN
39#endif
40// posix_memalign is missing on some 4.1 x86 devices
41#if __ANDROID_API__ == 18
42#ifdef GEMMLOWP_X86_32
43#define GEMMLOWP_USE_MEMALIGN
44#endif
45#endif
46#endif
47
48// Needed by chrome native builds
49#ifndef _SC_NPROCESSORS_CONF
50#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_ONLN
51#endif
52
53namespace gemmlowp {
54
55#ifdef _WIN32
56inline void *aligned_alloc(size_t alignment, size_t size) {
57  return _aligned_malloc(size, alignment);
58}
59
60inline void aligned_free(void *memptr) { _aligned_free(memptr); }
61
62inline int GetHardwareConcurrency(int max_threads) {
63  if (max_threads == 0) {
64    SYSTEM_INFO sysinfo;
65    GetSystemInfo(&sysinfo);
66    return sysinfo.dwNumberOfProcessors;
67  }
68  return max_threads;
69}
70
71inline double real_time_in_seconds() {
72  __int64 wintime;
73  GetSystemTimeAsFileTime((FILETIME *)&wintime);
74  wintime -= 116444736000000000i64;  // 1jan1601 to 1jan1970
75  return wintime / 10000000i64 + wintime % 10000000i64 * 100 * 1e-9;
76}
77
78#else
79inline void *aligned_alloc(size_t alignment, size_t size) {
80#ifdef GEMMLOWP_USE_MEMALIGN
81  return memalign(alignment, size);
82#else
83  void *memptr;
84  if (posix_memalign(&memptr, alignment, size)) {
85    memptr = nullptr;
86  }
87  return memptr;
88#endif
89}
90
91inline int GetHardwareConcurrency(int max_threads) {
92  if (max_threads == 0) {
93    static const int hardware_threads_count =
94        static_cast<int>(sysconf(_SC_NPROCESSORS_CONF));
95    return hardware_threads_count;
96  }
97  return max_threads;
98}
99
100inline void aligned_free(void *memptr) { free(memptr); }
101
102inline double real_time_in_seconds() {
103#ifdef __APPLE__
104  timeval t;
105  gettimeofday(&t, nullptr);
106  return t.tv_sec + 1e-6 * t.tv_usec;
107#else
108  timespec t;
109  clock_gettime(CLOCK_REALTIME, &t);
110  return t.tv_sec + 1e-9 * t.tv_nsec;
111#endif
112}
113
114#endif
115}  // namespace gemmlowp
116#endif  // GEMMLOWP_INTERNAL_PLATFORM_H_
117