Skip to content

Commit

Permalink
Merge pull request #236 from vein-lang/feature/threading
Browse files Browse the repository at this point in the history
Initial Threading
  • Loading branch information
0xF6 authored Jun 10, 2024
2 parents 6edf728 + a6e2fa3 commit 686032d
Show file tree
Hide file tree
Showing 23 changed files with 766 additions and 44 deletions.
3 changes: 2 additions & 1 deletion runtime/common/reflection/MethodFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum MethodFlags : short
Virtual = 1 << 6,
Abstract = 1 << 7,
Override = 1 << 8,
Special = 1 << 9
Special = 1 << 9,
Async = 1 << 10,
}
}
105 changes: 105 additions & 0 deletions runtime/ishtar.vm.libuv/LibUV.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
namespace ishtar.vm.libuv;

using System.Runtime.InteropServices;


public static class LibUV
{
public const string LIBNAME = "libuv";

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_thread_create(out uv_thread_t tid, uv_thread_cb entry, IntPtr arg);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_thread_join(uv_thread_t tid);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern nint uv_loop_new();

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_loop_init(nint loop);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_run(nint loop, uv_run_mode mode);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern void uv_stop(nint loop);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_async_init(nint loop, nint handle, uv_async_cb cb);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_async_send(nint handle);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern void uv_close(nint handle, uv_close_cb cb);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern ulong uv_thread_self();

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern nint uv_default_loop();

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_timer_init(nint loop, nint handle);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_timer_start(nint handle, uv_timer_cb cb, ulong timeout, ulong repeat);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern void uv_timer_stop(nint handle);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_queue_work(nint loop, ref uv_work_t req, uv_work_cb work_cb, uv_after_work_cb after_work_cb);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int uv_sem_init(out uv_sem_t sem, int value);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern void uv_sem_post(ref uv_sem_t sem);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern void uv_sem_wait(ref uv_sem_t sem);

[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
public static extern void uv_sem_destroy(ref uv_sem_t sem);

public delegate void uv_async_cb(nint handle);
public delegate void uv_close_cb(nint handle);
public delegate void uv_timer_cb(nint handle);
public delegate void uv_thread_cb(nint arg);
public delegate void uv_after_work_cb(nint req, int status);
public delegate void uv_work_cb(nint req);


public enum uv_run_mode
{
UV_RUN_DEFAULT = 0,
UV_RUN_ONCE = 1,
UV_RUN_NOWAIT = 2
}
public enum uv_loop_option
{
UV_LOOP_BLOCK_SIGNAL = 0,
UV_METRICS_IDLE_TIME = 1
}


[StructLayout(LayoutKind.Sequential)]
public struct uv_thread_t
{
private nint handle;
}

[StructLayout(LayoutKind.Sequential)]
public struct uv_sem_t
{
private nint handle;
}

[StructLayout(LayoutKind.Sequential)]
public struct uv_work_t
{
private nint handle;
}
}
10 changes: 10 additions & 0 deletions runtime/ishtar.vm.libuv/ishtar.vm.libuv.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Libuv" Version="1.10.0" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion runtime/ishtar.vm/FFI/ForeignFunctionInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public static void LinkExternalNativeLibrary(string importModule, string fnName,
{
var jitter = importCaller->Owner->Owner->vm.Jitter;

jitter.Compile21FFI(importCaller, importModule, fnName);
jitter.CompileFFI(importCaller, importModule, fnName);
}


Expand Down
20 changes: 8 additions & 12 deletions runtime/ishtar.vm/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Runtime.InteropServices;
using System.Text;
using ishtar;
using ishtar.runtime.gc;
using vein.fs;
using vein.runtime;

Expand All @@ -12,14 +11,9 @@
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Console.OutputEncoding = Encoding.Unicode;

BoehmGCLayout.Native.Load();
BoehmGCLayout.Native.GC_set_find_leak(true);
BoehmGCLayout.Native.GC_init();

var vm = VirtualMachine.Create("app");
var vault = vm.Vault;



var masterModule = default(IshtarAssembly);
var resolver = default(AssemblyResolver);

Expand Down Expand Up @@ -51,7 +45,7 @@

var module = resolver.Resolve(masterModule);

module->class_table->ForEach(x => x->init_vtable(vm));
module->class_table->ForEach(x => x->init_vtable(x->Owner->vm));

var entry_point = module->GetEntryPoint();

Expand All @@ -62,15 +56,17 @@
}

var args_ = stackalloc stackval[1];




var frame = CallFrame.Create(entry_point, null);
frame->args = args_;


var watcher = Stopwatch.StartNew();
vm.exec_method(frame);

entry_point->ForceSetAsAsync();

vm.task_scheduler->start_threading(module);
vm.task_scheduler->execute_method(frame);

if (!frame->exception.IsDefault())
{
Expand Down
31 changes: 21 additions & 10 deletions runtime/ishtar.vm/VirtualMachine.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
namespace ishtar
{
using emit;
using io;
using ishtar.llmv;
using ishtar.runtime.vin;
using runtime;
using runtime.gc;
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using collections;
using vein.extensions;
using vein.reflection;
using vein.runtime;
using static OpCodeValue;
using static vein.runtime.VeinTypeCode;
using static WNE;
using runtime.gc;
using ishtar.llmv;

public delegate void A_OperationDelegate<T>(ref T t1, ref T t2);

public unsafe partial class VirtualMachine : IDisposable
{


VirtualMachine() {}

/// <exception cref="OutOfMemoryException">There is insufficient memory to satisfy the request.</exception>
public static VirtualMachine Create(string name)
{
BoehmGCLayout.Native.Load();
BoehmGCLayout.Native.GC_set_find_leak(true);
BoehmGCLayout.Native.GC_init();
BoehmGCLayout.Native.GC_allow_register_threads();

var vm = new VirtualMachine();
vm.Jit = new IshtarJIT(vm);
vm.Config = new VMConfig();
Expand All @@ -51,6 +52,10 @@ public static VirtualMachine Create(string name)

vm.FFI = new ForeignFunctionInterface(vm);
vm.Jitter = new LLVMContext();

vm.threading = new IshtarThreading();

vm.task_scheduler = vm.threading.CreateScheduler();

return vm;
}
Expand Down Expand Up @@ -123,8 +128,10 @@ public void Dispose()
internal IshtarTrace trace;
internal LLVMContext Jitter;
public IshtarTypes* Types;
public IshtarThreading threading;
public TaskScheduler* task_scheduler;



public bool HasFaulted() => CurrentException is not null;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down Expand Up @@ -251,6 +258,8 @@ public void exec_method(CallFrame* invocation)
var locals = default(SmartPointer<stackval>);

var ip = mh->code;

// todo, revert to stackalloc
var stack = stackval.Allocate(invocation, mh->max_stack);

const int STACK_VIOLATION_LEVEL_SIZE = 32;
Expand Down Expand Up @@ -720,8 +729,10 @@ void ForceFail(RuntimeIshtarClass* clazz)
child_frame->args = method_args;


if (method->IsExtern) exec_method_native(child_frame);
else exec_method(child_frame);
if (method->IsExtern)
exec_method_native(child_frame);
else
task_scheduler->execute_method(child_frame);

if (method->ReturnType->TypeCode != TYPE_VOID)
{
Expand Down
Loading

0 comments on commit 686032d

Please sign in to comment.