diff --git a/mozglue/build/parallel_invoke.h b/mozglue/build/parallel_invoke.h
new file mode 100644
--- /dev/null
+++ b/mozglue/build/parallel_invoke.h
@@ -0,0 +1,18 @@
+#ifndef parallel_invoke_h_
+#define parallel_invoke_h_
+
+#include "mozilla/Types.h"
+
+MOZ_BEGIN_EXTERN_C
+
+#define PARALLEL_INVOKE_MAX_THREADS (-1)
+typedef void (*PARALLEL_INVOKE_FUNC)(void *param);
+
+MFBT_API void parallel_invoke(PARALLEL_INVOKE_FUNC *functions,
+                              int count,
+                              void *param = nullptr,
+                              int num_threads = PARALLEL_INVOKE_MAX_THREADS);
+
+MOZ_END_EXTERN_C
+
+#endif /* !defined(parallel_invoke_h_) */
diff --git a/mozglue/build/parallel_invoke.cpp b/mozglue/build/parallel_invoke.cpp
new file mode 100644
--- /dev/null
+++ b/mozglue/build/parallel_invoke.cpp
@@ -0,0 +1,44 @@
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+#include "parallel_invoke.h"
+
+void parallel_invoke(PARALLEL_INVOKE_FUNC *functions,
+                     int count,
+                     void *param,
+                     int num_threads)
+{
+#ifdef _OPENMP
+
+  if (num_threads == PARALLEL_INVOKE_MAX_THREADS)
+    num_threads = omp_get_max_threads();
+
+  if (num_threads <= 0)
+    num_threads = 1;
+
+  if (num_threads == 1 || count <= 1) {
+    for (int i = 0; i < count; i++) {
+      functions[i](param);
+    }
+  } else {
+#pragma omp parallel num_threads(num_threads)
+    {
+#pragma omp master
+      functions[0](param);
+
+#pragma omp for schedule(dynamic)
+      for (int i = 1; i < count; i++) {
+        functions[i](param);
+      }
+    }
+  }
+
+#else  // _OPENMP
+
+  for (int i = 0; i < count; i++) {
+    functions[i](param);
+  }
+
+#endif // _OPENMP
+}
