1/*******************************************************************************
2* Copyright 2018 Intel Corporation
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*******************************************************************************/
16
17#include <string.h>
18#ifdef _WIN32
19#include <malloc.h>
20#include <windows.h>
21#endif
22#include <limits.h>
23#include <stdlib.h>
24#include <stdio.h>
25
26#include "mkldnn.h"
27#include "utils.hpp"
28
29namespace mkldnn {
30namespace impl {
31
32int getenv(const char *name, char *buffer, int buffer_size) {
33 if (name == NULL || buffer_size < 0 || (buffer == NULL && buffer_size > 0))
34 return INT_MIN;
35
36 int result = 0;
37 int term_zero_idx = 0;
38 size_t value_length = 0;
39
40#ifdef _WIN32
41 value_length = GetEnvironmentVariable(name, buffer, buffer_size);
42#else
43 const char *value = ::getenv(name);
44 value_length = value == NULL ? 0 : strlen(value);
45#endif
46
47 if (value_length > INT_MAX)
48 result = INT_MIN;
49 else {
50 int int_value_length = (int)value_length;
51 if (int_value_length >= buffer_size) {
52 result = -int_value_length;
53 } else {
54 term_zero_idx = int_value_length;
55 result = int_value_length;
56#ifndef _WIN32
57 strncpy(buffer, value, value_length);
58#endif
59 }
60 }
61
62 if (buffer != NULL)
63 buffer[term_zero_idx] = '\0';
64 return result;
65}
66
67int getenv_int(const char *name, int default_value)
68{
69 int value = default_value;
70 // # of digits in the longest 32-bit signed int + sign + terminating null
71 const int len = 12;
72 char value_str[len];
73 if (getenv(name, value_str, len) > 0)
74 value = atoi(value_str);
75 return value;
76}
77
78FILE *fopen(const char *filename, const char *mode) {
79#ifdef _WIN32
80 FILE *fp = NULL;
81 return ::fopen_s(&fp, filename, mode) ? NULL : fp;
82#else
83 return ::fopen(filename, mode);
84#endif
85}
86
87void *malloc(size_t size, int alignment) {
88 void *ptr;
89
90#ifdef _WIN32
91 ptr = _aligned_malloc(size, alignment);
92 int rc = ptr ? 0 : -1;
93#else
94 int rc = ::posix_memalign(&ptr, alignment, size);
95#endif
96
97 return (rc == 0) ? ptr : 0;
98}
99
100void free(void *p) {
101#ifdef _WIN32
102 _aligned_free(p);
103#else
104 ::free(p);
105#endif
106}
107
108// Atomic operations
109int32_t fetch_and_add(int32_t *dst, int32_t val) {
110#ifdef _WIN32
111 return InterlockedExchangeAdd(reinterpret_cast<long*>(dst), val);
112#else
113 return __sync_fetch_and_add(dst, val);
114#endif
115}
116
117static int jit_dump_flag = 0;
118static bool jit_dump_flag_initialized = false;
119bool jit_dump_enabled() {
120 if (!jit_dump_flag_initialized) {
121 jit_dump_flag = getenv_int("MKLDNN_JIT_DUMP");
122 jit_dump_flag_initialized = true;
123 }
124 return jit_dump_flag != 0;
125}
126
127}
128}
129
130mkldnn_status_t mkldnn_set_jit_dump(int enabled) {
131 using namespace mkldnn::impl::status;
132 mkldnn::impl::jit_dump_flag = enabled;
133 mkldnn::impl::jit_dump_flag_initialized = true;
134 return success;
135}
136