Skip to content

Commit

Permalink
compiler: fix thread runtime initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Jan 11, 2025
1 parent af924e0 commit 2970a31
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 12 deletions.
9 changes: 8 additions & 1 deletion src/julec/obj/cxx/object.jule
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,11 @@ impl ObjectCoder {

fn initGlobals(mut &self) {
for (_, mut v) in self.ir.Ordered.Globals {
// Skip special cases
if v == meta::Program.Runtime.Threads ||
v == meta::Program.Runtime.NumCPU {
continue
}
self.Buf.WriteByte(indentKind)!
identCoder.var(self.Buf, v)
self.write(" = ")
Expand All @@ -1290,7 +1295,9 @@ impl ObjectCoder {

fn end(mut &self) {
self.write(`int main(int argc, char *argv[], char *envp[]) {`)
self.write("\n\n")
self.write("\n\t")
identCoder.funcIns(self.Buf, meta::Program.Runtime.Init)
self.write("();\n\n")
self.initGlobals()
self.write(`
__jule_argc = static_cast<jule::Int>(argc);
Expand Down
11 changes: 11 additions & 0 deletions src/julec/obj/meta/meta.jule
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ struct StrBuilder {

// Metadata for the runtime package.
struct Runtime {
Threads: &sema::Var
NumCPU: &sema::Var

// Hard initializer function of runtime.
Init: &sema::FuncIns

ToStr: &sema::Func
ArrayCmp: &sema::Func
Osyield: &sema::FuncIns
Expand Down Expand Up @@ -93,7 +99,12 @@ fn CollectRuntime(mut &ir: &obj::IR): &Runtime {
}
mut meta := new(Runtime)

// Globals.
meta.Threads = obj::RuntimeFindGlobal(p, "threads")
meta.NumCPU = obj::RuntimeFindGlobal(p, "numcpu")

// Functions.
meta.Init = obj::RuntimeFindFunc(p, "__init").Instances[0]
meta.ToStr = obj::RuntimeFindFunc(p, "toStr")
meta.ArrayCmp = obj::RuntimeFindFunc(p, "arrayCmp")
meta.Osyield = obj::RuntimeFindFunc(p, "osyield").Instances[0]
Expand Down
9 changes: 9 additions & 0 deletions src/julec/obj/runtime.jule
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

use "std/jule/sema"

fn RuntimeFindGlobal(mut &runtime: &sema::ImportInfo, ident: str): &sema::Var {
const Binded = false
mut f := runtime.FindVar(ident, Binded)
if f == nil {
panic("obj: runtime global variable is not exist, this is an implementation mistake, this panic call should be unreachable")
}
ret f
}

fn RuntimeFindFunc(mut &runtime: &sema::ImportInfo, ident: str): &sema::Func {
const Binded = false
mut f := runtime.FindFunc(ident, Binded)
Expand Down
14 changes: 9 additions & 5 deletions std/runtime/thread_unix.jule
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,18 @@ fn osyield() {
cpp.sched_yield()
}

fn init() {
// Reserved function for hard initialization.
// This function will be called at earlies stages of the program;
// Before initialization of global variables, and calling other initializer functions.
// This function must initialize critical data of the typical Jule program.
fn __init() {
// Set numcpu.
numcpu = unsafe { int(cpp.sysconf(_SC_NPROCESSORS_ONLN)) }
// Push the main thread to threads.
// See the documentation of the pushNewThread function.
threadMutex.lock()
// We already locked the mutex, set maxproc too.
numcpu = unsafe { int(cpp.sysconf(_SC_NPROCESSORS_ONLN)) }
// The |threads| should be initialized here, because compiler will not do it.
// We do not have to lock the mutex for threads, no risk for concurrency.
mut t := newThread()
t.os.handle = currentThreadID()
threads = t
threadMutex.unlock()
}
16 changes: 10 additions & 6 deletions std/runtime/thread_windows.jule
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,22 @@ fn osyield() {
cpp.SwitchToThread()
}

fn init() {
// Push the main thread to threads.
// See the documentation of the pushNewThread function.
threadMutex.lock()
// Reserved function for hard initialization.
// This function will be called at earlies stages of the program;
// Before initialization of global variables, and calling other initializer functions.
// This function must initialize critical data of the typical Jule program.
fn __init() {
// Set numcpu.
{
// We already locked the mutex, set maxproc too.
let info: cpp.SYSTEM_INFO
unsafe { cpp.GetSystemInfo(&info) }
numcpu = int(info.dwNumberOfProcessors)
}
// Push the main thread to threads.
// See the documentation of the pushNewThread function.
// The |threads| should be initialized here, because compiler will not do it.
// We do not have to lock the mutex for threads, no risk for concurrency.
mut t := newThread()
t.os.id = currentThreadID()
threads = t
threadMutex.unlock()
}

0 comments on commit 2970a31

Please sign in to comment.