Skip to content

Commit

Permalink
Switch to C test
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed Nov 4, 2022
1 parent 329f53f commit 7967b0f
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 33 deletions.
8 changes: 8 additions & 0 deletions test/gcext/Foreign/Manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file is machine-generated - editing it directly is not advised

julia_version = "1.9.0-DEV"
manifest_format = "2.0"
project_hash = "7b70172a2edbdc772ed789e79d4411d7528eae86"

[[deps.Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
6 changes: 6 additions & 0 deletions test/gcext/Foreign/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name = "Foreign"
uuid = "de1f6f7a-d7b3-400f-91c2-33f248ee89c4"
version = "0.1.0"

[deps]
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
34 changes: 34 additions & 0 deletions test/gcext/Foreign/deps/foreignlib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// This file is a part of Julia. License is MIT: https://julialang.org/license

#include "julia.h"
#include "julia_gcext.h"

int nmarks = 0;
int nsweeps = 0;

uintptr_t mark(jl_ptls_t ptls, jl_value_t *p)
{
nmarks += 1;
return 0;
}

void sweep(jl_value_t *p)
{
nsweeps++;
}

void init_dt_gc(jl_datatype_t *dt)
{
jl_reinit_foreign_type(dt, mark, sweep);
nmarks = nsweeps = 0;
}

int nmark_counter()
{
return nmarks;
}

int nsweep_counter()
{
return nsweeps;
}
21 changes: 21 additions & 0 deletions test/gcext/Foreign/src/Foreign.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

module Foreign

using Libdl

const foreignlib = joinpath(dirname(joinpath(@__DIR__)), "deps", "foreignlib.so")

const FObj = ccall(:jl_new_foreign_type, Any, (Symbol, Module, Any, Any, Any, Cint, Cint),
:FObj, Foreign, Any, C_NULL, C_NULL, 0, 0)

FObj() = ccall(:jl_new_struct_uninit, Any, (Any,), FObj)

get_nmark() = ccall((:nmark_counter, foreignlib), Cint, ())
get_nsweep() = ccall((:nsweep_counter, foreignlib), Cint, ())

function __init__()
ccall((:init_dt_gc, foreignlib), Cvoid, (Any,), FObj)
end

end # module Foreign
15 changes: 12 additions & 3 deletions test/gcext/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,42 @@ SRCDIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
# get the executable suffix, if any
EXE := $(suffix $(abspath $(JULIA)))

DYLIB := .so

# get compiler and linker flags. (see: `contrib/julia-config.jl`)
JULIA_CONFIG := $(JULIA) -e 'include(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "julia-config.jl"))' --
CPPFLAGS_ADD :=
CFLAGS_ADD = $(shell $(JULIA_CONFIG) --cflags)
LDFLAGS_ADD = -lm $(shell $(JULIA_CONFIG) --ldflags --ldlibs)
DYLIBFLAGS := --shared -fPIC

DEBUGFLAGS += -g

#=============================================================================

release: $(BIN)/gcext$(EXE)
debug: $(BIN)/gcext-debug$(EXE)
release: $(BIN)/gcext$(EXE) $(BIN)/Foreign/deps/foreignlib$(DYLIB)
debug: $(BIN)/gcext-debug$(EXE) $(BIN)/Foreign/deps/foreignlib-debug$(DYLIB)

$(BIN)/gcext$(EXE): $(SRCDIR)/gcext.c
$(CC) $^ -o $@ $(CPPFLAGS_ADD) $(CPPFLAGS) $(CFLAGS_ADD) $(CFLAGS) $(LDFLAGS_ADD) $(LDFLAGS)

$(BIN)/gcext-debug$(EXE): $(SRCDIR)/gcext.c
$(CC) $^ -o $@ $(CPPFLAGS_ADD) $(CPPFLAGS) $(CFLAGS_ADD) $(CFLAGS) $(LDFLAGS_ADD) $(LDFLAGS) $(DEBUGFLAGS)

$(BIN)/Foreign/deps/foreignlib$(DYLIB): $(SRCDIR)/Foreign/deps/foreignlib.c
$(CC) $^ -o $@ $(DYLIBFLAGS) $(CPPFLAGS_ADD) $(CPPFLAGS) $(CFLAGS_ADD) $(CFLAGS) $(LDFLAGS_ADD) $(LDFLAGS)

$(BIN)/Foreign/deps/foreignlib-debug$(DYLIB): $(SRCDIR)/Foreign/deps/foreignlib.c
$(CC) $^ -o $@ $(DYLIBFLAGS) $(CPPFLAGS_ADD) $(CPPFLAGS) $(CFLAGS_ADD) $(CFLAGS) $(LDFLAGS_ADD) $(LDFLAGS) $(DEBUGFLAGS)

ifneq ($(abspath $(BIN)),$(abspath $(SRCDIR)))
# for demonstration purposes, our demo code is also installed
# in $BIN, although this would likely not be typical
$(BIN)/LocalModule.jl: $(SRCDIR)/LocalModule.jl
cp $< $@
endif

check: $(BIN)/gcext$(EXE) $(BIN)/LocalTest.jl
check: $(BIN)/gcext$(EXE) $(BIN)/LocalTest.jl $(BIN)/Foreign/deps/foreignlib$(DYLIB)
$(JULIA) --depwarn=error $(SRCDIR)/gcext-test.jl $<
@echo SUCCESS

Expand Down
19 changes: 19 additions & 0 deletions test/gcext/gcext-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# tests the output of the embedding example is correct
using Test
using Pkg

if Sys.iswindows()
# libjulia needs to be in the same directory as the embedding executable or in path
Expand Down Expand Up @@ -40,3 +41,21 @@ end
@test checknum(lines[6], r"([0-9]+) corrupted auxiliary roots",
n -> n == 0)
end

@testset "Package with foreign type" begin
load_path = joinpath(@__DIR__, "Foreign")
push!(LOAD_PATH, load_path)
try
(@eval (using Foreign))
@test Base.invokelatest(Foreign.get_nmark) == 0
@test Base.invokelatest(Foreign.get_nsweep) == 0
x = [Base.invokelatest(Foreign.FObj) for _ in 1:10]
GC.gc(true)
x = nothing
GC.gc(true)
@test Base.invokelatest(Foreign.get_nmark) > 0
@test Base.invokelatest(Foreign.get_nsweep) > 0
finally
filter!(()(load_path), LOAD_PATH)
end
end
30 changes: 0 additions & 30 deletions test/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1554,35 +1554,5 @@ precompile_test_harness("issue #46296") do load_path
(@eval (using CodeInstancePrecompile))
end

precompile_test_harness("foreign types") do path
write(joinpath(load_path, "Foreign.jl"),
"""
module Foreign
export FObj
const FObj = ccall(:jl_new_foreign_type, Any, (Symbol, Module, Any, Any, Any, Cint, Cint),
:FObj, Foreign, Any, C_NULL, C_NULL, 0, 0)
FObj() = ccall(:jl_new_struct_uninit, Any, (Any,), FObj)
const nmark = Ref(0)
const nsweep = Ref(0)
inc_nmark() = (nmark[] += 1; return nothing)
inc_nsweep() = (nsweep[] += 1; return nothing)
function __init__()
ccall(:jl_reinit_foreign_type, Cint, (Any, Any, Any),
FObj, @cfunction(inc_nmark, Cvoid, ()), @cfunction(inc_nsweep, Cvoid, ()))
end
end # module Foreign
""")
(@eval (using Foreign))
x = [FObj() for _ in 1:1000]
GC.gc(true)
@test_broken Foreign.nmark[] > 0 || Foreign.nsweep[] > 0
end

empty!(Base.DEPOT_PATH)
append!(Base.DEPOT_PATH, original_depot_path)

0 comments on commit 7967b0f

Please sign in to comment.