// 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 --experimental-enable-isolate-groups-jit --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();
}
