blob: b256b66ef2312b50951be38139bcbea99803d734 [file] [log] [blame] [edit]
// Copyright (c) 2017 Facebook Inc.
// Copyright (c) 2015-2017 Georgia Institute of Technology
// All rights reserved.
//
// Copyright 2019 Google LLC
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.
/* Standard C headers */
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
/* POSIX headers */
#ifdef __ANDROID__
#include <malloc.h>
#endif
/* Windows headers */
#ifdef _WIN32
#include <malloc.h>
#endif
/* Internal library headers */
#include "threadpool-common.h"
#include "threadpool-object.h"
#if defined(__has_builtin)
#if __has_builtin(__builtin_available)
#define PTHREADPOOL_BUILTIN_AVAILABLE
#endif
#endif
extern int posix_memalign(void **memptr, size_t alignment, size_t size);
PTHREADPOOL_INTERNAL struct pthreadpool* pthreadpool_allocate(
size_t threads_count) {
assert(threads_count >= 1);
const size_t threadpool_size =
sizeof(struct pthreadpool) + threads_count * sizeof(struct thread_info);
struct pthreadpool* threadpool = NULL;
#if defined(__ANDROID__)
/*
* Android didn't get posix_memalign until API level 17 (Android 4.2).
* Use (otherwise obsolete) memalign function on Android platform.
*/
threadpool = memalign(PTHREADPOOL_CACHELINE_SIZE, threadpool_size);
#elif defined(_WIN32)
threadpool = _aligned_malloc(threadpool_size, PTHREADPOOL_CACHELINE_SIZE);
#elif _POSIX_C_SOURCE >= 200112L || defined(__hexagon__)
if (posix_memalign((void**)&threadpool, PTHREADPOOL_CACHELINE_SIZE,
threadpool_size) != 0) {
return NULL;
}
#elif defined(PTHREADPOOL_BUILTIN_AVAILABLE)
if (__builtin_available(macOS 10.15, iOS 13, *)) {
threadpool = aligned_alloc(PTHREADPOOL_CACHELINE_SIZE, threadpool_size);
} else {
threadpool = malloc(threadpool_size);
}
#else
threadpool = aligned_alloc(PTHREADPOOL_CACHELINE_SIZE, threadpool_size);
#endif
if (threadpool == NULL) {
return NULL;
}
memset(threadpool, 0, threadpool_size);
return threadpool;
}
PTHREADPOOL_INTERNAL void pthreadpool_deallocate(
struct pthreadpool* threadpool) {
assert(threadpool != NULL);
#ifdef _WIN32
_aligned_free(threadpool);
#else
free(threadpool);
#endif
}