text:
This example demonstrates how to build a library with webpack that has dependencies to other libraries which should not be included in the compiled version.

We use the `libraryTarget: "umd"` option to build a UMD module that is consumable in CommonJs, AMD and with script tags. We don't specify the `library` option so the library is exported to the root namespace.

We use the `externals` option to define dependencies that should be resolved in the target environment.

In the simple case we just need to specify a string (`"add"`). Then it's resolved as `"add"` module in CommonJs and AMD, and as global `add` when used with script tag.

In the complex case we specify different values for each environment:

| environment        | config value             | resolved as                  |
|--------------------|--------------------------|------------------------------|
| CommonJs (strict)  | `["./math", "subtract"]` | `require("./math").subtract` |
| CommonJs (node.js) | `"./subtract"`           | `require("./subtract")`      |
| AMD                | `"subtract"`             | `define(["subtract"], ...)`  |
| script tag         | `"subtract"`             | `this.subtract`              |

# example.js

``` javascript
var add = require("add");
var subtract = require("subtract");

exports.exampleValue = subtract(add(42, 2), 2);
```

# webpack.config.js

``` javascript
module.exports = {
	output: {
		libraryTarget: "umd"
	},
	externals: [
		"add",
		{
			"subtract": {
				root: "subtract",
				commonjs2: "./subtract",
				commonjs: ["./math", "subtract"],
				amd: "subtract"
			}
		}
	]
}
```

# js/output.js

``` javascript
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory(require("add"), require("./subtract"));
	else if(typeof define === 'function' && define.amd)
		define(["add", "subtract"], factory);
	else {
		var a = typeof exports === 'object' ? factory(require("add"), require("./math")["subtract"]) : factory(root["add"], root["subtract"]);
		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
	}
})(this, function(__WEBPACK_EXTERNAL_MODULE_0__, __WEBPACK_EXTERNAL_MODULE_1__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}

/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "js/";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/*!**********************!*\
  !*** external "add" ***!
  \**********************/
/***/ function(module, exports) {

	module.exports = __WEBPACK_EXTERNAL_MODULE_0__;

/***/ },
/* 1 */
/*!***************************************************************************************************************!*\
  !*** external {"root":"subtract","commonjs2":"./subtract","commonjs":["./math","subtract"],"amd":"subtract"} ***!
  \***************************************************************************************************************/
/***/ function(module, exports) {

	module.exports = __WEBPACK_EXTERNAL_MODULE_1__;

/***/ },
/* 2 */
/*!********************!*\
  !*** ./example.js ***!
  \********************/
/***/ function(module, exports, __webpack_require__) {

	var add = __webpack_require__(/*! add */ 0);
	var subtract = __webpack_require__(/*! subtract */ 1);

	exports.exampleValue = subtract(add(42, 2), 2);

/***/ }
/******/ ])
});
;
```

# Info

## Uncompressed

```
Hash: 94d30510034c2c70a921
Version: webpack 2.0.6-beta
Time: 66ms
    Asset    Size  Chunks             Chunk Names
output.js  2.9 kB       0  [emitted]  main
chunk    {0} output.js (main) 197 bytes [rendered]
    > main [2] ./example.js
    [2] ./example.js 113 bytes {0} [built]
     + 2 hidden modules
```

## Minimized (uglify-js, no zip)

```
Hash: 94d30510034c2c70a921
Version: webpack 2.0.6-beta
Time: 165ms
    Asset       Size  Chunks             Chunk Names
output.js  714 bytes       0  [emitted]  main
chunk    {0} output.js (main) 197 bytes [rendered]
    > main [2] ./example.js
    [2] ./example.js 113 bytes {0} [built]
     + 2 hidden modules
```


text:
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace KafkaHttp.Net
{
    internal static class WaitHandleExtensions
    {
        internal static Task ToTask(this WaitHandle waitHandle, string timeoutMessage = null, string successMessage = null)
        {
            var tcs = new TaskCompletionSource<object>();
            ThreadPool.RegisterWaitForSingleObject(
                waitObject: waitHandle,
                callBack: (o, timeout) =>
                {
                    if (timeout)
                    {
                        Trace.TraceError(timeoutMessage);
                        tcs.SetResult(new TimeoutException($"{timeoutMessage} Timeout occured waiting for response."));
                        return;
                    }

                    Trace.TraceInformation(successMessage);
                    tcs.SetResult(null);
                },
                state: null,
                timeout: TimeSpan.FromSeconds(10),
                executeOnlyOnce: true);
            return tcs.Task;
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
---
layout: post
title: nodejs学习笔记——关于V8
date:   2017-08-22 20:30:00 +0800
categories: javascirpt
tag: [v8]
---

* content
{:toc}

## 概念

V8 是Google开发的JavaScript引擎,提供JavaScript运行环境,可以说它就是 Node.js 的发动机。

## 重要知识点

### js引擎的工作流程

- 现在专业的js引擎的工作过程大概是: 源代码->抽象语法树->字节码->JIT->本地代码。
- v8的特点做法是,直接的将抽象语法树通过 JIT 技术转换成本地代码,放弃了在字节码阶段可以进行的一些性能优化,但保证了执行速度。在 V8 生成本地代码后,也会通过 Profiler 采集一些信息,来优化本地代码。虽然,少了生成字节码这一阶段的性能优化, 但极大减少了转换时间。

### 对象、作用域与垃圾回收

### 对象

- V8 为了对内存分配进行管理,GC 需要对 V8 中的 所有对象进行跟踪,而对象都是用 Handle 方式引用的,所以 GC 需要对 Handle 进行管理,这样 GC 就能知道 Heap 中一个对象的引用情况,当一个对象的 Handle 引用发生改变的时候,GC 即可对该对象进行回收或者移动。
- 在v8源码中,`include/v8.h`定义了泛型类`class Local`,代码中有注释,笔者添加中文翻译

```cpp
/**
An object reference managed by the v8 garbage collector.
    对象引用由v8垃圾回收管理

All objects returned from v8 have to be tracked by the garbage
collector so that it knows that the objects are still alive.
    所有从v8返回的对象,都被垃圾回收器追踪与知道对象是否活跃。

Also, because the garbage collector may move objects, it is unsafe to
point directly to an object.
    因为垃圾回收器可能会回收这个对象,如果使用指针直接指向一个对象的地址,那是不安全的。

Instead, all objects are stored in
handles which are known by the garbage collector and updated
whenever an object moves.  Handles should always be passed by value
(except in cases like out-parameters) and they should never be
allocated on the heap.
    所以,所有对象都存储在handles中,handle是被垃圾回收器管理,如果对象被回收就会更新handle.
    Handles一般是用作传参(在输出参数情况下除外),它们不应该被分配在堆heap中

There are two types of handles: local and persistent handles.
    handles有两种,Local 和 Persistent (局部的 与 持久的)

Local handles are light-weight and transient and typically used in
local operations.
    Local handles是轻量的,短暂使用的,一般用于局部的运算。(local本意是局部)

They are managed by HandleScopes. That means that a
HandleScope must exist on the stack when they are created and that they are
only valid inside of the HandleScope active during their creation.
    Local被HandleScopes管理,一个HandleScopes应该存储在栈stack中,当Local被创建后,
    当HandleScopes处于活跃期间,Local才是合法存在的(也就是说,HandleScopes不再处于活跃,Local对象就会被回收)

For passing a local handle to an outer HandleScope, an EscapableHandleScope
and its Escape() method must be used.
    如果,一个local handle传参到外部的HandleScope或者EscapableHandleScope,必须被使用它的Escape()方法
    (闭包的特性,escape逃逸是什么意思?)

Persistent handles can be used when storing objects across several
independent operations and have to be explicitly deallocated when they're no
longer used.
    Persistent handles(持久的对象),可以被用于处理多个独立操作,它如果不在使用,必须被显式回收

It is safe to extract the object stored in the handle by
dereferencing the handle (for instance, to extract the Object* from
a Local<Object>);
    通过封装handle,提取存储在handle的对象,这是安全的。例如,从`Local<Object>`中提取`Object*`指针 ( 这是说把对象的操作等细节封装在Local类中,暴露出来public的函数是安全的 )

the value will still be governed by a handle
behind the scenes and the same rules apply to these values as to
their handles.
    对象的值由handle在背后处理

*/
template <class T>
class Local {
 public:
  V8_INLINE Local() : val_(0) {} // 没有参数的构造函数,初始化私有成员`val_`为0
  template <class S>
  V8_INLINE Local(Local<S> that)
      : val_(reinterpret_cast<T*>(*that)) { // 传参同样是Local<S>的构造函数,初始化私有成员`val_`为传入的参数,并且检查类型S与T是否一样
    /**
     * This check fails when trying to convert between incompatible
     * handles. For example, converting from a Local<String> to a
     * Local<Number>.
     */
    TYPE_CHECK(T, S);
  }
//...

  // 重载操作符`->`,返回私有成员`val_`
  V8_INLINE T* operator->() const { return val_; }

  // 重载操作符`*`,返回私有成员`val_`
  V8_INLINE T* operator*() const { return val_; }

 // .....

 // Handle is an alias for Local for historical reasons.
 // 由于历史原因,Handle是Local的别名
template <class T>
using Handle = Local<T>;
```

- 在`v8/src/objects.h`中,可看,所有js的对象的声明都是需要使用模板,`Handle<Object> object`,这样js的对象就可以被gc管理
- 上面提到一个javascript的高级特性,闭包,实现外部作用域访问内部作用域中变量的方法。
    + 通过函数式编程,高阶函数返回一个函数对象,该函数引用到高阶函数中声明的变量,外部作用域中,可以通过这个中间函数访问或修改高阶函数的变量。
    + 它的问题在于,一旦有变量引用这个中间函数,这个中间函数将不会释放,高阶函数这个原始作用域也不会释放,作用于中产生的内存占用就不会得到释放,除非不再有引用,才会逐步释放。

#### 对象的操作符重载

- 得益于C++的面向对象特性的强大,可以重载对象的操作符,v8是使用C++编写的引擎,自然使用这个特性来实现js的一些语法
- 例子,javascript是使用"+"来实现字符串对象的拼接,v8中字符串对象的代码在`v8/src/inspector/string-16.h`,下面贴出部分代码,加上笔者的注释

```cpp
class String16 {
 public:

    //explicit 避免隐式转换
  explicit String16(const std::basic_string<UChar>& impl) : m_impl(impl) {}

    // 重载操作符=,传入常量的对象的引用
  String16& operator=(const String16& other) {
    m_impl = other.m_impl;
    hash_code = other.hash_code;
    return *this;
  }

    // 重载操作符=,转移&&, 传入String16对象的右值
  String16& operator=(String16&& other) {
      // 左值引用转换为右值引用
    m_impl = std::move(other.m_impl);
    hash_code = other.hash_code;
    return *this;
  }

    // 重载操作符+,右操作数是String16对象引用
  inline String16 operator+(const String16& other) const {
    return String16(m_impl + other.m_impl);
  }
    // 重载操作符+, 左操作数是char*字符指针,右操作数是String16对象引用
  inline String16 operator+(const char* a, const String16& b) {
    return String16(a) + b;
  }

 private:
  std::basic_string<UChar> m_impl; // 私有m_impl实质上使用C++标准库的string对象,string对象的操作符+也是被重载过的
}

```

- 题外话,v8的字符串对象的操作,对于前端项目的平常需求是满足的,但是对于node而言,高并发、大流量的网络字节的处理,是使用stream与Buffer来处理的,而Buffer对象的内存分配不是在v8的堆内存中,而是Node在C++层面实现的,使用slab分配机制,笔者以后详细分析。

#### 作用域

- 从概念上理解,作用域可以看成是一个句柄的容器,在一个作用域里面可以有很多很多个句柄(也就是说,一个 scope 里面可以包含很多很多个 v8 引擎相关的对象),句柄指向的对象是可以一个一个单独地释放的,但是很多时候(真正开始写业务代码的时候),一个一个地释放句柄过于 繁琐,取而代之的是,可以释放一个 scope,那么包含在这个 scope 中的所有 handle 就都会被统一释放掉了。
- 作用域在v8有: HandleScope,Context::Scope
- HandleScope 的定义在`v8/src/handles.h`

```cpp
// After the handle scope of a local handle has been deleted the
// garbage collector will no longer track the object stored in the
// handle and may deallocate it.  The behavior of accessing a handle
// for which the handle scope has been deleted is undefined.
// 局部作用域的handle scope被销毁后,gc不在追踪存储在handle的对象而且回收它,表现在于访问这个作用域的对象会获得undefined
class HandleScope {
 public:
  explicit inline HandleScope(Isolate* isolate);

  // HandleScope 以链表的方式存储, Isolate是当前的虚拟机
  Isolate* isolate_;
  Object** prev_next_;
  Object** prev_limit_;

  // Close the handle scope resetting limits to a previous state.
  static inline void CloseScope(Isolate* isolate,
                                Object** prev_next,
                                Object** prev_limit);

  // Extend the handle scope making room for more handles.
  V8_EXPORT_PRIVATE static Object** Extend(Isolate* isolate);

};

```

- 再看一下`HandleScope`是怎么创建`Handle`与获取`Handle`的

```cpp
Object** HandleScope::CreateHandle(Isolate* isolate, Object* value) {
  DCHECK(AllowHandleAllocation::IsAllowed());
  HandleScopeData* data = isolate->handle_scope_data();

  Object** result = data->next;
  if (result == data->limit) result = Extend(isolate);
  // Update the current next field, set the value in the created
  // handle, and return the result.
  DCHECK(result < data->limit);
  data->next = result + 1;

  *result = value;
  return result;
}

Object** HandleScope::GetHandle(Isolate* isolate, Object* value) {
  DCHECK(AllowHandleAllocation::IsAllowed());
  HandleScopeData* data = isolate->handle_scope_data();
  CanonicalHandleScope* canonical = data->canonical_scope;
  // 寻找对象 lookup
  return canonical ? canonical->Lookup(value) : CreateHandle(isolate, value);
}
```

#### 上下文Context

- 上面提到了Context这个类,看下源码和注解

```cpp
/**
 * A sandboxed execution context with its own set of built-in objects
 * and functions.
  context是一个沙盒的执行上下文,放置内置的对象与函数
 */
class V8_EXPORT Context {
 public:
  /**
   * Returns the global proxy object.
      返回一个全局代理对象
   *
   * Global proxy object is a thin wrapper whose prototype points to actual
   * context's global object with the properties like Object, etc. This is done
   * that way for security reasons (for more details see
   * https://wiki.mozilla.org/Gecko:SplitWindow).
   *
   * Please note that changes to global proxy object prototype most probably
   * would break VM---v8 expects only global object as a prototype of global
   * proxy object.
   */
  Local<Object> Global();

  //...

  /**
   * Stack-allocated class which sets the execution context for all
   * operations executed within a local scope.
   */
  class Scope {
   public:
    explicit V8_INLINE Scope(Local<Context> context) : context_(context) {
      context_->Enter();
    }
    V8_INLINE ~Scope() { context_->Exit(); }

   private:
    Local<Context> context_;
  };
```

- HandleScope 是用来管理 Handle 的,而 Context::Scope 仅仅用来管理 Context 对象。
- 一般情况下,函数的开始部分都放一个 HandleScope,这样此函数中的 Handle 就不需要再理会释放资源了。 而 Context::Scope 仅仅做了:在构造中调用 context->Enter(),而在析构函数中调用 context->Exit()。
- 从概念上讲,这个上下文环境也可以理解为运行环境。在执行 javascript 脚本的时候,总要有一些环境变量或者全局函数。 我们如果要在自己的 c++ 代码中嵌入 v8 引擎,自然希望提供一些 c++ 编写的函数或者模块,让其他用户从脚本中直接调用,这样才会体现出 javascript 的强大。 我们可以用 c++ 编写全局函数或者类,让其他人通过 javascript 进行调用,这样,就无形中扩展了 javascript 的功能。
- Context 可以嵌套,即当前函数有一个 Context,调用其它函数时如果又有一个 Context,则在被调用的函数中 javascript 是以最近的 Context 为准的,当退出这个函数时,又恢复到了原来的 Context。
- 我们可以往不同的 Context 里 "导入" 不同的全局变量及函数,互不影响。据说设计 Context 的最初目的是为了让浏览器在解析 HTML 的 iframe 时,让每个 iframe 都有独立的 javascript 执行环境,即一个 iframe 对应一个 Context。

### 虚拟机

- `Isolate`,一个 Isolate 是一个独立的虚拟机。对应一个或多个线程。但同一时刻 只能被一个线程进入。所有的 Isolate 彼此之间是完全隔离的, 它们不能够有任何共享的资源。如果不显示创建 Isolate, 会自动创建一个默认的 Isolate。

> An isolate is a VM instance with its own heap. It represents an isolated instance of the V8 engine. V8 isolates have completely separate states. Objects from one isolate must not be used in other isolates.

- 上文中提到的`Handle`, `Scope`, `Context`都是在`Isolate`内部的
- 源码`v8/src/isolate.h`与`v8/src/isolate.cc`,以下下贴出笔者觉得有意思的部分代码

```cpp
class Isolate {

  // True if at least one thread Enter'ed this isolate.
  // 线程进入前调用,确认能否进入
  bool IsInUse() { return entry_stack_ != NULL; }

  // Access to top context (where the current function object was created).
  // 返回当前上下文context,当function创建时,需要使用context
  Context* context() { return thread_local_top_.context_; }

  // Returns the global object of the current context. It could be
  // a builtin object, or a JS global object.
  // 获取全局对象
  inline Handle<JSGlobalObject> global_object();

  // Promise的相关函数
  // Push and pop a promise and the current try-catch handler.
  void PushPromise(Handle<JSObject> promise);
  void PopPromise();

  // Return the relevant Promise that a throw/rejection pertains to, based
  // on the contents of the Promise stack
  Handle<Object> GetPromiseOnStackOnThrow();

  // Heuristically guess whether a Promise is handled by user catch handler
  bool PromiseHasUserDefinedRejectHandler(Handle<Object> promise);

}
```

- 将以上代码的promise相关部分展开看,这部分应该和node的线程库Libuv有关联

```cpp
void Isolate::PushPromise(Handle<JSObject> promise) {
  ThreadLocalTop* tltop = thread_local_top();
  PromiseOnStack* prev = tltop->promise_on_stack_;
  Handle<JSObject> global_promise = global_handles()->Create(*promise);
  tltop->promise_on_stack_ = new PromiseOnStack(global_promise, prev);
}

void Isolate::PopPromise() {
  ThreadLocalTop* tltop = thread_local_top();
  if (tltop->promise_on_stack_ == NULL) return;
  PromiseOnStack* prev = tltop->promise_on_stack_->prev();
  Handle<Object> global_promise = tltop->promise_on_stack_->promise();
  delete tltop->promise_on_stack_;
  tltop->promise_on_stack_ = prev;
  global_handles()->Destroy(global_promise.location());
}
```

### 学习心得

- 水平有限,没有在v8没找到链式作用域的`lookup`的清晰的代码

## 参考资料

- [deep-into-node](https://yjhjstz.gitbooks.io/deep-into-node)
- 《深入浅出node》- 朴灵
- [v8引擎使用示例](https://www.ibm.com/developerworks/cn/opensource/os-cn-v8engine/)


text:
"""
Django settings for pntr_dog project.

Generated by 'django-admin startproject' using Django .

For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '*$^if)$#pw8wv(-gz5bft#wuz+#uxp7+df3prkkuxh7=tx7gtw'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

TEMPLATE_DEBUG = DEBUG

ALLOWED_HOSTS = []

# Application definition

DJANGO_APPS = (
    # Default Django apps:
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
)

# Apps specific for this project go here.
LOCAL_APPS = (
)

INSTALLED_APPS = DJANGO_APPS + LOCAL_APPS

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

ROOT_URLCONF = 'pntr_dog.urls'

WSGI_APPLICATION = 'pntr_dog.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE':   'django.db.backends.postgresql_psycopg2',
        'NAME':     'pntr_dog',
        'USER':     '',
        'PASSWORD': '',
        'HOST':     '',
        'PORT':     '',
    }
}

# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/

STATIC_URL = '/static/'


text:
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Diagnosers;
using Org.SbeTool.Sbe.Dll;
using Uk.Co.Real_logic.Sbe.Benchmarks.Fix;

namespace Org.SbeTool.Sbe.Benchmarks
{
    [MemoryDiagnoser]
    public class MarketDataBenchmark
    {
        private readonly byte[] _eBuffer = new byte[1024];
        private readonly byte[] _dBuffer = new byte[1024];
        private DirectBuffer _encodeBuffer;
        private DirectBuffer _decodeBuffer;
        private readonly MarketDataIncrementalRefreshTrades _marketData = new MarketDataIncrementalRefreshTrades();
        private readonly MessageHeader _messageHeader = new MessageHeader();

        [GlobalSetup]
        public void Setup()
        {
            _encodeBuffer = new DirectBuffer(_eBuffer);
            _decodeBuffer = new DirectBuffer(_dBuffer);
            Encode(_decodeBuffer, 0);
        }

        [Benchmark]
        public int Encode()
        {
            return Encode(_encodeBuffer, 0);
        }

        public int Encode(DirectBuffer buffer, int bufferOffset)
        {
            _messageHeader.Wrap(buffer, bufferOffset, 0);
            _messageHeader.BlockLength = MarketDataIncrementalRefreshTrades.BlockLength;
            _messageHeader.TemplateId = MarketDataIncrementalRefreshTrades.TemplateId;
            _messageHeader.SchemaId = MarketDataIncrementalRefreshTrades.SchemaId;
            _messageHeader.Version = MarketDataIncrementalRefreshTrades.SchemaVersion;

            _marketData.WrapForEncode(buffer, bufferOffset + MessageHeader.Size);
            _marketData.TransactTime = 1234L;
            _marketData.EventTimeDelta = 987;
            _marketData.MatchEventIndicator = MatchEventIndicator.END_EVENT;

            var mdIncGrp = _marketData.MdIncGrpCount(2);

            mdIncGrp.Next();
            mdIncGrp.TradeId = 1234L;
            mdIncGrp.SecurityId = 56789L;
            mdIncGrp.MdEntryPx.Mantissa = 50;
            mdIncGrp.MdEntrySize.Mantissa = 10;
            mdIncGrp.NumberOfOrders = 1;
            mdIncGrp.MdUpdateAction = MDUpdateAction.NEW;
            mdIncGrp.RptSeq = 1;
            mdIncGrp.AggressorSide = Side.BUY;

            mdIncGrp.Next();
            mdIncGrp.TradeId = 1234L;
            mdIncGrp.SecurityId = 56789L;
            mdIncGrp.MdEntryPx.Mantissa = 50;
            mdIncGrp.MdEntrySize.Mantissa = 10;
            mdIncGrp.NumberOfOrders = 1;
            mdIncGrp.MdUpdateAction = MDUpdateAction.NEW;
            mdIncGrp.RptSeq = 1;
            mdIncGrp.AggressorSide = Side.SELL;

            return _marketData.Size;
        }

        [Benchmark]
        public int Decode()
        {
            return Decode(_decodeBuffer, 0);
        }

        public int Decode(DirectBuffer buffer, int bufferOffset)
        {
            _messageHeader.Wrap(buffer, bufferOffset, 0);

            int actingVersion = _messageHeader.Version;
            int actingBlockLength = _messageHeader.BlockLength;

            _marketData.WrapForDecode(buffer, bufferOffset + MessageHeader.Size, actingBlockLength, actingVersion);

            var transactTime = _marketData.TransactTime;
            var matchEventIndicator = _marketData.MatchEventIndicator;

            var mdIncGrpGroup = _marketData.MdIncGrp;
            while (mdIncGrpGroup.HasNext)
            {
                mdIncGrpGroup.Next();
                var tradeId = mdIncGrpGroup.TradeId;
                var securityId = mdIncGrpGroup.SecurityId;
                var mantissa = mdIncGrpGroup.MdEntryPx.Mantissa;
                var i = mdIncGrpGroup.MdEntrySize.Mantissa;
                var numberOfOrders = mdIncGrpGroup.NumberOfOrders;
                var mdUpdateAction = mdIncGrpGroup.MdUpdateAction;
                var rptSeq = mdIncGrpGroup.RptSeq;
                var aggressorSide = mdIncGrpGroup.AggressorSide;
                var mdEntryType = mdIncGrpGroup.MdEntryType;
            }

            return _marketData.Size;
        }
    }
}


text:
foreach(lang)
  include(CMakeFiles/tests.dir/cmake_clean_${lang}.cmake OPTIONAL)
endforeach()


text:
PhusionPassenger.require_passenger_lib 'ruby_core_enhancements'
PhusionPassenger.require_passenger_lib 'standalone/config_options_list'

module PhusionPassenger
  module Standalone

    module ConfigUtils
      extend self    # Make methods available as class methods.

      def self.included(klass)
        # When included into another class, make sure that Utils
        # methods are made private.
        public_instance_methods(false).each do |method_name|
          klass.send(:private, method_name)
        end
      end

      class ConfigLoadError < StandardError
      end

      def global_config_file_path
        @global_config_file_path ||= File.join(PhusionPassenger.home_dir,
          USER_NAMESPACE_DIRNAME, "standalone", "config.json")
      end

      def load_local_config_file_from_app_dir_param!(argv)
        if argv.empty?
          app_dir = Dir.logical_pwd
        elsif argv.size == 1
          app_dir = argv[0]
        end
        local_options = {}
        if app_dir
          begin
            ConfigUtils.load_local_config_file!(app_dir, local_options)
          rescue ConfigUtils::ConfigLoadError => e
            abort "*** ERROR: #{e.message}"
          end
        end
        local_options
      end

      def load_local_config_file!(app_dir, options)
        config_file = File.join(app_dir, "Passengerfile.json")
        if !File.exist?(config_file)
          config_file = File.join(app_dir, "passenger-standalone.json")
        end
        if File.exist?(config_file)
          local_options = load_config_file(config_file)
          options.merge!(local_options)
        end
      end

      def load_config_file(filename)
        if !defined?(PhusionPassenger::Utils::JSON)
          PhusionPassenger.require_passenger_lib 'utils/json'
        end
        begin
          data = File.open(filename, "r:utf-8") do |f|
            f.read
          end
        rescue SystemCallError => e
          raise ConfigLoadError, "cannot load config file #{filename} (#{e})"
        end

        begin
          config = PhusionPassenger::Utils::JSON.parse(data)
        rescue => e
          raise ConfigLoadError, "cannot parse config file #{filename} (#{e})"
        end
        if !config.is_a?(Hash)
          raise ConfigLoadError, "cannot parse config file #{filename} (it does not contain an object)"
        end

        result = {}
        config_file_dir = File.dirname(File.absolute_logical_path(filename))
        config.each_pair do |key, val|
          key = key.to_sym
          spec_item = CONFIG_NAME_INDEX[key]
          if spec_item
            begin
              result[key] = parse_config_value(spec_item, val, config_file_dir)
            rescue ConfigLoadError => e
              raise ConfigLoadError, "cannot parse config file #{filename} " \
                "(error in config option '#{key}': #{e.message})"
            end
          else
            STDERR.puts "*** WARNING: #{filename}: configuration key '#{key}' is not supported"
            result[key] = val
          end
        end

        result
      end

      def load_env_config!
        begin
          load_env_config
        rescue ConfigUtils::ConfigLoadError => e
          abort "*** ERROR: #{e.message}"
        end
      end

      def load_env_config
        config = {}
        pwd = Dir.logical_pwd

        ENV.each_pair do |name, value|
          next if name !~ /^PASSENGER_(.+)/
          key = $1.downcase.to_sym
          spec_item = CONFIG_NAME_INDEX[key]
          next if !spec_item
          next if !config_type_supported_in_envvar?(spec_item[:type])
          next if value.empty?

          begin
            config[key] = parse_config_value(spec_item, value, pwd)
          rescue ConfigLoadError => e
            raise ConfigLoadError, "cannot parse environment variable '#{name}' " \
              "(#{e.message})"
          end
        end

        config
      end

      def add_option_parser_options_from_config_spec(parser, spec, options)
        spec.each do |spec_item|
          next if spec_item[:cli].nil?
          args = []

          if spec_item[:short_cli]
            args << spec_item[:short_cli]
          end

          args << make_long_cli_switch(spec_item)

          if type = determine_cli_switch_type(spec_item)
            args << type
          end

          args << format_cli_switch_description(spec_item)

          cli_parser = make_cli_switch_parser(parser, spec_item, options)

          parser.on(*args, &cli_parser)
        end
      end

      # We want the command line options to override the options in the local
      # config file, but the local config file could only be parsed when the
      # command line options have been parsed. This method remerges all the
      # config options from different sources so that options are overriden
      # according to the following order:
      #
      # - CONFIG_DEFAULTS
      # - global config file
      # - local config file
      # - environment variables
      # - command line options
      def remerge_all_config(global_options, local_options, env_options, parsed_options)
        CONFIG_DEFAULTS.merge(remerge_all_config_without_defaults(
          global_options, local_options, env_options, parsed_options))
      end

      def remerge_all_config_without_defaults(global_options, local_options, env_options, parsed_options)
        global_options.
          merge(local_options).
          merge(env_options).
          merge(parsed_options)
      end

      def find_pid_and_log_file(execution_root, options)
        if options[:socket_file]
          pid_basename = 'passenger.pid'
          log_basename = 'passenger.log'
        else
          pid_basename = "passenger.#{options[:port]}.pid"
          log_basename = "passenger.#{options[:port]}.log"
        end
        if File.directory?("#{execution_root}/tmp/pids")
          options[:pid_file] ||= "#{execution_root}/tmp/pids/#{pid_basename}"
        else
          options[:pid_file] ||= "#{execution_root}/#{pid_basename}"
        end
        if File.directory?("#{execution_root}/log")
          options[:log_file] ||= "#{execution_root}/log/#{log_basename}"
        else
          options[:log_file] ||= "#{execution_root}/#{log_basename}"
        end
      end

    private
      def config_type_supported_in_envvar?(type)
        type == :string || type == :integer || type == :boolean ||
          type == :path || type == :hostname
      end

      def parse_config_value(spec_item, value, base_dir)
        if parser = spec_item[:config_value_parser]
          return parser.call(value, base_dir)
        end

        case spec_item[:type]
        when :string
          value.to_s
        when :integer
          value = value.to_i
          if spec_item[:min] && value < spec_item[:min]
            raise ConfigLoadError, "value must be greater than or equal to #{spec_item[:min]}"
          else
            value
          end
        when :boolean
          value = value.to_s.downcase
          value == 'true' || value == 'yes' || value == 'on' || value == '1'
        when :path
          File.absolute_logical_path(value.to_s, base_dir)
        when :array
          if value.is_a?(Array)
            value
          else
            raise ConfigLoadError, "array expected"
          end
        when :map
          if value.is_a?(Hash)
            value
          else
            raise ConfigLoadError, "map expected"
          end
        when :hostname
          begin
            resolve_hostname(value)
          rescue SocketError => e
            raise ConfigLoadError, "hostname #{value} cannot be resolved: #{e}"
          end
        else
          raise ArgumentError, "Unsupported type #{spec_item[:type]}"
        end
      end

      def make_long_cli_switch(spec_item)
        case spec_item[:type]
        when :string, :integer, :path, :array, :map, :hostname
          "#{spec_item[:cli]} #{spec_item[:type_desc]}"
        when :boolean
          spec_item[:cli]
        else
          raise ArgumentError,
            "Cannot create long CLI switch for type #{spec_item[:type]}"
        end
      end

      def determine_cli_switch_type(spec_item)
        case spec_item[:type]
        when :string, :path, :array, :map, :hostname
          String
        when :integer
          Integer
        when :boolean
          nil
        else
          raise ArgumentError,
            "Cannot determine CLI switch type for #{spec_item[:type]}"
        end
      end

      def format_cli_switch_description(spec_item)
        desc = spec_item[:desc]
        return '(no description)' if desc.nil?
        result = desc.gsub("\n", "\n" + ' ' * 37)
        result.gsub!('%DEFAULT%', (spec_item[:default] || 'N/A').to_s)
        result
      end

      def make_cli_switch_parser(parser, spec_item, options)
        if cli_parser = spec_item[:cli_parser]
          lambda do |value|
            cli_parser.call(options, value)
          end
        elsif spec_item[:type] == :integer
          lambda do |value|
            if spec_item[:min] && value < spec_item[:min]
              abort "*** ERROR: you may only specify for #{spec_item[:cli]} " \
                "a number greater than or equal to #{spec_item[:min]}"
            end
            options[spec_item[:name]] = value
          end
        elsif spec_item[:type] == :path
          lambda do |value|
            options[spec_item[:name]] = File.absolute_logical_path(value,
              Dir.logical_pwd)
          end
        elsif spec_item[:type] == :boolean
          lambda do |value|
            options[spec_item[:name]] = true
          end
        elsif spec_item[:type] == :hostname
          lambda do |value|
            begin
              options[spec_item[:name]] = resolve_hostname(value)
            rescue SocketError => e
              abort "*** ERROR: the hostname passed to #{spec_item[:cli]}, #{value}, cannot be resolved: #{e}"
            end
          end
        else
          lambda do |value|
            options[spec_item[:name]] = value
          end
        end
      end

      def resolve_hostname(hostname)
        # We resolve the hostname into an IP address during configuration loading
        # because different components in the system (Nginx, Passenger core) may
        # resolve hostnames differently. If a hostname resolves to multiple addresses
        # (for example, to an IPv6 and an IPv4 address) then different components may
        # pick a different address as 'winner'. By resolving the hostname here, we
        # guarantee consistent behavior.
        #
        # Furthermore, `rails server` defaults to setting the hostname to 'localhost'.
        # But the user almost certainly doesn't explicitly want it to resolve to an IPv6
        # address because most tools work better with IPv4 and because `http://[::1]:3000`
        # just looks weird. So we special case 'localhost' and resolve it to 127.0.0.1.
        if hostname.downcase == 'localhost'
          '127.0.0.1'
        else
          Socket.getaddrinfo(hostname, nil).first[3]
        end
      end
    end

  end # module Standalone
end # module PhusionPassenger


text:
#if defined(SOKOL_IMPL) && !defined(SOKOL_MEMTRACK_IMPL)
#define SOKOL_MEMTRACK_IMPL
#endif
#ifndef SOKOL_MEMTRACK_INCLUDED

#define SOKOL_MEMTRACK_INCLUDED (1)
#include <stddef.h>
#include <stdint.h>

#if defined(SOKOL_API_DECL) && !defined(SOKOL_MEMTRACK_API_DECL)
#define SOKOL_MEMTRACK_API_DECL SOKOL_API_DECL
#endif
#ifndef SOKOL_MEMTRACK_API_DECL
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_MEMTRACK_IMPL)
#define SOKOL_MEMTRACK_API_DECL __declspec(dllexport)
#elif defined(_WIN32) && defined(SOKOL_DLL)
#define SOKOL_MEMTRACK_API_DECL __declspec(dllimport)
#else
#define SOKOL_MEMTRACK_API_DECL extern
#endif
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct smemtrack_info_t {
    int num_allocs;
    int num_bytes;
} smemtrack_info_t;

SOKOL_MEMTRACK_API_DECL smemtrack_info_t smemtrack_info(void);

#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SOKOL_MEMTRACK_INCLUDED */

/*=== IMPLEMENTATION =========================================================*/
#ifdef SOKOL_MEMTRACK_IMPL
#define SOKOL_MEMTRACK_IMPL_INCLUDED (1)
#include <stdlib.h> /* malloc, free, calloc */
#include <string.h> /* memset */

#ifndef SOKOL_API_IMPL
    #define SOKOL_API_IMPL
#endif
#ifndef SOKOL_DEBUG
    #ifndef NDEBUG
        #define SOKOL_DEBUG (1)
    #endif
#endif
#ifndef _SOKOL_PRIVATE
    #if defined(__GNUC__) || defined(__clang__)
        #define _SOKOL_PRIVATE __attribute__((unused)) static
    #else
        #define _SOKOL_PRIVATE static
    #endif
#endif

#define SOKOL_MALLOC(s) _smemtrack_malloc(s)
#define SOKOL_FREE(p) _smemtrack_free(p)
#define SOKOL_CALLOC(n,s) _smemtrack_calloc(n,s)

#define _SMEMTRACK_HEADER_SIZE (16)

static struct {
    smemtrack_info_t state;
} _smemtrack;

_SOKOL_PRIVATE void* _smemtrack_malloc(size_t size) {
    _smemtrack.state.num_allocs++;
    _smemtrack.state.num_bytes += (int) size;
    uint8_t* ptr = (uint8_t*) malloc(size + _SMEMTRACK_HEADER_SIZE);
    *(size_t*)ptr = size;
    return ptr + _SMEMTRACK_HEADER_SIZE;
}

_SOKOL_PRIVATE void _smemtrack_free(void* ptr) {
    uint8_t* alloc_ptr = ((uint8_t*)ptr) - _SMEMTRACK_HEADER_SIZE;
    size_t size = *(size_t*)alloc_ptr;
    _smemtrack.state.num_allocs--;
    _smemtrack.state.num_bytes -= (int) size;
    free(alloc_ptr);
}

_SOKOL_PRIVATE void* _smemtrack_calloc(size_t num, size_t size) {
    size_t mem_size = num * size;
    _smemtrack.state.num_allocs++;
    _smemtrack.state.num_bytes += (int) mem_size;
    uint8_t* ptr = (uint8_t*) malloc(mem_size + _SMEMTRACK_HEADER_SIZE);
    memset(ptr + _SMEMTRACK_HEADER_SIZE, 0, mem_size);
    *(size_t*)ptr = size;
    return ptr + _SMEMTRACK_HEADER_SIZE;
}

SOKOL_API_IMPL smemtrack_info_t smemtrack_info(void) {
    return _smemtrack.state;
}

#endif /* SOKOL_MEMTRACK_IMPL */


text:
#if defined(_WIN32)
// prevent compile error because MSVC doesn't realize in debug build that
// LOG(FATAL) finally invokes abort()
#pragma warning(disable : 4716)
#endif  // _WIN32

#ifndef TENSORFLOW_CORE_PLATFORM_DEFAULT_LOGGING_H_
#define TENSORFLOW_CORE_PLATFORM_DEFAULT_LOGGING_H_

// IWYU pragma: private, include "third_party/tensorflow/core/platform/logging.h"
// IWYU pragma: friend third_party/tensorflow/core/platform/logging.h

#include <atomic>
#include <limits>
#include <memory>
#include <sstream>
#include <vector>

#include "absl/base/log_severity.h"
#include "absl/strings/string_view.h"
#include "tensorflow/core/platform/macros.h"
#include "tensorflow/core/platform/types.h"

// TODO(mrry): Prevent this Windows.h #define from leaking out of our headers.
#undef ERROR

namespace tensorflow {
const int INFO = 0;            // base_logging::INFO;
const int WARNING = 1;         // base_logging::WARNING;
const int ERROR = 2;           // base_logging::ERROR;
const int FATAL = 3;           // base_logging::FATAL;
const int NUM_SEVERITIES = 4;  // base_logging::NUM_SEVERITIES;

namespace internal {

class LogMessage : public std::basic_ostringstream<char> {
 public:
  LogMessage(const char* fname, int line, int severity);
  ~LogMessage() override;

  // Change the location of the log message.
  LogMessage& AtLocation(const char* fname, int line);

  // Returns the maximum log level for VLOG statements.
  // E.g., if MaxVLogLevel() is 2, then VLOG(2) statements will produce output,
  // but VLOG(3) will not. Defaults to 0.
  static int64 MaxVLogLevel();

  // Returns whether VLOG level lvl is activated for the file fname.
  //
  // E.g. if the environment variable TF_CPP_VMODULE contains foo=3 and fname is
  // foo.cc and lvl is <= 3, this will return true. It will also return true if
  // the level is lower or equal to TF_CPP_MAX_VLOG_LEVEL (default zero).
  //
  // It is expected that the result of this query will be cached in the VLOG-ing
  // call site to avoid repeated lookups. This routine performs a hash-map
  // access against the VLOG-ing specification provided by the env var.
  static bool VmoduleActivated(const char* fname, int level);

 protected:
  void GenerateLogMessage();

 private:
  const char* fname_;
  int line_;
  int severity_;
};

// Uses the lower operator & precedence to voidify a LogMessage reference, so
// that the ternary VLOG() implementation is balanced, type wise.
struct Voidifier {
  template <typename T>
  void operator&(const T&)const {}
};

// LogMessageFatal ensures the process will exit in failure after
// logging this message.
class LogMessageFatal : public LogMessage {
 public:
  LogMessageFatal(const char* file, int line) TF_ATTRIBUTE_COLD;
  TF_ATTRIBUTE_NORETURN ~LogMessageFatal() override;
};

// LogMessageNull supports the DVLOG macro by simply dropping any log messages.
class LogMessageNull : public std::basic_ostringstream<char> {
 public:
  LogMessageNull() {}
  ~LogMessageNull() override {}
};

#define _TF_LOG_INFO \
  ::tensorflow::internal::LogMessage(__FILE__, __LINE__, ::tensorflow::INFO)
#define _TF_LOG_WARNING \
  ::tensorflow::internal::LogMessage(__FILE__, __LINE__, ::tensorflow::WARNING)
#define _TF_LOG_ERROR \
  ::tensorflow::internal::LogMessage(__FILE__, __LINE__, ::tensorflow::ERROR)
#define _TF_LOG_FATAL \
  ::tensorflow::internal::LogMessageFatal(__FILE__, __LINE__)

#define _TF_LOG_QFATAL _TF_LOG_FATAL

#define LOG(severity) _TF_LOG_##severity

#ifdef IS_MOBILE_PLATFORM

// Turn VLOG off when under mobile devices for considerations of binary size.
#define VLOG_IS_ON(lvl) ((lvl) <= 0)

#else

// Otherwise, set TF_CPP_MAX_VLOG_LEVEL environment to update minimum log level
// of VLOG, or TF_CPP_VMODULE to set the minimum log level for individual
// translation units.
#define VLOG_IS_ON(lvl)                                                     \
  (([](int level, const char* fname) {                                      \
    static const bool vmodule_activated =                                   \
        ::tensorflow::internal::LogMessage::VmoduleActivated(fname, level); \
    return vmodule_activated;                                               \
  })(lvl, __FILE__))

#endif

#define VLOG(level)                                              \
  TF_PREDICT_TRUE(!VLOG_IS_ON(level))                            \
  ? (void)0                                                      \
  : ::tensorflow::internal::Voidifier() &                        \
          ::tensorflow::internal::LogMessage(__FILE__, __LINE__, \
                                             tensorflow::INFO)

// `DVLOG` behaves like `VLOG` in debug mode (i.e. `#ifndef NDEBUG`).
// Otherwise, it compiles away and does nothing.
#ifndef NDEBUG
#define DVLOG VLOG
#else
#define DVLOG(verbose_level) \
  while (false && (verbose_level) > 0) ::tensorflow::internal::LogMessageNull()
#endif

class LogEveryNState {
 public:
  bool ShouldLog(int n);
  uint32_t counter() { return counter_.load(std::memory_order_relaxed); }

 private:
  std::atomic<uint32> counter_{0};
};

class LogFirstNState {
 public:
  bool ShouldLog(int n);
  uint32 counter() { return counter_.load(std::memory_order_relaxed); }

 private:
  std::atomic<uint32> counter_{0};
};

class LogEveryPow2State {
 public:
  bool ShouldLog(int ignored);
  uint32 counter() { return counter_.load(std::memory_order_relaxed); }

 private:
  std::atomic<uint32> counter_{0};
};

class LogEveryNSecState {
 public:
  bool ShouldLog(double seconds);
  uint32 counter() { return counter_.load(std::memory_order_relaxed); }

 private:
  std::atomic<uint32> counter_{0};
  // Cycle count according to CycleClock that we should next log at.
  std::atomic<int64> next_log_time_cycles_{0};
};

// This macro has a lot going on!
//
// * A local static (`logging_internal_stateful_condition_state`) is
//   declared in a scope such that each `LOG_EVERY_N` (etc.) line has its own
//   state.
// * `COUNTER`, the third variable, is used to support `<< COUNTER`. It is not
//   mangled, so shadowing can be a problem, albeit more of a
//   shoot-yourself-in-the-foot one.  Don't name your variables `COUNTER`.
// * A single for loop can declare state and also test
//   `condition && state.ShouldLog()`, but there's no way to constrain it to run
//   only once (or not at all) without declaring another variable.  The outer
//   for-loop declares this variable (`do_log`).
// * Using for loops instead of if statements means there's no risk of an
//   ambiguous dangling else statement.
#define LOGGING_INTERNAL_STATEFUL_CONDITION(kind, condition, arg)   \
  for (bool logging_internal_stateful_condition_do_log(condition);  \
       logging_internal_stateful_condition_do_log;                  \
       logging_internal_stateful_condition_do_log = false)          \
    for (static ::tensorflow::internal::Log##kind##State            \
             logging_internal_stateful_condition_state;             \
         logging_internal_stateful_condition_do_log &&              \
         logging_internal_stateful_condition_state.ShouldLog(arg);  \
         logging_internal_stateful_condition_do_log = false)        \
      for (const uint32_t COUNTER ABSL_ATTRIBUTE_UNUSED =           \
               logging_internal_stateful_condition_state.counter(); \
           logging_internal_stateful_condition_do_log;              \
           logging_internal_stateful_condition_do_log = false)

// An instance of `LOG_EVERY_N` increments a hidden zero-initialized counter
// every time execution passes through it and logs the specified message when
// the counter's value is a multiple of `n`, doing nothing otherwise.  Each
// instance has its own counter.  The counter's value can be logged by streaming
// the symbol `COUNTER`.  `LOG_EVERY_N` is thread-safe.
// Example:
//
//   for (const auto& user : all_users) {
//     LOG_EVERY_N(INFO, 1000) << "Processing user #" << COUNTER;
//     ProcessUser(user);
//   }
#define LOG_EVERY_N(severity, n)                       \
  LOGGING_INTERNAL_STATEFUL_CONDITION(EveryN, true, n) \
  LOG(severity)
// `LOG_FIRST_N` behaves like `LOG_EVERY_N` except that the specified message is
// logged when the counter's value is less than `n`.  `LOG_FIRST_N` is
// thread-safe.
#define LOG_FIRST_N(severity, n)                       \
  LOGGING_INTERNAL_STATEFUL_CONDITION(FirstN, true, n) \
  LOG(severity)
// `LOG_EVERY_POW_2` behaves like `LOG_EVERY_N` except that the specified
// message is logged when the counter's value is a power of 2.
// `LOG_EVERY_POW_2` is thread-safe.
#define LOG_EVERY_POW_2(severity)                         \
  LOGGING_INTERNAL_STATEFUL_CONDITION(EveryPow2, true, 0) \
  LOG(severity)
// An instance of `LOG_EVERY_N_SEC` uses a hidden state variable to log the
// specified message at most once every `n_seconds`.  A hidden counter of
// executions (whether a message is logged or not) is also maintained and can be
// logged by streaming the symbol `COUNTER`.  `LOG_EVERY_N_SEC` is thread-safe.
// Example:
//
//   LOG_EVERY_N_SEC(INFO, 2.5) << "Got " << COUNTER << " cookies so far";
#define LOG_EVERY_N_SEC(severity, n_seconds)                      \
  LOGGING_INTERNAL_STATEFUL_CONDITION(EveryNSec, true, n_seconds) \
  LOG(severity)

// CHECK dies with a fatal error if condition is not true.  It is *not*
// controlled by NDEBUG, so the check will be executed regardless of
// compilation mode.  Therefore, it is safe to do things like:
//    CHECK(fp->Write(x) == 4)
#define CHECK(condition)              \
  if (TF_PREDICT_FALSE(!(condition))) \
  LOG(FATAL) << "Check failed: " #condition " "

// Function is overloaded for integral types to allow static const
// integrals declared in classes and not defined to be used as arguments to
// CHECK* macros. It's not encouraged though.
template <typename T>
inline const T& GetReferenceableValue(const T& t) {
  return t;
}
inline char GetReferenceableValue(char t) { return t; }
inline unsigned char GetReferenceableValue(unsigned char t) { return t; }
inline signed char GetReferenceableValue(signed char t) { return t; }
inline int16 GetReferenceableValue(int16 t) { return t; }
inline uint16 GetReferenceableValue(uint16 t) { return t; }
inline int GetReferenceableValue(int t) { return t; }
inline unsigned int GetReferenceableValue(unsigned int t) { return t; }
inline int64 GetReferenceableValue(int64 t) { return t; }
inline uint64 GetReferenceableValue(uint64 t) { return t; }

// This formats a value for a failing CHECK_XX statement.  Ordinarily,
// it uses the definition for operator<<, with a few special cases below.
template <typename T>
inline void MakeCheckOpValueString(std::ostream* os, const T& v) {
  (*os) << v;
}

// Overrides for char types provide readable values for unprintable
// characters.
template <>
void MakeCheckOpValueString(std::ostream* os, const char& v);
template <>
void MakeCheckOpValueString(std::ostream* os, const signed char& v);
template <>
void MakeCheckOpValueString(std::ostream* os, const unsigned char& v);

#if LANG_CXX11
// We need an explicit specialization for std::nullptr_t.
template <>
void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& v);
#endif

// A container for a string pointer which can be evaluated to a bool -
// true iff the pointer is non-NULL.
struct CheckOpString {
  explicit CheckOpString(string* str) : str_(str) {}
  // No destructor: if str_ is non-NULL, we're about to LOG(FATAL),
  // so there's no point in cleaning up str_.
  explicit operator bool() const { return TF_PREDICT_FALSE(str_ != nullptr); }
  string* str_;
};

// Build the error message string. Specify no inlining for code size.
template <typename T1, typename T2>
string* MakeCheckOpString(const T1& v1, const T2& v2,
                          const char* exprtext) TF_ATTRIBUTE_NOINLINE;

// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
// statement.  See MakeCheckOpString for sample usage.  Other
// approaches were considered: use of a template method (e.g.,
// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1,
// base::Print<T2>, &v2), however this approach has complications
// related to volatile arguments and function-pointer arguments).
class CheckOpMessageBuilder {
 public:
  // Inserts "exprtext" and " (" to the stream.
  explicit CheckOpMessageBuilder(const char* exprtext);
  // Deletes "stream_".
  ~CheckOpMessageBuilder();
  // For inserting the first variable.
  std::ostream* ForVar1() { return stream_; }
  // For inserting the second variable (adds an intermediate " vs. ").
  std::ostream* ForVar2();
  // Get the result (inserts the closing ")").
  string* NewString();

 private:
  std::ostringstream* stream_;
};

template <typename T1, typename T2>
string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) {
  CheckOpMessageBuilder comb(exprtext);
  MakeCheckOpValueString(comb.ForVar1(), v1);
  MakeCheckOpValueString(comb.ForVar2(), v2);
  return comb.NewString();
}

// Helper functions for CHECK_OP macro.
// The (int, int) specialization works around the issue that the compiler
// will not instantiate the template version of the function on values of
// unnamed enum type - see comment below.
// The (size_t, int) and (int, size_t) specialization are to handle unsigned
// comparison errors while still being thorough with the comparison.
#define TF_DEFINE_CHECK_OP_IMPL(name, op)                                 \
  template <typename T1, typename T2>                                     \
  inline string* name##Impl(const T1& v1, const T2& v2,                   \
                            const char* exprtext) {                       \
    if (TF_PREDICT_TRUE(v1 op v2))                                        \
      return NULL;                                                        \
    else                                                                  \
      return ::tensorflow::internal::MakeCheckOpString(v1, v2, exprtext); \
  }                                                                       \
  inline string* name##Impl(int v1, int v2, const char* exprtext) {       \
    return name##Impl<int, int>(v1, v2, exprtext);                        \
  }                                                                       \
  inline string* name##Impl(const size_t v1, const int v2,                \
                            const char* exprtext) {                       \
    if (TF_PREDICT_FALSE(v2 < 0)) {                                       \
      return ::tensorflow::internal::MakeCheckOpString(v1, v2, exprtext); \
    }                                                                     \
    return name##Impl<size_t, size_t>(v1, v2, exprtext);                  \
  }                                                                       \
  inline string* name##Impl(const int v1, const size_t v2,                \
                            const char* exprtext) {                       \
    if (TF_PREDICT_FALSE(v2 >= std::numeric_limits<int>::max())) {        \
      return ::tensorflow::internal::MakeCheckOpString(v1, v2, exprtext); \
    }                                                                     \
    const size_t uval = (size_t)((unsigned)v2);                           \
    return name##Impl<size_t, size_t>(v1, uval, exprtext);                \
  }

// We use the full name Check_EQ, Check_NE, etc. in case the file including
// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
// This happens if, for example, those are used as token names in a
// yacc grammar.
TF_DEFINE_CHECK_OP_IMPL(Check_EQ,
                        ==)  // Compilation error with CHECK_EQ(NULL, x)?
TF_DEFINE_CHECK_OP_IMPL(Check_NE, !=)  // Use CHECK(x == NULL) instead.
TF_DEFINE_CHECK_OP_IMPL(Check_LE, <=)
TF_DEFINE_CHECK_OP_IMPL(Check_LT, <)
TF_DEFINE_CHECK_OP_IMPL(Check_GE, >=)
TF_DEFINE_CHECK_OP_IMPL(Check_GT, >)
#undef TF_DEFINE_CHECK_OP_IMPL

// In optimized mode, use CheckOpString to hint to compiler that
// the while condition is unlikely.
#define CHECK_OP_LOG(name, op, val1, val2)                     \
  while (::tensorflow::internal::CheckOpString _result{        \
      ::tensorflow::internal::name##Impl(                      \
          ::tensorflow::internal::GetReferenceableValue(val1), \
          ::tensorflow::internal::GetReferenceableValue(val2), \
          #val1 " " #op " " #val2)})                           \
  ::tensorflow::internal::LogMessageFatal(__FILE__, __LINE__) << *(_result.str_)

#define CHECK_OP(name, op, val1, val2) CHECK_OP_LOG(name, op, val1, val2)

// CHECK_EQ/NE/...
#define CHECK_EQ(val1, val2) CHECK_OP(Check_EQ, ==, val1, val2)
#define CHECK_NE(val1, val2) CHECK_OP(Check_NE, !=, val1, val2)
#define CHECK_LE(val1, val2) CHECK_OP(Check_LE, <=, val1, val2)
#define CHECK_LT(val1, val2) CHECK_OP(Check_LT, <, val1, val2)
#define CHECK_GE(val1, val2) CHECK_OP(Check_GE, >=, val1, val2)
#define CHECK_GT(val1, val2) CHECK_OP(Check_GT, >, val1, val2)
#define CHECK_NOTNULL(val)                                 \
  ::tensorflow::internal::CheckNotNull(__FILE__, __LINE__, \
                                       "'" #val "' Must be non NULL", (val))

#ifndef NDEBUG
// DCHECK_EQ/NE/...
#define DCHECK(condition) CHECK(condition)
#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)

#else

#define DCHECK(condition) \
  while (false && (condition)) LOG(FATAL)

// NDEBUG is defined, so DCHECK_EQ(x, y) and so on do nothing.
// However, we still want the compiler to parse x and y, because
// we don't want to lose potentially useful errors and warnings.
// _DCHECK_NOP is a helper, and should not be used outside of this file.
#define _TF_DCHECK_NOP(x, y) \
  while (false && ((void)(x), (void)(y), 0)) LOG(FATAL)

#define DCHECK_EQ(x, y) _TF_DCHECK_NOP(x, y)
#define DCHECK_NE(x, y) _TF_DCHECK_NOP(x, y)
#define DCHECK_LE(x, y) _TF_DCHECK_NOP(x, y)
#define DCHECK_LT(x, y) _TF_DCHECK_NOP(x, y)
#define DCHECK_GE(x, y) _TF_DCHECK_NOP(x, y)
#define DCHECK_GT(x, y) _TF_DCHECK_NOP(x, y)

#endif

// These are for when you don't want a CHECK failure to print a verbose
// stack trace.  The implementation of CHECK* in this file already doesn't.
#define QCHECK(condition) CHECK(condition)
#define QCHECK_EQ(x, y) CHECK_EQ(x, y)
#define QCHECK_NE(x, y) CHECK_NE(x, y)
#define QCHECK_LE(x, y) CHECK_LE(x, y)
#define QCHECK_LT(x, y) CHECK_LT(x, y)
#define QCHECK_GE(x, y) CHECK_GE(x, y)
#define QCHECK_GT(x, y) CHECK_GT(x, y)

template <typename T>
T&& CheckNotNull(const char* file, int line, const char* exprtext, T&& t) {
  if (t == nullptr) {
    LogMessageFatal(file, line) << string(exprtext);
  }
  return std::forward<T>(t);
}

int64 MinLogLevelFromEnv();

int64 MaxVLogLevelFromEnv();

}  // namespace internal

// LogSink support adapted from //base/logging.h
//
// `LogSink` is an interface which can be extended to intercept and process
// all log messages. LogSink implementations must be thread-safe. A single
// instance will be called from whichever thread is performing a logging
// operation.
class TFLogEntry {
  static absl::LogSeverity AsAbslLogSeverity(int severity) {
    return static_cast<absl::LogSeverity>(severity);
  }

 public:
  explicit TFLogEntry(int severity, absl::string_view message)
      : severity_(AsAbslLogSeverity(severity)), message_(message) {}

  explicit TFLogEntry(int severity, absl::string_view fname, int line,
                      absl::string_view message)
      : severity_(AsAbslLogSeverity(severity)),
        fname_(fname),
        line_(line),
        message_(message) {}

  absl::LogSeverity log_severity() const { return severity_; }
  std::string FName() const { return fname_; }
  int Line() const { return line_; }
  std::string ToString() const { return message_; }
  absl::string_view text_message() const { return message_; }

 private:
  const absl::LogSeverity severity_;
  const std::string fname_;
  int line_ = -1;
  const std::string message_;
};

class TFLogSink {
 public:
  virtual ~TFLogSink() = default;

  // `Send` is called synchronously during the log statement.  The logging
  // module guarantees not to call `Send` concurrently on the same log sink.
  // Implementations should be careful not to call`LOG` or `CHECK` or take
  // any locks that might be held by the `LOG` caller, to avoid deadlock.
  //
  // `e` is guaranteed to remain valid until the subsequent call to
  // `WaitTillSent` completes, so implementations may store a pointer to or
  // copy of `e` (e.g. in a thread local variable) for use in `WaitTillSent`.
  virtual void Send(const TFLogEntry& entry) = 0;

  // `WaitTillSent` blocks the calling thread (the thread that generated a log
  // message) until the sink has finished processing the log message.
  // `WaitTillSent` is called once per log message, following the call to
  // `Send`.  This may be useful when log messages are buffered or processed
  // asynchronously by an expensive log sink.
  // The default implementation returns immediately.  Like `Send`,
  // implementations should be careful not to call `LOG` or `CHECK or take any
  // locks that might be held by the `LOG` caller, to avoid deadlock.
  virtual void WaitTillSent() {}
};

// This is the default log sink. This log sink is used if there are no other
// log sinks registered. To disable the default log sink, set the
// "no_default_logger" Bazel config setting to true or define a
// NO_DEFAULT_LOGGER preprocessor symbol. This log sink will always log to
// stderr.
class TFDefaultLogSink : public TFLogSink {
 public:
  void Send(const TFLogEntry& entry) override;
};

// Add or remove a `LogSink` as a consumer of logging data.  Thread-safe.
void TFAddLogSink(TFLogSink* sink);
void TFRemoveLogSink(TFLogSink* sink);

// Get all the log sinks.  Thread-safe.
std::vector<TFLogSink*> TFGetLogSinks();

}  // namespace tensorflow

#endif  // TENSORFLOW_CORE_PLATFORM_DEFAULT_LOGGING_H_


text:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Copyright (c) 2014-2021 The DÃSH Core Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

/**
 * Server/client environment: argument handling, config file parsing,
 * thread wrappers, startup time
 */
#ifndef BITCOIN_UTIL_H
#define BITCOIN_UTIL_H

#if defined(HAVE_CONFIG_H)
#include <config/biblepay-config.h>
#endif

#include <attributes.h>
#include <compat.h>
#include <fs.h>
#include <logging.h>
#include <sync.h>
#include <tinyformat.h>
#include <utiltime.h>
#include <utilmemory.h>
#include <amount.h>

#include <atomic>
#include <exception>
#include <map>
#include <set>
#include <stdint.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <boost/signals2/signal.hpp>
#include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted

// Debugging macros

// Uncomment the following line to enable debugging messages
// or enable on a per file basis prior to inclusion of util.h
//#define ENABLE_BIBLEPAY_DEBUG
#ifdef ENABLE_BIBLEPAY_DEBUG
#define DBG( x ) x
#else
#define DBG( x )
#endif

//BiblePay only features

extern bool fMasternodeMode;
extern bool fDisableGovernance;
extern int nWalletBackups;

// Application startup time (used for uptime calculation)
int64_t GetStartupTime();

/** Signals for translation. */
class CTranslationInterface
{
public:
    /** Translate a message to the native language of the user. */
    boost::signals2::signal<std::string (const char* psz)> Translate;
};

extern CTranslationInterface translationInterface;

extern const char * const BITCOIN_CONF_FILENAME;
extern const char * const BITCOIN_PID_FILENAME;

/**
 * Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
 * If no translation slot is registered, nothing is returned, and simply return the input.
 */
inline std::string _(const char* psz)
{
    boost::optional<std::string> rv = translationInterface.Translate(psz);
    return rv ? (*rv) : psz;
}

void SetupEnvironment();
bool SetupNetworking();

template<typename... Args>
bool error(const char* fmt, const Args&... args)
{
    LogPrintStr("ERROR: " + SafeStringFormat(fmt, args...) + "\n");
    return false;
}

void PrintExceptionContinue(const std::exception_ptr pex, const char* pszExceptionOrigin);
bool FileCommit(FILE *file);
bool TruncateFile(FILE *file, unsigned int length);
int RaiseFileDescriptorLimit(int nMinFD);
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
bool RenameOver(fs::path src, fs::path dest);
bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false);
bool DirIsWritable(const fs::path& directory);

/** Release all directory locks. This is used for unit testing only, at runtime
 * the global destructor will take care of the locks.
 */
void ReleaseDirectoryLocks();

bool TryCreateDirectories(const fs::path& p);
fs::path GetDefaultDataDir();
const fs::path &GetBlocksDir(bool fNetSpecific = true);
const fs::path &GetDataDir(bool fNetSpecific = true);
fs::path GetBackupsDir();
void ClearDatadirCache();
fs::path GetConfigFile(const std::string& confPath);
#ifndef WIN32
fs::path GetPidFile();
void CreatePidFile(const fs::path &path, pid_t pid);
#endif
#ifdef WIN32
fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
#endif
void runCommand(const std::string& strCommand);

/**
 * Most paths passed as configuration arguments are treated as relative to
 * the datadir if they are not absolute.
 *
 * @param path The path to be conditionally prefixed with datadir.
 * @param net_specific Forwarded to GetDataDir().
 * @return The normalized path.
 */
fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific = true);

inline bool IsSwitchChar(char c)
{
#ifdef WIN32
    return c == '-' || c == '/';
#else
    return c == '-';
#endif
}

enum class OptionsCategory
{
    OPTIONS,
    CONNECTION,
    INDEXING,
    MASTERNODE,
    STATSD,
    WALLET,
    WALLET_FEE,
    WALLET_HD,
    WALLET_KEEPASS,
    WALLET_COINJOIN,
    WALLET_DEBUG_TEST,
    ZMQ,
    DEBUG_TEST,
    CHAINPARAMS,
    NODE_RELAY,
    BLOCK_CREATION,
    RPC,
    GUI,
    COMMANDS,
    REGISTER_COMMANDS
};

class ArgsManager
{
protected:
    friend class ArgsManagerHelper;

    mutable CCriticalSection cs_args;
    std::map<std::string, std::vector<std::string>> m_override_args;
    std::map<std::string, std::vector<std::string>> m_config_args;
    std::string m_network;
    std::set<std::string> m_network_only_args;
    std::map<std::pair<OptionsCategory, std::string>, std::pair<std::string, bool>> m_available_args;

    void ReadConfigStream(std::istream& stream);

public:
    ArgsManager();

    /**
     * Select the network in use
     */
    void SelectConfigNetwork(const std::string& network);

    void ParseParameters(int argc, const char*const argv[]);
    void ReadConfigFile(const std::string& confPath);

    /**
     * Log warnings for options in m_section_only_args when
     * they are specified in the default section but not overridden
     * on the command line or in a network-specific section in the
     * config file.
     */
    void WarnForSectionOnlyArgs();

    /**
     * Return a vector of strings of the given argument
     *
     * @param strArg Argument to get (e.g. "-foo")
     * @return command-line arguments
     */
    std::vector<std::string> GetArgs(const std::string& strArg) const;

    /**
     * Return true if the given argument has been manually set
     *
     * @param strArg Argument to get (e.g. "-foo")
     * @return true if the argument has been set
     */
    bool IsArgSet(const std::string& strArg) const;

    /**
     * Return true if the argument was originally passed as a negated option,
     * i.e. -nofoo.
     *
     * @param strArg Argument to get (e.g. "-foo")
     * @return true if the argument was passed negated
     */
    bool IsArgNegated(const std::string& strArg) const;

    /**
     * Return string argument or default value
     *
     * @param strArg Argument to get (e.g. "-foo")
     * @param strDefault (e.g. "1")
     * @return command-line argument or default value
     */
    std::string GetArg(const std::string& strArg, const std::string& strDefault) const;

    /**
     * Return integer argument or default value
     *
     * @param strArg Argument to get (e.g. "-foo")
     * @param nDefault (e.g. 1)
     * @return command-line argument (0 if invalid number) or default value
     */
    int64_t GetArg(const std::string& strArg, int64_t nDefault) const;

    /**
     * Return boolean argument or default value
     *
     * @param strArg Argument to get (e.g. "-foo")
     * @param fDefault (true or false)
     * @return command-line argument or default value
     */
    bool GetBoolArg(const std::string& strArg, bool fDefault) const;

    /**
     * Set an argument if it doesn't already have a value
     *
     * @param strArg Argument to set (e.g. "-foo")
     * @param strValue Value (e.g. "1")
     * @return true if argument gets set, false if it already had a value
     */
    bool SoftSetArg(const std::string& strArg, const std::string& strValue);

    /**
     * Set a boolean argument if it doesn't already have a value
     *
     * @param strArg Argument to set (e.g. "-foo")
     * @param fValue Value (e.g. false)
     * @return true if argument gets set, false if it already had a value
     */
    bool SoftSetBoolArg(const std::string& strArg, bool fValue);

    // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
    // been set. Also called directly in testing.
    void ForceSetArg(const std::string& strArg, const std::string& strValue);
    void ForceRemoveArg(const std::string& strArg);

    /**
     * Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
     * @return CBaseChainParams::MAIN by default; raises runtime error if an invalid combination is given.
     */
    std::string GetChainName() const;

    /**
     * Looks for -devnet and returns either "devnet-<name>" or simply "devnet" if no name was specified.
     * This function should never be called for non-devnets.
     * @return either "devnet-<name>" or "devnet"; raises runtime error if no -devent was specified.
     */
    std::string GetDevNetName() const;

    /**
     * Add argument
     */
    void AddArg(const std::string& name, const std::string& help, const bool debug_only, const OptionsCategory& cat);

    /**
     * Get the help string
     */
    std::string GetHelpMessage();
};

extern ArgsManager gArgs;

/**
 * Format a string to be used as group of options in help messages
 *
 * @param message Group name (e.g. "RPC server options:")
 * @return the formatted string
 */
std::string HelpMessageGroup(const std::string& message);

/**
 * Format a string to be used as option description in help messages
 *
 * @param option Option message (e.g. "-rpcuser=<user>")
 * @param message Option description (e.g. "Username for JSON-RPC connections")
 * @return the formatted string
 */
std::string HelpMessageOpt(const std::string& option, const std::string& message);

/**
 * Return the number of cores available on the current system.
 * @note This does count virtual cores, such as those provided by HyperThreading.
 */
int GetNumCores();

void RenameThread(const char* name);
std::string GetThreadName();

namespace ctpl {
    class thread_pool;
}
void RenameThreadPool(ctpl::thread_pool& tp, const char* baseName);

/**
 * .. and a wrapper that just calls func once
 */
template <typename Callable> void TraceThread(const std::string name,  Callable func)
{
    std::string s = "biblepay-" + name;
    RenameThread(s.c_str());
    try
    {
        LogPrintf("%s thread start\n", name);
        func();
        LogPrintf("%s thread exit\n", name);
    }
    catch (const boost::thread_interrupted&)
    {
        LogPrintf("%s thread interrupt\n", name);
        throw;
    }
    catch (...) {
        PrintExceptionContinue(std::current_exception(), name.c_str());
        throw;
    }
}

std::string CopyrightHolders(const std::string& strPrefix, unsigned int nStartYear, unsigned int nEndYear);

/**
 * On platforms that support it, tell the kernel the calling thread is
 * CPU-intensive and non-interactive. See SCHED_BATCH in sched(7) for details.
 *
 * @return The return value of sched_setschedule(), or 1 on systems without
 * sched_setchedule().
 */
int ScheduleBatchPriority(void);

#endif // BITCOIN_UTIL_H