Skip to content

Commit

Permalink
Merge pull request #3061 from armanbilge/topic/native-no-more-zones
Browse files Browse the repository at this point in the history
Native "`Array`-pointer" optimizations
  • Loading branch information
mpilquist authored Nov 20, 2022
2 parents 3878dca + 8f0a44b commit d430755
Show file tree
Hide file tree
Showing 13 changed files with 312 additions and 139 deletions.
3 changes: 3 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ ThisBuild / mimaBinaryIssueFilters ++= Seq(
),
ProblemFilters.exclude[DirectMissingMethodProblem]( // something funky in Scala 3.2.0 ...
"fs2.io.net.SocketGroupCompanionPlatform#AsyncSocketGroup.this"
),
ProblemFilters.exclude[DirectMissingMethodProblem](
"fs2.io.net.tls.S2nConnection#RecvCallbackContext.readBuffer"
)
)

Expand Down
14 changes: 13 additions & 1 deletion core/native/src/main/scala/fs2/ChunkRuntimePlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@

package fs2

import scala.scalanative.libc.string._
import scala.scalanative.unsafe._
import scala.scalanative.unsigned._

private[fs2] trait ChunkRuntimePlatform[+O]

private[fs2] trait ChunkCompanionRuntimePlatform
private[fs2] trait ChunkCompanionRuntimePlatform {

def fromBytePtr(ptr: Ptr[Byte], length: Int): Chunk[Byte] = {
val bytes = new Array[Byte](length)
memcpy(bytes.at(0), ptr, length.toULong)
Chunk.ArraySlice(bytes, 0, length)
}

}
120 changes: 120 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
inputs = {
typelevel-nix.url = "github:typelevel/typelevel-nix";
nixpkgs.follows = "typelevel-nix/nixpkgs";
flake-utils.follows = "typelevel-nix/flake-utils";
};

outputs = { self, nixpkgs, flake-utils, typelevel-nix }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ typelevel-nix.overlay ];
};
in
{
devShell = pkgs.devshell.mkShell {
imports = [ typelevel-nix.typelevelShell ];
name = "fs2-shell";
typelevelShell = {
jdk.package = pkgs.jdk17;
nodejs.enable = true;
native.enable = true;
native.libraries = [ pkgs.zlib pkgs.s2n-tls pkgs.openssl ];
};
};
}
);
}
64 changes: 64 additions & 0 deletions io/native/src/main/scala/fs2/io/internal/ResizableBuffer.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2013 Functional Streams for Scala
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package fs2.io.internal

import cats.effect.kernel.Resource
import cats.effect.kernel.Sync
import cats.syntax.all._

import scala.scalanative.libc.errno._
import scala.scalanative.libc.stdlib._
import scala.scalanative.unsafe._
import scala.scalanative.unsigned._

private[io] final class ResizableBuffer[F[_]] private (
private var ptr: Ptr[Byte],
private[this] var size: Int
)(implicit F: Sync[F]) {

def get(size: Int): F[Ptr[Byte]] = F.delay {
if (size <= this.size)
F.pure(ptr)
else {
ptr = realloc(ptr, size.toUInt)
this.size = size
if (ptr == null)
F.raiseError[Ptr[Byte]](new RuntimeException(s"realloc: ${errno}"))
else F.pure(ptr)
}
}.flatten

}

private[io] object ResizableBuffer {

def apply[F[_]](size: Int)(implicit F: Sync[F]): Resource[F, ResizableBuffer[F]] =
Resource.make {
F.delay {
val ptr = malloc(size.toUInt)
if (ptr == null)
throw new RuntimeException(s"malloc: ${errno}")
else new ResizableBuffer(ptr, size)
}
}(buf => F.delay(free(buf.ptr)))

}
18 changes: 8 additions & 10 deletions io/native/src/main/scala/fs2/io/net/tls/CertChainAndKey.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,14 @@ final class CertChainAndKey private (chainPem: ByteVector, privateKeyPem: ByteVe
)
.evalTap { certChainAndKey =>
F.delay {
Zone { implicit z =>
guard_ {
s2n_cert_chain_and_key_load_pem_bytes(
certChainAndKey,
chainPem.toPtr,
chainPem.length.toUInt,
privateKeyPem.toPtr,
privateKeyPem.length.toUInt
)
}
guard_ {
s2n_cert_chain_and_key_load_pem_bytes(
certChainAndKey,
chainPem.toArray.at(0),
chainPem.length.toUInt,
privateKeyPem.toArray.at(0),
privateKeyPem.length.toUInt
)
}
}
}
Expand Down
12 changes: 3 additions & 9 deletions io/native/src/main/scala/fs2/io/net/tls/S2nConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ object S2nConfig {

_ <- pems.traverse_ { pem =>
F.delay {
Zone { implicit z =>
guard_(s2n_config_add_pem_to_trust_store(cfg, toCString(pem)))
}
guard_(s2n_config_add_pem_to_trust_store(cfg, toCStringArray(pem).at(0)))
}
}.toResource

Expand All @@ -123,17 +121,13 @@ object S2nConfig {

_ <- dhParams.traverse_ { pem =>
F.delay {
Zone { implicit z =>
guard_(s2n_config_add_dhparams(cfg, toCString(pem)))
}
guard_(s2n_config_add_dhparams(cfg, toCStringArray(pem).at(0)))
}
}.toResource

_ <- cipherPreferences.traverse_ { version =>
F.delay {
Zone { implicit z =>
guard_(s2n_config_set_cipher_preferences(cfg, toCString(version)))
}
guard_(s2n_config_set_cipher_preferences(cfg, toCStringArray(version).at(0)))
}
}.toResource
} yield new S2nConfig(cfg)
Expand Down
Loading

0 comments on commit d430755

Please sign in to comment.