<commit_before>#line 2 "togo/core/system/system/linux.ipp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.
*/

#include <togo/core/config.hpp>
#include <togo/core/error/assert.hpp>
#include <togo/core/utility/utility.hpp>
#include <togo/core/log/log.hpp>
#include <togo/core/string/string.hpp>
#include <togo/core/system/system.hpp>

#include <cerrno>
#include <cstring>

#include <unistd.h>
#include <limits.h>
#include <stdlib.h>
#include <time.h>

#include <sys/types.h>

namespace togo {

unsigned system::pid() {
	pid_t id = ::getpid();
	TOGO_DEBUG_ASSERT(id >= 0, "unexpected pid < 0, what does it mean?");
	return static_cast<unsigned>(id);
}

unsigned system::num_cores() {
	signed const num = ::sysconf(_SC_NPROCESSORS_ONLN);
	return static_cast<unsigned>(max(1, num));
}

StringRef system::hostname() {
	static char name[HOST_NAME_MAX];
	static unsigned size = 0;
	if (size == 0) {
		TOGO_ASSERTE(::gethostname(name, array_extent(name)) == 0);
		size = string::size(name);
	}
	return StringRef{name, size};
}

void system::sleep_ms(unsigned duration_ms) {
	timespec duration;
	timespec remaining;
	duration.tv_sec = duration_ms / 1000;
	duration.tv_nsec = (duration_ms % 1000) * 1000000; // 10^6
	signed err = 0;
	do {
		err = ::nanosleep(&duration, &remaining);
	} while (err != 0 && errno == EINTR);
	if (err != 0 && errno != 0) {
		TOGO_LOG_DEBUGF(
			"sleep_ms: errno = %d, %s\n",
			errno, std::strerror(errno)
		);
	}
}

float system::time_monotonic() {
	timespec ts;
	signed const err = ::clock_gettime(CLOCK_MONOTONIC, &ts);
	TOGO_ASSERTF(
		err == 0,<commit_msg>lib/core/system/system/linux: tidy hostname().¹<commit_after>#line 2 "togo/core/system/system/linux.ipp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.
*/

#include <togo/core/config.hpp>
#include <togo/core/error/assert.hpp>
#include <togo/core/utility/utility.hpp>
#include <togo/core/log/log.hpp>
#include <togo/core/string/string.hpp>
#include <togo/core/system/system.hpp>

#include <cerrno>
#include <cstring>

#include <unistd.h>
#include <limits.h>
#include <stdlib.h>
#include <time.h>

#include <sys/types.h>

namespace togo {

unsigned system::pid() {
	pid_t id = ::getpid();
	TOGO_DEBUG_ASSERT(id >= 0, "unexpected pid < 0, what does it mean?");
	return static_cast<unsigned>(id);
}

unsigned system::num_cores() {
	signed const num = ::sysconf(_SC_NPROCESSORS_ONLN);
	return static_cast<unsigned>(max(1, num));
}

namespace {
	static char cached_hostname[HOST_NAME_MAX]{};
	static unsigned cached_hostname_size = 0;
} // anonymous namespace

StringRef system::hostname() {
	if (cached_hostname_size == 0) {
		TOGO_ASSERTE(::gethostname(cached_hostname, HOST_NAME_MAX) == 0);
		cached_hostname_size = string::size(cached_hostname);
	}
	return StringRef{cached_hostname, cached_hostname_size};
}

void system::sleep_ms(unsigned duration_ms) {
	timespec duration;
	timespec remaining;
	duration.tv_sec = duration_ms / 1000;
	duration.tv_nsec = (duration_ms % 1000) * 1000000; // 10^6
	signed err = 0;
	do {
		err = ::nanosleep(&duration, &remaining);
	} while (err != 0 && errno == EINTR);
	if (err != 0 && errno != 0) {
		TOGO_LOG_DEBUGF(
			"sleep_ms: errno = %d, %s\n",
			errno, std::strerror(errno)
		);
	}
}

float system::time_monotonic() {
	timespec ts;
	signed const err = ::clock_gettime(CLOCK_MONOTONIC, &ts);
	TOGO_ASSERTF(
		err == 0,
{'fraction_non_alphanumeric': 0.15955254636443922, 'fraction_numerical': 0.01766264350897851, 'mean_word_length': 5.014159292035398, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1451862', 'n_tokens_mistral': 1368, 'n_tokens_neox': 1289, 'n_words': 280}