From fad87daa776766e66a8a56f17ab8f50fdf13a797 Mon Sep 17 00:00:00 2001 From: Pushkar N Kulkarni Date: Wed, 19 Dec 2018 15:30:27 +0530 Subject: [PATCH] Initialize ELG with the number of affinitized cores (#120) --- Package.swift | 5 ++- Sources/CLinuxHelpers/ProcessorAffinity.c | 40 +++++++++++++++++++ .../CLinuxHelpers/include/ProcessorAffinity.h | 19 +++++++++ Sources/KituraNet/HTTP/HTTPServer.swift | 12 +++++- 4 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 Sources/CLinuxHelpers/ProcessorAffinity.c create mode 100644 Sources/CLinuxHelpers/include/ProcessorAffinity.h diff --git a/Package.swift b/Package.swift index e4159ca2..ed9ad1e7 100644 --- a/Package.swift +++ b/Package.swift @@ -36,9 +36,12 @@ let package = Package( targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target( + name: "CLinuxHelpers", + dependencies: []), .target( name: "KituraNet", - dependencies: ["NIO", "NIOFoundationCompat", "NIOHTTP1", "NIOOpenSSL", "SSLService", "LoggerAPI", "NIOWebSocket"]), + dependencies: ["NIO", "NIOFoundationCompat", "NIOHTTP1", "NIOOpenSSL", "SSLService", "LoggerAPI", "NIOWebSocket", "CLinuxHelpers"]), .testTarget( name: "KituraNetTests", dependencies: ["KituraNet"]), diff --git a/Sources/CLinuxHelpers/ProcessorAffinity.c b/Sources/CLinuxHelpers/ProcessorAffinity.c new file mode 100644 index 00000000..259b2f5b --- /dev/null +++ b/Sources/CLinuxHelpers/ProcessorAffinity.c @@ -0,0 +1,40 @@ +/* + * Copyright IBM Corporation 2018 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef __linux__ + +#define _GNU_SOURCE +#include +#include + +// Reference: https://stackoverflow.com/questions/10490756/how-to-use-sched-getaffinity-and-sched-setaffinity-in-linux-from-c +int linux_sched_getaffinity() { + cpu_set_t mask; + long nproc, i, count = 0; + + if (sched_getaffinity(0, sizeof(cpu_set_t), &mask) == -1) { + return -1; + } else { + nproc = sysconf(_SC_NPROCESSORS_ONLN); + for (i = 0; i < nproc; i++) { + if(CPU_ISSET(i, &mask)) + count += 1; + } + return count; + } +} + +#endif diff --git a/Sources/CLinuxHelpers/include/ProcessorAffinity.h b/Sources/CLinuxHelpers/include/ProcessorAffinity.h new file mode 100644 index 00000000..0a180b99 --- /dev/null +++ b/Sources/CLinuxHelpers/include/ProcessorAffinity.h @@ -0,0 +1,19 @@ +/* + * Copyright IBM Corporation 2018 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if __linux__ +int linux_sched_getaffinity(); +#endif diff --git a/Sources/KituraNet/HTTP/HTTPServer.swift b/Sources/KituraNet/HTTP/HTTPServer.swift index 4af87d51..a65c5584 100644 --- a/Sources/KituraNet/HTTP/HTTPServer.swift +++ b/Sources/KituraNet/HTTP/HTTPServer.swift @@ -21,6 +21,7 @@ import NIOOpenSSL import SSLService import LoggerAPI import NIOWebSocket +import CLinuxHelpers /// An HTTP server that listens for connections on a socket. public class HTTPServer : Server { @@ -66,11 +67,18 @@ public class HTTPServer : Server { private let maxPendingConnections = 100 /// The event loop group on which the HTTP handler runs - let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount) + private let eventLoopGroup: MultiThreadedEventLoopGroup private var ctx: ChannelHandlerContext? - public init() { } + public init() { +#if os(Linux) + let numberOfCores = Int(linux_sched_getaffinity()) + self.eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: numberOfCores > 0 ? numberOfCores : System.coreCount) +#else + self.eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount) +#endif + } /// SSL cert configs for handling client requests public var sslConfig: SSLService.Configuration? {