185
204
heap_frag_do(((N*5) div 4) + 1, Max).
206
types(doc) -> ["Type tests"];
208
types(Config) when is_list(Config) ->
210
ensure_lib_loaded(Config),
211
?line ok = type_test(),
212
lists:foreach(fun(Tpl) ->
213
Lst = erlang:tuple_to_list(Tpl),
214
Lst = tuple_2_list(Tpl)
216
[{},{ok},{{}},{[],{}},{1,2,3,4,5}]),
217
Stuff = [[],{},0,0.0,(1 bsl 100),(fun()-> ok end),make_ref(),self()],
218
[eq_cmp(A,clone(B)) || A<-Stuff, B<-Stuff],
219
?line verify_tmpmem(TmpMem),
223
binary_to_term(term_to_binary(X)).
227
eq_cmp_do([A,B],[A,B]),
228
eq_cmp_do({A,B},{A,B}).
231
%%?t:format("compare ~p and ~p\n",[A,B]),
233
?line Eq = is_identical(A,B),
239
?line Cmp = case compare(A,B) of
240
C when is_integer(C), C < 0 -> -1;
242
C when is_integer(C) -> 1
247
many_args(doc) -> ["Test NIF with many arguments"];
248
many_args(suite) -> [];
249
many_args(Config) when is_list(Config) ->
251
?line ensure_lib_loaded(Config ,1),
252
?line ok = apply(?MODULE,many_args_100,lists:seq(1,100)),
253
?line ok = many_args_100(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100),
254
?line verify_tmpmem(TmpMem),
257
binaries(doc) -> ["Test NIF binary handling."];
258
binaries(suite) -> [];
259
binaries(Config) when is_list(Config) ->
261
?line ensure_lib_loaded(Config, 1),
262
?line RefcBin = list_to_binary(lists:seq(1,255)),
263
?line RefcBin = clone_bin(RefcBin),
264
?line HeapBin = list_to_binary(lists:seq(1,20)),
265
?line HeapBin = clone_bin(HeapBin),
266
?line <<_:8,Sub1:6/binary,_/binary>> = RefcBin,
267
?line <<_:8,Sub2:6/binary,_/binary>> = HeapBin,
269
?line Sub1 = clone_bin(Sub1),
270
?line Sub2 = clone_bin(Sub2),
271
?line <<_:9,Sub3:6/binary,_/bitstring>> = RefcBin,
272
?line <<_:9,Sub4:6/binary,_/bitstring>> = HeapBin,
274
?line Sub3 = clone_bin(Sub3),
275
?line Sub4 = clone_bin(Sub4),
276
%% When NIFs get bitstring support
277
%%?line <<_:8,Sub5:27/bitstring,_/bitstring>> = RefcBin,
278
%%?line <<_:8,Sub6:27/bitstring,_/bitstring>> = HeapBin,
280
%%?line Sub5 = clone_bin(Sub5),
281
%%?line Sub6 = clone_bin(Sub6),
282
%%?line <<_:9,Sub7:27/bitstring,_/bitstring>> = RefcBin,
283
%%?line <<_:9,Sub8:27/bitstring,_/bitstring>> = HeapBin,
285
%%?line Sub7 = clone_bin(Sub7),
286
%%?line Sub8 = clone_bin(Sub8),
287
%%?line <<>> = clone_bin(<<>>),
289
<<_:8,SubBinA:200/binary,_/binary>> = RefcBin,
290
<<_:9,SubBinB:200/binary,_/bitstring>> = RefcBin,
291
<<_:8,SubBinC:17/binary,_/binary>> = HeapBin,
292
<<_:9,SubBinD:17/binary,_/bitstring>> = HeapBin,
293
test_make_sub_bin(RefcBin),
294
test_make_sub_bin(HeapBin),
295
test_make_sub_bin(SubBinA),
296
test_make_sub_bin(SubBinB),
297
test_make_sub_bin(SubBinC),
298
test_make_sub_bin(SubBinD),
300
?line verify_tmpmem(TmpMem),
303
test_make_sub_bin(Bin) ->
304
Size = byte_size(Bin),
307
?line Bin = make_sub_bin(Bin, 0, Size),
308
<<_:10/binary,Sub0:Rest10/binary>> = Bin,
309
?line Sub0 = make_sub_bin(Bin, 10, Rest10),
310
<<Sub1:10/binary,_/binary>> = Bin,
311
?line Sub1 = make_sub_bin(Bin, 0, 10),
312
<<_:7/binary,Sub2:10/binary,_/binary>> = Bin,
313
?line Sub2 = make_sub_bin(Bin, 7, 10),
314
?line <<>> = make_sub_bin(Bin, 0, 0),
315
?line <<>> = make_sub_bin(Bin, 10, 0),
316
?line <<>> = make_sub_bin(Bin, Rest1, 0),
317
?line <<>> = make_sub_bin(Bin, Size, 0),
320
get_string(doc) -> ["Test enif_get_string"];
321
get_string(suite) -> [];
322
get_string(Config) when is_list(Config) ->
323
?line ensure_lib_loaded(Config, 1),
324
?line {7, <<"hejsan",0,_:3/binary>>} = string_to_bin("hejsan",10),
325
?line {7, <<"hejsan",0,_>>} = string_to_bin("hejsan",8),
326
?line {7, <<"hejsan",0>>} = string_to_bin("hejsan",7),
327
?line {-6, <<"hejsa",0>>} = string_to_bin("hejsan",6),
328
?line {-5, <<"hejs",0>>} = string_to_bin("hejsan",5),
329
?line {-1, <<0>>} = string_to_bin("hejsan",1),
330
?line {0, <<>>} = string_to_bin("hejsan",0),
331
?line {1, <<0>>} = string_to_bin("",1),
332
?line {0, <<>>} = string_to_bin("",0),
335
get_atom(doc) -> ["Test enif_get_atom"];
336
get_atom(suite) -> [];
337
get_atom(Config) when is_list(Config) ->
338
?line ensure_lib_loaded(Config, 1),
339
?line {7, <<"hejsan",0,_:3/binary>>} = atom_to_bin(hejsan,10),
340
?line {7, <<"hejsan",0,_>>} = atom_to_bin(hejsan,8),
341
?line {7, <<"hejsan",0>>} = atom_to_bin(hejsan,7),
342
?line {0, <<_:6/binary>>} = atom_to_bin(hejsan,6),
343
?line {0, <<>>} = atom_to_bin(hejsan,0),
344
?line {1, <<0>>} = atom_to_bin('',1),
345
?line {0, <<>>} = atom_to_bin('',0),
348
api_macros(doc) -> ["Test macros enif_make_list<N> and enif_make_tuple<N>"];
349
api_macros(suite) -> [];
350
api_macros(Config) when is_list(Config) ->
351
?line ensure_lib_loaded(Config, 1),
352
Expected = {[lists:seq(1,N) || N <- lists:seq(1,9)],
353
[list_to_tuple(lists:seq(1,N)) || N <- lists:seq(1,9)]
355
?line Expected = macros(list_to_tuple(lists:seq(1,9))),
358
from_array(doc) -> ["enif_make_[tuple|list]_from_array"];
359
from_array(suite) -> [];
360
from_array(Config) when is_list(Config) ->
361
?line ensure_lib_loaded(Config, 1),
362
lists:foreach(fun(Tpl) ->
363
Lst = tuple_to_list(Tpl),
364
?line {Lst,Tpl} = tuple_2_list_and_tuple(Tpl)
366
[{}, {1,2,3}, {[4,5],[],{},{6,7}}, {{}}, {[]}]),
369
iolist_as_binary(doc) -> ["enif_inspect_iolist_as_binary"];
370
iolist_as_binary(suite) -> [];
371
iolist_as_binary(Config) when is_list(Config) ->
372
?line ensure_lib_loaded(Config, 1),
374
List = [<<"hejsan">>, <<>>, [], [17], [<<>>],
376
[1, 2, 3, <<"abc">>, [<<"def">>,4], 5, <<"ghi">>],
377
[1, 2, 3, <<"abc">>, [<<"def">>,4], 5 | <<"ghi">>]],
379
lists:foreach(fun(IoL) ->
380
B1 = erlang:iolist_to_binary(IoL),
381
?line B2 = iolist_2_bin(IoL),
385
?line verify_tmpmem(TmpMem),
388
resource(doc) -> ["Test memory managed objects, aka 'resources'"];
389
resource(suite) -> [];
390
resource(Config) when is_list(Config) ->
391
?line ensure_lib_loaded(Config, 1),
392
?line Type = get_resource_type(0),
399
resource_hugo(Type) ->
400
DtorCall = resource_hugo_do(Type),
401
erlang:garbage_collect(),
402
?line DtorCall = last_resource_dtor_call(),
405
resource_hugo_do(Type) ->
406
HugoBin = <<"Hugo Hacker">>,
407
?line HugoPtr = alloc_resource(Type, HugoBin),
408
?line Hugo = make_resource(HugoPtr),
410
release_resource(HugoPtr),
411
erlang:garbage_collect(),
412
?line {HugoPtr,HugoBin} = get_resource(Type,Hugo),
413
Pid = spawn_link(fun() ->
414
receive {Pid, Type, Resource, Ptr, Bin} ->
415
Pid ! {self(), got_it},
416
receive {Pid, check_it} ->
417
?line {Ptr,Bin} = get_resource(Type,Resource),
422
Pid ! {self(), Type, Hugo, HugoPtr, HugoBin},
423
?line {Pid, got_it} = receive_any(),
424
erlang:garbage_collect(), % just to make our ProcBin move in memory
425
Pid ! {self(), check_it},
426
?line {Pid, ok} = receive_any(),
427
?line [] = last_resource_dtor_call(),
428
?line {HugoPtr,HugoBin} = get_resource(Type,Hugo),
429
{HugoPtr, HugoBin, 1}.
431
resource_otto(Type) ->
432
{OttoPtr, OttoBin} = resource_otto_do(Type),
433
erlang:garbage_collect(),
434
?line [] = last_resource_dtor_call(),
435
release_resource(OttoPtr),
436
?line {OttoPtr,OttoBin,1} = last_resource_dtor_call(),
439
resource_otto_do(Type) ->
440
OttoBin = <<"Otto Ordonnans">>,
441
?line OttoPtr = alloc_resource(Type, OttoBin),
442
?line Otto = make_resource(OttoPtr),
444
%% forget resource term but keep referenced by NIF
447
resource_new(Type) ->
448
?line {PtrB,BinB} = resource_new_do1(Type),
449
erlang:garbage_collect(),
450
?line {PtrB,BinB,1} = last_resource_dtor_call(),
453
resource_new_do1(Type) ->
454
?line {{PtrA,BinA}, {ResB,PtrB,BinB}} = resource_new_do2(Type),
455
erlang:garbage_collect(),
456
?line {PtrA,BinA,1} = last_resource_dtor_call(),
457
?line {PtrB,BinB} = get_resource(Type, ResB),
458
%% forget ResB and make it garbage
461
resource_new_do2(Type) ->
464
?line ResA = make_new_resource(Type, BinA),
465
?line ResB = make_new_resource(Type, BinB),
468
?line {PtrA,BinA} = get_resource(Type, ResA),
469
?line {PtrB,BinB} = get_resource(Type, ResB),
470
?line true = (PtrA =/= PtrB),
471
?line [] = last_resource_dtor_call(),
472
%% forget ResA and make it garbage
473
{{PtrA,BinA}, {ResB,PtrB,BinB}}.
475
resource_neg(TypeA) ->
476
TypeB = get_resource_type(1),
477
Aptr = alloc_resource(TypeA, <<"Arnold">>),
478
Bptr = alloc_resource(TypeB, <<"Bobo">>),
479
?line {'EXIT',{badarg,_}} = (catch get_resource(TypeA, Bptr)),
480
?line {'EXIT',{badarg,_}} = (catch get_resource(TypeB, Aptr)),
483
-define(RT_CREATE,1).
484
-define(RT_TAKEOVER,2).
486
resource_takeover(doc) -> ["Test resource takeover by module reload and upgrade"];
487
resource_takeover(suite) -> [];
488
resource_takeover(Config) when is_list(Config) ->
490
ensure_lib_loaded(Config),
492
?line Data = ?config(data_dir, Config),
493
?line File = filename:join(Data, "nif_mod"),
494
?line {ok,nif_mod,ModBin} = compile:file(File, [binary,return_errors]),
495
?line {module,nif_mod} = erlang:load_module(nif_mod,ModBin),
497
?line ok = nif_mod:load_nif_lib(Config, 1,
498
[{resource_type, 0, ?RT_CREATE, "resource_type_A",resource_dtor_A,
500
{resource_type, 1, ?RT_CREATE, "resource_type_null_A",null,
502
{resource_type, 2, ?RT_CREATE bor ?RT_TAKEOVER, "resource_type_A_null",resource_dtor_A,
504
{resource_type, 3, ?RT_CREATE, "resource_type_B_goneX",resource_dtor_B,
506
{resource_type, 4, ?RT_CREATE, "resource_type_null_goneX",null,
508
{resource_type, null, ?RT_TAKEOVER, "Pink unicorn", resource_dtor_A,
512
?line hold_nif_mod_priv_data(nif_mod:get_priv_data_ptr()),
513
?line [{load,1,1,101},{get_priv_data_ptr,1,2,102}] = nif_mod_call_history(),
515
?line {Holder, _MRef} = spawn_opt(fun resource_holder/0, [link, monitor]),
517
{A1,BinA1} = make_resource(0,Holder,"A1"),
518
{A2,BinA2} = make_resource(0,Holder,"A2"),
519
{A3,BinA3} = make_resource(0,Holder,"A3"),
521
{NA1,_BinNA1} = make_resource(1,Holder,"NA1"),
522
{NA2,BinNA2} = make_resource(1,Holder,"NA2"),
523
{NA3,_BinNA3} = make_resource(1,Holder,"NA3"),
525
{AN1,BinAN1} = make_resource(2,Holder,"AN1"),
526
{AN2,_BinAN2} = make_resource(2,Holder,"AN2"),
527
{AN3,BinAN3} = make_resource(2,Holder,"AN3"),
529
{BGX1,BinBGX1} = make_resource(3,Holder,"BGX1"),
530
{BGX2,BinBGX2} = make_resource(3,Holder,"BGX2"),
532
{NGX1,_BinNGX1} = make_resource(4,Holder,"NGX1"),
533
{NGX2,_BinNGX2} = make_resource(4,Holder,"NGX2"),
535
?line [] = nif_mod_call_history(),
537
?line ok = forget_resource(A1),
538
?line [{{resource_dtor_A_v1,BinA1},1,3,103}] = nif_mod_call_history(),
540
?line ok = forget_resource(NA1),
541
?line [] = nif_mod_call_history(), % no dtor
543
?line ok = forget_resource(AN1),
544
?CHECK([{{resource_dtor_A_v1,BinAN1},1,4,104}] , nif_mod_call_history()),
546
?line ok = forget_resource(BGX1),
547
?CHECK([{{resource_dtor_B_v1,BinBGX1},1,5,105}], nif_mod_call_history()),
549
?line ok = forget_resource(NGX1),
550
?CHECK([], nif_mod_call_history()), % no dtor
552
?line ok = nif_mod:load_nif_lib(Config, 2,
553
[{resource_type, 0, ?RT_TAKEOVER, "resource_type_A",resource_dtor_A,
555
{resource_type, 1, ?RT_TAKEOVER bor ?RT_CREATE, "resource_type_null_A",resource_dtor_A,
557
{resource_type, 2, ?RT_TAKEOVER, "resource_type_A_null",null,
559
{resource_type, null, ?RT_TAKEOVER, "Pink unicorn", resource_dtor_A,
561
{resource_type, null, ?RT_CREATE, "resource_type_B_goneX",resource_dtor_B,
563
{resource_type, null, ?RT_CREATE, "resource_type_null_goneX",null,
565
{resource_type, 3, ?RT_CREATE, "resource_type_B_goneY",resource_dtor_B,
567
{resource_type, 4, ?RT_CREATE, "resource_type_null_goneY",null,
570
?CHECK([{reload,2,1,201}], nif_mod_call_history()),
572
?line BinA2 = read_resource(0,A2),
573
?line ok = forget_resource(A2),
574
?CHECK([{{resource_dtor_A_v2,BinA2},2,2,202}], nif_mod_call_history()),
576
?line ok = forget_resource(NA2),
577
?CHECK([{{resource_dtor_A_v2,BinNA2},2,3,203}], nif_mod_call_history()),
579
?line ok = forget_resource(AN2),
580
?CHECK([], nif_mod_call_history()), % no dtor
582
?line ok = forget_resource(BGX2), % calling dtor in orphan library v1 still loaded
583
?CHECK([{{resource_dtor_B_v1,BinBGX2},1,6,106}], nif_mod_call_history()),
584
% How to test that lib v1 is closed here?
586
?line ok = forget_resource(NGX2),
587
?CHECK([], nif_mod_call_history()), % no dtor
589
{BGY1,BinBGY1} = make_resource(3,Holder,"BGY1"),
590
{NGY1,_BinNGY1} = make_resource(4,Holder,"NGY1"),
592
%% Module upgrade with same lib-version
593
?line {module,nif_mod} = erlang:load_module(nif_mod,ModBin),
594
?line undefined = nif_mod:lib_version(),
595
?line ok = nif_mod:load_nif_lib(Config, 2,
596
[{resource_type, 2, ?RT_TAKEOVER, "resource_type_A",resource_dtor_B,
598
{resource_type, 0, ?RT_TAKEOVER bor ?RT_CREATE, "resource_type_null_A",null,
600
{resource_type, 1, ?RT_TAKEOVER, "resource_type_A_null",resource_dtor_A,
602
{resource_type, null, ?RT_TAKEOVER, "Pink elephant", resource_dtor_A,
604
{resource_type, 3, ?RT_CREATE, "resource_type_B_goneZ",resource_dtor_B,
606
{resource_type, 4, ?RT_CREATE, "resource_type_null_goneZ",null,
610
?line 2 = nif_mod:lib_version(),
611
?CHECK([{upgrade,2,4,204},{lib_version,2,5,205}], nif_mod_call_history()),
613
?line ok = forget_resource(A3),
614
?CHECK([{{resource_dtor_B_v2,BinA3},2,6,206}], nif_mod_call_history()),
616
?line ok = forget_resource(NA3),
617
?CHECK([], nif_mod_call_history()),
619
?line ok = forget_resource(AN3),
620
?CHECK([{{resource_dtor_A_v2,BinAN3},2,7,207}], nif_mod_call_history()),
622
{A4,BinA4} = make_resource(2,Holder, "A4"),
623
{NA4,BinNA4} = make_resource(0,Holder, "NA4"),
624
{AN4,_BinAN4} = make_resource(1,Holder, "AN4"),
626
{BGZ1,BinBGZ1} = make_resource(3,Holder,"BGZ1"),
627
{NGZ1,_BinNGZ1} = make_resource(4,Holder,"NGZ1"),
629
?line false = code:purge(nif_mod),
630
?line [] = nif_mod_call_history(),
632
?line ok = forget_resource(NGY1),
633
?line [] = nif_mod_call_history(),
635
?line ok = forget_resource(BGY1), % calling dtor in orphan library v2 still loaded
636
?line [{{resource_dtor_B_v2,BinBGY1},2,8,208},{unload,2,9,209}] = nif_mod_call_history(),
638
%% Module upgrade with other lib-version
639
?line {module,nif_mod} = erlang:load_module(nif_mod,ModBin),
640
?line undefined = nif_mod:lib_version(),
641
?line ok = nif_mod:load_nif_lib(Config, 1,
642
[{resource_type, 2, ?RT_TAKEOVER, "resource_type_A",resource_dtor_A,
644
{resource_type, 0, ?RT_TAKEOVER bor ?RT_CREATE, "resource_type_null_A",resource_dtor_A,
646
{resource_type, 1, ?RT_TAKEOVER, "resource_type_A_null",null,
648
{resource_type, null, ?RT_TAKEOVER, "Mr Pink", resource_dtor_A,
652
?line 1 = nif_mod:lib_version(),
653
?line [{upgrade,1,1,101},{lib_version,1,2,102}] = nif_mod_call_history(),
655
%%?line false= check_process_code(Pid, nif_mod),
656
?line false = code:purge(nif_mod),
657
%% no unload here as we still have instances with destructors
658
?line [] = nif_mod_call_history(),
660
?line ok = forget_resource(BGZ1), % calling dtor in orphan library v2 still loaded
661
?line [{{resource_dtor_B_v2,BinBGZ1},2,10,210},{unload,2,11,211}] = nif_mod_call_history(),
663
?line ok = forget_resource(NGZ1),
664
?line [] = nif_mod_call_history(),
666
?line ok = forget_resource(A4),
667
?line [{{resource_dtor_A_v1,BinA4},1,3,103}] = nif_mod_call_history(),
669
?line ok = forget_resource(NA4),
670
?line [{{resource_dtor_A_v1,BinNA4},1,4,104}] = nif_mod_call_history(),
672
?line ok = forget_resource(AN4),
673
?line [] = nif_mod_call_history(),
675
?line [?MODULE, nif_mod] = erlang:system_info(taints),
676
?line verify_tmpmem(TmpMem),
679
make_resource(Type,Holder,Str) when is_list(Str) ->
680
Bin = list_to_binary(Str),
681
A1 = make_resource_do(Type,Holder,Bin),
682
?line Bin = read_resource(Type,A1),
685
make_resource_do(Type, Holder, Bin) ->
686
Holder ! {self(), make, Type, Bin},
687
{Holder, make_ok, Id} = receive_any(),
690
read_resource(Type, {Holder,Id}) ->
691
Holder ! {self(), get, Type, Id},
692
{Holder, get_ok, Bin} = receive_any(),
695
forget_resource({Holder,Id}) ->
696
Holder ! {self(), forget, Id},
697
{Holder, forget_ok, Id} = receive_any(),
703
resource_holder(List) ->
704
%%io:format("resource_holder waiting for msg\n", []),
706
%%io:format("resource_holder got ~p with list = ~p\n", [Msg,List]),
708
{Pid, make, Type, Bin} ->
709
?line Resource = nif_mod:make_new_resource(Type, Bin),
710
Id = {make_ref(),Bin},
711
Pid ! {self(), make_ok, Id},
712
resource_holder([{Id,Resource} | List]);
713
{Pid, get, Type, Id} ->
714
{Id,Resource} = lists:keyfind(Id, 1, List),
715
Pid ! {self(), get_ok, nif_mod:get_resource(Type, Resource)},
716
resource_holder(List);
719
NewList = lists:keydelete(Id, 1, List),
720
%%io:format("resource_holder forget: NewList = ~p\n", [NewList]),
721
resource_holder(Pid, {self(),forget_ok,Id}, NewList)
724
resource_holder(Pid,Reply,List) ->
725
erlang:garbage_collect(),
726
%%io:format("resource_holder GC'ed, now send ~p to ~p\n", [Reply,Pid]),
728
resource_holder(List).
731
threading(doc) -> ["Test the threading API functions (reuse tests from driver API)"];
732
threading(Config) when is_list(Config) ->
733
?line Data = ?config(data_dir, Config),
734
?line File = filename:join(Data, "tester"),
735
?line {ok,tester,ModBin} = compile:file(File, [binary,return_errors]),
736
?line {module,tester} = erlang:load_module(tester,ModBin),
738
?line ok = tester:load_nif_lib(Config, "basic"),
739
?line ok = tester:run(),
741
?line ok = tester:load_nif_lib(Config, "rwlock"),
742
?line ok = tester:run(),
744
?line ok = tester:load_nif_lib(Config, "tsd"),
745
?line ok = tester:run().
188
747
neg(doc) -> ["Negative testing of load_nif"];
190
748
neg(Config) when is_list(Config) ->
191
750
?line {'EXIT',{badarg,_}} = (catch erlang:load_nif(badarg, 0)),
192
?line {error,load_failed,_} = erlang:load_nif("pink_unicorn", 0),
751
?line {error,{load_failed,_}} = erlang:load_nif("pink_unicorn", 0),
194
753
?line Data = ?config(data_dir, Config),
195
754
?line File = filename:join(Data, "nif_mod"),
196
755
?line {ok,nif_mod,Bin} = compile:file(File, [binary,return_errors]),
197
756
?line {module,nif_mod} = erlang:load_module(nif_mod,Bin),
199
?line {error,bad_lib,_} = nif_mod:load_nif_lib(Config, no_init),
758
?line {error,{bad_lib,_}} = nif_mod:load_nif_lib(Config, no_init),
759
?line verify_tmpmem(TmpMem),
204
764
ensure_lib_loaded(Config) ->
205
765
ensure_lib_loaded(Config, 1).
207
766
ensure_lib_loaded(Config, Ver) ->
208
767
?line case lib_version() of
210
769
?line Path = ?config(data_dir, Config),
211
770
?line Lib = "nif_SUITE." ++ integer_to_list(Ver),
212
?line ok = erlang:load_nif(filename:join(Path,Lib), 0);
771
?line ok = erlang:load_nif(filename:join(Path,Lib), []);
213
772
Ver when is_integer(Ver) ->
777
case erlang:system_info({allocator,temp_alloc}) of
781
fun ({instance, _, L}, Acc) ->
782
{value,{_,MBCS}} = lists:keysearch(mbcs, 1, L),
783
{value,{_,SBCS}} = lists:keysearch(sbcs, 1, L),
789
fun(L, {Bl0,BlSz0}) ->
790
{value,{_,Bl,_,_}} = lists:keysearch(blocks, 1, L),
791
{value,{_,BlSz,_,_}} = lists:keysearch(blocks_size, 1, L),
796
verify_tmpmem(MemInfo) ->
797
%%wait_for_test_procs(),
800
io:format("Tmp mem info: ~p", [MemInfo]),
802
{notsup,undefined} ->
803
%% Use 'erl +Mea max' to do more complete memory leak testing.
804
{comment,"Incomplete or no mem leak testing"};
809
io:format("Expected: ~p", [MemInfo]),
810
io:format("Actual: ~p", [Other]),
218
815
%%io:format("~p calling ~p with ~p\n",[self(), Pid, Cmd]),
219
816
Pid ! {self(), Cmd},