blob: 695fda237356c7ac90cd01aa098ef5f14a2bfa1c [file] [log] [blame]
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// SharedObjects=ffi_test_functions
// VMOptions=--enable-isolate-groups --disable-heap-verification
import 'dart:async';
import 'dart:ffi';
import 'package:expect/expect.dart';
import 'test_utils.dart';
import '../../../../../tests/ffi_2/dylib_utils.dart';
// This should be larger than max-new-space-size/tlab-size.
const int threadCount = 200;
class Isolate extends Opaque {}
typedef Dart_CurrentIsolateFT = Pointer<Isolate> Function();
typedef Dart_CurrentIsolateNFT = Pointer<Isolate> Function();
typedef Dart_EnterIsolateFT = void Function(Pointer<Isolate>);
typedef Dart_EnterIsolateNFT = Void Function(Pointer<Isolate>);
typedef Dart_ExitIsolateFT = void Function();
typedef Dart_ExitIsolateNFT = Void Function();
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
final threadPoolBarrierSync = ffiTestFunctions.lookupFunction<
Void Function(
Pointer<NativeFunction<Dart_CurrentIsolateNFT>>,
Pointer<NativeFunction<Dart_EnterIsolateNFT>>,
Pointer<NativeFunction<Dart_ExitIsolateNFT>>,
IntPtr),
void Function(
Pointer<NativeFunction<Dart_CurrentIsolateNFT>>,
Pointer<NativeFunction<Dart_EnterIsolateNFT>>,
Pointer<NativeFunction<Dart_ExitIsolateNFT>>,
int)>('ThreadPoolTest_BarrierSync');
final Pointer<NativeFunction<Dart_CurrentIsolateNFT>> dartCurrentIsolate =
DynamicLibrary.executable().lookup("Dart_CurrentIsolate").cast();
final Pointer<NativeFunction<Dart_EnterIsolateNFT>> dartEnterIsolate =
DynamicLibrary.executable().lookup("Dart_EnterIsolate").cast();
final Pointer<NativeFunction<Dart_ExitIsolateNFT>> dartExitIsolate =
DynamicLibrary.executable().lookup("Dart_ExitIsolate").cast();
class Worker extends RingElement {
final int id;
Worker(this.id);
Future run(dynamic _, dynamic _2) async {
threadPoolBarrierSync(
dartCurrentIsolate, dartEnterIsolate, dartExitIsolate, threadCount);
return id;
}
}
main(args) async {
final ring = await Ring.create(threadCount);
// Let each worker:
// - call into C
// - exit the isolate
// - wait until notified
// - continue & exit
final results = await ring.run((int id) => Worker(id));
Expect.equals(threadCount, results.length);
for (int i = 0; i < threadCount; ++i) {
Expect.equals(i, results[i]);
}
await ring.close();
}