157 lines
4.8 KiB
C++
157 lines
4.8 KiB
C++
/* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License, version 2.0,
|
|
as published by the Free Software Foundation.
|
|
|
|
This program is also distributed with certain software (including
|
|
but not limited to OpenSSL) that is licensed under separate terms,
|
|
as designated in a particular file or component or in included license
|
|
documentation. The authors of MySQL hereby grant you an additional
|
|
permission to link the program and your derivative works with the
|
|
separately licensed software that they have included with MySQL.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License, version 2.0, for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
#include "thread_attrs_api.h"
|
|
|
|
#include <errno.h>
|
|
#include <sys/cpuset.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/sysctl.h>
|
|
#include <sys/time.h>
|
|
|
|
#include "my_dbug.h"
|
|
#include "my_sys.h"
|
|
#include "mysql/components/services/log_builtins.h"
|
|
#include "mysqld_error.h"
|
|
|
|
namespace resourcegroups {
|
|
namespace platform {
|
|
|
|
bool is_platform_supported() { return true; }
|
|
|
|
bool bind_to_cpu(cpu_id_t cpu_id) {
|
|
return bind_to_cpu(cpu_id, my_thread_os_id());
|
|
}
|
|
|
|
bool bind_to_cpu(cpu_id_t cpu_id, my_thread_os_id_t thread_id) {
|
|
DBUG_TRACE;
|
|
|
|
cpuset_t cpu_set;
|
|
|
|
CPU_ZERO(&cpu_set);
|
|
CPU_SET(cpu_id, &cpu_set);
|
|
if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, thread_id,
|
|
sizeof(cpu_set), &cpu_set) == -1) {
|
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
LogErr(ERROR_LEVEL, ER_RES_GRP_SET_THR_AFFINITY_FAILED, thread_id, cpu_id,
|
|
my_errno(), my_strerror(errbuf, MYSQL_ERRMSG_SIZE, my_errno()));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool bind_to_cpus(const std::vector<cpu_id_t> &cpu_ids) {
|
|
return bind_to_cpus(cpu_ids, my_thread_os_id());
|
|
}
|
|
|
|
bool bind_to_cpus(const std::vector<cpu_id_t> &cpu_ids,
|
|
my_thread_os_id_t thread_id) {
|
|
DBUG_TRACE;
|
|
|
|
if (cpu_ids.empty()) return false;
|
|
|
|
cpuset_t cpu_set;
|
|
|
|
CPU_ZERO(&cpu_set);
|
|
for (const auto &cpu_id : cpu_ids) CPU_SET(cpu_id, &cpu_set);
|
|
|
|
if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, thread_id,
|
|
sizeof(cpu_set), &cpu_set) == -1) {
|
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
LogErr(ERROR_LEVEL, ER_RES_GRP_SET_THR_AFFINITY_FAILED, thread_id,
|
|
my_errno(), my_strerror(errbuf, MYSQL_ERRMSG_SIZE, my_errno()));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool unbind_thread() { return unbind_thread(my_thread_os_id()); }
|
|
|
|
bool unbind_thread(my_thread_os_id_t thread_id) {
|
|
DBUG_TRACE;
|
|
|
|
cpuset_t cpu_set;
|
|
|
|
CPU_ZERO(&cpu_set);
|
|
uint32_t num_cpus = num_vcpus();
|
|
if (num_cpus == 0) {
|
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
LogErr(ERROR_LEVEL, ER_RES_GRP_THD_UNBIND_FROM_CPU_FAILED, thread_id,
|
|
my_errno(), my_strerror(errbuf, MYSQL_ERRMSG_SIZE, my_errno()));
|
|
return true;
|
|
}
|
|
for (cpu_id_t cpu_id = 0; cpu_id < num_cpus; ++cpu_id)
|
|
CPU_SET(cpu_id, &cpu_set);
|
|
if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, thread_id,
|
|
sizeof(cpu_set), &cpu_set) == -1) {
|
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
LogErr(ERROR_LEVEL, ER_RES_GRP_THD_UNBIND_FROM_CPU_FAILED, thread_id,
|
|
my_errno(), my_strerror(errbuf, MYSQL_ERRMSG_SIZE, my_errno()));
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int thread_priority() { return getpriority(PRIO_PROCESS, my_thread_os_id()); }
|
|
|
|
int thread_priority(my_thread_os_id_t) {
|
|
DBUG_ASSERT(0);
|
|
LogErr(WARNING_LEVEL, ER_RES_GRP_GET_THREAD_PRIO_NOT_SUPPORTED, "FreeBSD");
|
|
return 0;
|
|
}
|
|
|
|
bool set_thread_priority(int priority) {
|
|
return set_thread_priority(priority, my_thread_os_id());
|
|
}
|
|
|
|
bool set_thread_priority(int, my_thread_os_id_t) {
|
|
DBUG_TRACE;
|
|
// Thread priority setting unsupported in FreeBSD.
|
|
return false;
|
|
}
|
|
|
|
uint32_t num_vcpus_using_affinity() {
|
|
uint32_t num_vcpus = 0;
|
|
|
|
#ifdef HAVE_PTHREAD_GETAFFINITY_NP
|
|
cpuset_t set;
|
|
|
|
if (pthread_getaffinity_np(pthread_self(), sizeof(set), &set) == 0)
|
|
num_vcpus = CPU_COUNT(&set);
|
|
#endif // HAVE_PTHREAD_GETAFFINITY_NP
|
|
return num_vcpus;
|
|
}
|
|
|
|
uint32_t num_vcpus_using_config() {
|
|
cpu_id_t num_vcpus = 0;
|
|
size_t num_vcpus_size = sizeof(cpu_id_t);
|
|
if (sysctlbyname("hw.ncpu", &num_vcpus, &num_vcpus_size, nullptr, 0) != 0) {
|
|
LogErr(ERROR_LEVEL, ER_RES_GRP_FAILED_DETERMINE_CPU_COUNT);
|
|
num_vcpus = 0;
|
|
}
|
|
return num_vcpus;
|
|
}
|
|
|
|
bool can_thread_priority_be_set() { return false; }
|
|
} // namespace platform
|
|
} // namespace resourcegroups
|