|
Packit Service |
d40955 |
/*
|
|
Packit Service |
d40955 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
d40955 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
d40955 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
d40955 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
d40955 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
d40955 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
d40955 |
* GNU General Public License for more details.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
d40955 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
d40955 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
d40955 |
* 02110-1301, USA.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/threadConfig.c#2 $
|
|
Packit Service |
d40955 |
*/
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "threadConfig.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "logger.h"
|
|
Packit Service |
d40955 |
#include "memoryAlloc.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "constants.h"
|
|
Packit Service |
d40955 |
#include "types.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static int allocateThreadConfig(ZoneCount logicalZoneCount,
|
|
Packit Service |
d40955 |
ZoneCount physicalZoneCount,
|
|
Packit Service |
d40955 |
ZoneCount hashZoneCount,
|
|
Packit Service |
d40955 |
ZoneCount baseThreadCount,
|
|
Packit Service |
d40955 |
ThreadConfig **configPtr)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
ThreadConfig *config;
|
|
Packit Service |
d40955 |
int result = ALLOCATE(1, ThreadConfig, "thread config", &config);
|
|
Packit Service |
d40955 |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
d40955 |
return result;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
result = ALLOCATE(logicalZoneCount, ThreadID, "logical thread array",
|
|
Packit Service |
d40955 |
&config->logicalThreads);
|
|
Packit Service |
d40955 |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
d40955 |
freeThreadConfig(&config);
|
|
Packit Service |
d40955 |
return result;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
result = ALLOCATE(physicalZoneCount, ThreadID, "physical thread array",
|
|
Packit Service |
d40955 |
&config->physicalThreads);
|
|
Packit Service |
d40955 |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
d40955 |
freeThreadConfig(&config);
|
|
Packit Service |
d40955 |
return result;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
result = ALLOCATE(hashZoneCount, ThreadID, "hash thread array",
|
|
Packit Service |
d40955 |
&config->hashZoneThreads);
|
|
Packit Service |
d40955 |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
d40955 |
freeThreadConfig(&config);
|
|
Packit Service |
d40955 |
return result;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
config->logicalZoneCount = logicalZoneCount;
|
|
Packit Service |
d40955 |
config->physicalZoneCount = physicalZoneCount;
|
|
Packit Service |
d40955 |
config->hashZoneCount = hashZoneCount;
|
|
Packit Service |
d40955 |
config->baseThreadCount = baseThreadCount;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
*configPtr = config;
|
|
Packit Service |
d40955 |
return VDO_SUCCESS;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static void assignThreadIDs(ThreadID threadIDs[],
|
|
Packit Service |
d40955 |
ZoneCount count,
|
|
Packit Service |
d40955 |
ThreadID *idPtr)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
for (ZoneCount zone = 0; zone < count; zone++) {
|
|
Packit Service |
d40955 |
threadIDs[zone] = (*idPtr)++;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
int makeThreadConfig(ZoneCount logicalZoneCount,
|
|
Packit Service |
d40955 |
ZoneCount physicalZoneCount,
|
|
Packit Service |
d40955 |
ZoneCount hashZoneCount,
|
|
Packit Service |
d40955 |
ThreadConfig **configPtr)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
if ((logicalZoneCount == 0)
|
|
Packit Service |
d40955 |
&& (physicalZoneCount == 0)
|
|
Packit Service |
d40955 |
&& (hashZoneCount == 0)) {
|
|
Packit Service |
d40955 |
return makeOneThreadConfig(configPtr);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
if (physicalZoneCount > MAX_PHYSICAL_ZONES) {
|
|
Packit Service |
d40955 |
return logErrorWithStringError(VDO_BAD_CONFIGURATION,
|
|
Packit Service |
d40955 |
"Physical zone count %u exceeds maximum "
|
|
Packit Service |
d40955 |
"(%u)",
|
|
Packit Service |
d40955 |
physicalZoneCount, MAX_PHYSICAL_ZONES);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
if (logicalZoneCount > MAX_LOGICAL_ZONES) {
|
|
Packit Service |
d40955 |
return logErrorWithStringError(VDO_BAD_CONFIGURATION,
|
|
Packit Service |
d40955 |
"Logical zone count %u exceeds maximum "
|
|
Packit Service |
d40955 |
"(%u)",
|
|
Packit Service |
d40955 |
logicalZoneCount, MAX_LOGICAL_ZONES);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
ThreadConfig *config;
|
|
Packit Service |
d40955 |
ThreadCount total = logicalZoneCount + physicalZoneCount + hashZoneCount + 2;
|
|
Packit Service |
d40955 |
int result = allocateThreadConfig(logicalZoneCount, physicalZoneCount,
|
|
Packit Service |
d40955 |
hashZoneCount, total, &config);
|
|
Packit Service |
d40955 |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
d40955 |
return result;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
ThreadID id = 0;
|
|
Packit Service |
d40955 |
config->adminThread = id;
|
|
Packit Service |
d40955 |
config->journalThread = id++;
|
|
Packit Service |
d40955 |
config->packerThread = id++;
|
|
Packit Service |
d40955 |
assignThreadIDs(config->logicalThreads, logicalZoneCount, &id;;
|
|
Packit Service |
d40955 |
assignThreadIDs(config->physicalThreads, physicalZoneCount, &id;;
|
|
Packit Service |
d40955 |
assignThreadIDs(config->hashZoneThreads, hashZoneCount, &id;;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
ASSERT_LOG_ONLY(id == total, "correct number of thread IDs assigned");
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
*configPtr = config;
|
|
Packit Service |
d40955 |
return VDO_SUCCESS;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
int makeZeroThreadConfig(ThreadConfig **configPtr)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
ThreadConfig *config;
|
|
Packit Service |
d40955 |
int result = ALLOCATE(1, ThreadConfig, __func__, &config);
|
|
Packit Service |
d40955 |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
d40955 |
return result;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
config->logicalZoneCount = 0;
|
|
Packit Service |
d40955 |
config->physicalZoneCount = 0;
|
|
Packit Service |
d40955 |
config->hashZoneCount = 0;
|
|
Packit Service |
d40955 |
config->baseThreadCount = 0;
|
|
Packit Service |
d40955 |
*configPtr = config;
|
|
Packit Service |
d40955 |
return VDO_SUCCESS;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
int makeOneThreadConfig(ThreadConfig **configPtr)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
ThreadConfig *config;
|
|
Packit Service |
d40955 |
int result = allocateThreadConfig(1, 1, 1, 1, &config);
|
|
Packit Service |
d40955 |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
d40955 |
return result;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
config->logicalThreads[0] = 0;
|
|
Packit Service |
d40955 |
config->physicalThreads[0] = 0;
|
|
Packit Service |
d40955 |
config->hashZoneThreads[0] = 0;
|
|
Packit Service |
d40955 |
*configPtr = config;
|
|
Packit Service |
d40955 |
return VDO_SUCCESS;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
int copyThreadConfig(const ThreadConfig *oldConfig, ThreadConfig **configPtr)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
ThreadConfig *config;
|
|
Packit Service |
d40955 |
int result = allocateThreadConfig(oldConfig->logicalZoneCount,
|
|
Packit Service |
d40955 |
oldConfig->physicalZoneCount,
|
|
Packit Service |
d40955 |
oldConfig->hashZoneCount,
|
|
Packit Service |
d40955 |
oldConfig->baseThreadCount,
|
|
Packit Service |
d40955 |
&config);
|
|
Packit Service |
d40955 |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
d40955 |
return result;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
config->adminThread = oldConfig->adminThread;
|
|
Packit Service |
d40955 |
config->journalThread = oldConfig->journalThread;
|
|
Packit Service |
d40955 |
config->packerThread = oldConfig->packerThread;
|
|
Packit Service |
d40955 |
for (ZoneCount i = 0; i < config->logicalZoneCount; i++) {
|
|
Packit Service |
d40955 |
config->logicalThreads[i] = oldConfig->logicalThreads[i];
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
for (ZoneCount i = 0; i < config->physicalZoneCount; i++) {
|
|
Packit Service |
d40955 |
config->physicalThreads[i] = oldConfig->physicalThreads[i];
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
for (ZoneCount i = 0; i < config->hashZoneCount; i++) {
|
|
Packit Service |
d40955 |
config->hashZoneThreads[i] = oldConfig->hashZoneThreads[i];
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
*configPtr = config;
|
|
Packit Service |
d40955 |
return VDO_SUCCESS;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
void freeThreadConfig(ThreadConfig **configPtr)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
if (*configPtr == NULL) {
|
|
Packit Service |
d40955 |
return;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
ThreadConfig *config = *configPtr;
|
|
Packit Service |
d40955 |
*configPtr = NULL;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
FREE(config->logicalThreads);
|
|
Packit Service |
d40955 |
FREE(config->physicalThreads);
|
|
Packit Service |
d40955 |
FREE(config->hashZoneThreads);
|
|
Packit Service |
d40955 |
FREE(config);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
static bool getZoneThreadName(const ThreadID threadIDs[],
|
|
Packit Service |
d40955 |
ZoneCount count,
|
|
Packit Service |
d40955 |
ThreadID id,
|
|
Packit Service |
d40955 |
const char *prefix,
|
|
Packit Service |
d40955 |
char *buffer,
|
|
Packit Service |
d40955 |
size_t bufferLength)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
if (id >= threadIDs[0]) {
|
|
Packit Service |
d40955 |
ThreadID index = id - threadIDs[0];
|
|
Packit Service |
d40955 |
if (index < count) {
|
|
Packit Service |
d40955 |
snprintf(buffer, bufferLength, "%s%d", prefix, index);
|
|
Packit Service |
d40955 |
return true;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
return false;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**********************************************************************/
|
|
Packit Service |
d40955 |
void getVDOThreadName(const ThreadConfig *threadConfig,
|
|
Packit Service |
d40955 |
ThreadID threadID,
|
|
Packit Service |
d40955 |
char *buffer,
|
|
Packit Service |
d40955 |
size_t bufferLength)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
if (threadConfig->baseThreadCount == 1) {
|
|
Packit Service |
d40955 |
// Historically this was the "request queue" thread.
|
|
Packit Service |
d40955 |
snprintf(buffer, bufferLength, "reqQ");
|
|
Packit Service |
d40955 |
return;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
if (threadID == threadConfig->journalThread) {
|
|
Packit Service |
d40955 |
snprintf(buffer, bufferLength, "journalQ");
|
|
Packit Service |
d40955 |
return;
|
|
Packit Service |
d40955 |
} else if (threadID == threadConfig->adminThread) {
|
|
Packit Service |
d40955 |
// Theoretically this could be different from the journal thread.
|
|
Packit Service |
d40955 |
snprintf(buffer, bufferLength, "adminQ");
|
|
Packit Service |
d40955 |
return;
|
|
Packit Service |
d40955 |
} else if (threadID == threadConfig->packerThread) {
|
|
Packit Service |
d40955 |
snprintf(buffer, bufferLength, "packerQ");
|
|
Packit Service |
d40955 |
return;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
if (getZoneThreadName(threadConfig->logicalThreads,
|
|
Packit Service |
d40955 |
threadConfig->logicalZoneCount,
|
|
Packit Service |
d40955 |
threadID, "logQ", buffer, bufferLength)) {
|
|
Packit Service |
d40955 |
return;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
if (getZoneThreadName(threadConfig->physicalThreads,
|
|
Packit Service |
d40955 |
threadConfig->physicalZoneCount,
|
|
Packit Service |
d40955 |
threadID, "physQ", buffer, bufferLength)) {
|
|
Packit Service |
d40955 |
return;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
if (getZoneThreadName(threadConfig->hashZoneThreads,
|
|
Packit Service |
d40955 |
threadConfig->hashZoneCount,
|
|
Packit Service |
d40955 |
threadID, "hashQ", buffer, bufferLength)) {
|
|
Packit Service |
d40955 |
return;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
// Some sort of misconfiguration?
|
|
Packit Service |
d40955 |
snprintf(buffer, bufferLength, "reqQ%d", threadID);
|
|
Packit Service |
d40955 |
}
|