How does the Dart VM manage OS threads under the hood when multiple isolates are created?

This is fantastic, thanks!

I went ahead and tested it on the quicksort example from the linked issue. And it works!

import 'dart:ffi';
import 'dart:isolate';
import 'dart:math';
import 'dart:typed_data';

import 'package:ffi/ffi.dart';

void main() async {
  const n = 40;
  final pointer = malloc.allocate<Int64>(n * Int64List.bytesPerElement);
  final array = pointer.asTypedList(n, finalizer: malloc.nativeFree);

  final random = Random();
  for (var i = 0; i < n; i++) {
    array[i] = random.nextInt(10);
  }

  print('Original array: $array');

  final receivePort = ReceivePort();
  final isolate = await Isolate.spawn(isolateEntry, [
    receivePort.sendPort,
    n,
    pointer,
  ]);

  bool working = true;
  receivePort.listen((message) {
    if (message is String) {
      print('Message: $message');
      receivePort.close();
      isolate.kill();
      working = false;
    }
  });

  while (working) {
    print('Current WIP array: $array');
    await Future<void>.delayed(Duration(milliseconds: 50));
  }

  print('Final: $array');
}

void isolateEntry(List<dynamic> args) async {
  final sendPort = args[0] as SendPort;
  final n = args[1] as int;
  final pointer = args[2] as Pointer<Int64>;
  final array = pointer.asTypedList(n);

  await _quickSort(array, 0, array.length - 1);

  sendPort.send("DONE");
}

int _partition(Int64List array, int low, int high) {
  int pivot = array[high];
  int i = (low - 1);

  for (var j = low; j < high; j++) {
    if (array[j] <= pivot) {
      _swap(array, ++i, j);
    }
  }

  _swap(array, i + 1, high);

  return i + 1;
}

Future<void> _quickSort(Int64List array, int low, int high) async {
  if (low < high) {
    int partitionIndex = _partition(array, low, high);

    // Introduce synthetic delay.
    await Future<void>.delayed(const Duration(milliseconds: 100));

    await Future.wait<void>([
      _quickSort(array, low, partitionIndex - 1),
      _quickSort(array, partitionIndex + 1, high),
    ]);
  }
}

void _swap(Int64List array, int i, int j) {
  final tmp = array[i];
  array[i] = array[j];
  array[j] = tmp;
}
7 Likes