<commit_before>/**
 * \file
 * \brief ThreadControlBlock class implementation
 *
 * \author Copyright (C) 2014-2015 <NAME> http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-03-14
 */

#include "distortos/scheduler/ThreadControlBlock.hpp"

#include "distortos/scheduler/getScheduler.hpp"
#include "distortos/scheduler/Scheduler.hpp"
#include "distortos/scheduler/ThreadGroupControlBlock.hpp"

#include "distortos/synchronization/MutexControlBlock.hpp"

#include "distortos/architecture/InterruptMaskingLock.hpp"

#include "distortos/SignalsReceiver.hpp"

#include <cerrno>
#include <cstring>

namespace distortos
{

namespace scheduler
{

/*---------------------------------------------------------------------------------------------------------------------+
| public functions
+---------------------------------------------------------------------------------------------------------------------*/

ThreadControlBlock::ThreadControlBlock(architecture::Stack&& stack, const uint8_t priority,
		const SchedulingPolicy schedulingPolicy, ThreadGroupControlBlock* const threadGroupControlBlock,
		SignalsReceiver* const signalsReceiver, ThreadBase& owner) :
		stack_{std::move(stack)},
		owner_(owner),
		ownedProtocolMutexControlBlocksList_
		{
				MutexControlBlockListAllocator{getScheduler().getMutexControlBlockListAllocatorPool()}
		},
		priorityInheritanceMutexControlBlock_{},
		list_{},
		iterator_{},
		threadGroupControlBlock_{threadGroupControlBlock},
		threadGroupList_{},
		threadGroupIterator_{},
		unblockReason_{},
		signalsReceiverControlBlock_
		{
				signalsReceiver != nullptr ? &signalsReceiver->signalsReceiverControlBlock_ : nullptr
		},
		pendingSignalSet_{SignalSet::empty},
		waitingSignalSet_{},
		priority_{priority},
		boostedPriority_{},
		roundRobinQuantum_{},
		schedulingPolicy_{schedulingPolicy},
		state_{State::New}
{
	_REENT_INIT_PTR(&reent_);
}

ThreadControlBlock::~ThreadControlBlock()
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	if (threadGroupList_ != nullptr)
		threadGroupList_->erase(threadGroupIterator_);

	_reclaim_reent(&reent_);
}

int ThreadControlBlock::acceptPendingSignal(const uint8_t signalNumber)
{
	architecture::InterruptMaskingLock interruptMaskingLock;
	return pendingSignalSet_.remove(signalNumber);
}

int ThreadControlBlock::addHook()
{
	if (threadGroupControlBlock_ == nullptr)
	{
		threadGroupControlBlock_ = getScheduler().getCurrentThreadControlBlock().threadGroupControlBlock_;
		if (threadGroupControlBlock_ == nullptr)
			return EINVAL;
	}

	const auto addRet = threadGroupControlBlock_->add(*this);
	threadGroupList_ = &addRet.first;
	threadGroupIterator_ = addRet.second;
	return 0;
}

SignalSet ThreadControlBlock::getPendingSignalSet() const
{
	architecture::InterruptMaskingLock interruptMaskingLock;
	return pendingSignalSet_;
}

int ThreadControlBlock::generateSignal(const uint8_t signalNumber)
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	const auto ret = pendingSignalSet_.add(signalNumber);
	if (ret != 0)
		return ret;

	if (waitingSignalSet_ == nullptr)
		return 0;

	const auto testResult = waitingSignalSet_->test(signalNumber);<commit_msg>ThreadControlBlock::addHook(): add "this" to SignalsReceiverControlBlock (if it was provided)<commit_after>/**
 * \file
 * \brief ThreadControlBlock class implementation
 *
 * \author Copyright (C) 2014-2015 <NAME> http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-03-14
 */

#include "distortos/scheduler/ThreadControlBlock.hpp"

#include "distortos/scheduler/getScheduler.hpp"
#include "distortos/scheduler/Scheduler.hpp"
#include "distortos/scheduler/ThreadGroupControlBlock.hpp"

#include "distortos/synchronization/MutexControlBlock.hpp"

#include "distortos/architecture/InterruptMaskingLock.hpp"

#include "distortos/SignalsReceiver.hpp"

#include <cerrno>
#include <cstring>

namespace distortos
{

namespace scheduler
{

/*---------------------------------------------------------------------------------------------------------------------+
| public functions
+---------------------------------------------------------------------------------------------------------------------*/

ThreadControlBlock::ThreadControlBlock(architecture::Stack&& stack, const uint8_t priority,
		const SchedulingPolicy schedulingPolicy, ThreadGroupControlBlock* const threadGroupControlBlock,
		SignalsReceiver* const signalsReceiver, ThreadBase& owner) :
		stack_{std::move(stack)},
		owner_(owner),
		ownedProtocolMutexControlBlocksList_
		{
				MutexControlBlockListAllocator{getScheduler().getMutexControlBlockListAllocatorPool()}
		},
		priorityInheritanceMutexControlBlock_{},
		list_{},
		iterator_{},
		threadGroupControlBlock_{threadGroupControlBlock},
		threadGroupList_{},
		threadGroupIterator_{},
		unblockReason_{},
		signalsReceiverControlBlock_
		{
				signalsReceiver != nullptr ? &signalsReceiver->signalsReceiverControlBlock_ : nullptr
		},
		pendingSignalSet_{SignalSet::empty},
		waitingSignalSet_{},
		priority_{priority},
		boostedPriority_{},
		roundRobinQuantum_{},
		schedulingPolicy_{schedulingPolicy},
		state_{State::New}
{
	_REENT_INIT_PTR(&reent_);
}

ThreadControlBlock::~ThreadControlBlock()
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	if (threadGroupList_ != nullptr)
		threadGroupList_->erase(threadGroupIterator_);

	_reclaim_reent(&reent_);
}

int ThreadControlBlock::acceptPendingSignal(const uint8_t signalNumber)
{
	architecture::InterruptMaskingLock interruptMaskingLock;
	return pendingSignalSet_.remove(signalNumber);
}

int ThreadControlBlock::addHook()
{
	if (threadGroupControlBlock_ == nullptr)
	{
		threadGroupControlBlock_ = getScheduler().getCurrentThreadControlBlock().threadGroupControlBlock_;
		if (threadGroupControlBlock_ == nullptr)
			return EINVAL;
	}

	const auto addRet = threadGroupControlBlock_->add(*this);
	threadGroupList_ = &addRet.first;
	threadGroupIterator_ = addRet.second;

	if (signalsReceiverControlBlock_ != nullptr)
		signalsReceiverControlBlock_->setThreadControlBlock(*this);

	return 0;
}

SignalSet ThreadControlBlock::getPendingSignalSet() const
{
	architecture::InterruptMaskingLock interruptMaskingLock;
	return pendingSignalSet_;
}

int ThreadControlBlock::generateSignal(const uint8_t signalNumber)
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	const auto ret = pendingSignalSet_.add(signalNumber);
	if (ret != 0)
		return ret;

	if (waitingSignalSet_ == nullptr)
		return 0;

	const auto testResult = waitingSignalSet_->test(signalNumber);
{'fraction_non_alphanumeric': 0.1621815058688806, 'fraction_numerical': 0.007443458345261953, 'mean_word_length': 4.3092705167173255, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '237022', 'n_tokens_mistral': 2094, 'n_tokens_neox': 1957, 'n_words': 379}