Commit ec54c676 authored by John van Groningen's avatar John van Groningen

add parallel code generation on windows

parent d1e7b84a
implementation module PmDriver implementation module PmDriver
import StdArray, StdBool, StdList, StdMisc, StdEnum import StdArray, StdBool, StdList, StdMisc, StdEnum, StdStrictLists
import UtilNewlinesFile, UtilIO import UtilNewlinesFile, UtilIO
...@@ -24,13 +24,8 @@ import PmDirCache ...@@ -24,13 +24,8 @@ import PmDirCache
import Platform import Platform
from StdLibMisc import :: Date{..}, :: Time{..} from StdLibMisc import :: Date{..}, :: Time{..}
//from dodebug import trace_n`
//import nodebug
//import dodebug
trace_n _ g :== g trace_n _ g :== g
trace_n` _ g :== g trace_n` _ g :== g
//from StdDebug import trace_r
//--
verboseInfo verbose info ps :== verbi verbose info ps verboseInfo verbose info ps :== verbi verbose info ps
where where
...@@ -45,14 +40,11 @@ where ...@@ -45,14 +40,11 @@ where
traceInfo _ ps :== ps traceInfo _ ps :== ps
//traceInfo i ps :== showInfo i ps //traceInfo i ps :== showInfo i ps
//--
getFICache` ps getFICache` ps
# (_,ps) = getFICache ps # (_,ps) = getFICache ps
# fi = FI_EmptyCache # fi = FI_EmptyCache
= (fi,ps) = (fi,ps)
/*--- TO DO: /*--- TO DO:
system module dependancy analysis is possible... system module dependancy analysis is possible...
...@@ -132,6 +124,24 @@ GenAsmProjectModule path project setproject ps ...@@ -132,6 +124,24 @@ GenAsmProjectModule path project setproject ps
unknown_finished_processors :: !UnknownFinishedProcessors unknown_finished_processors :: !UnknownFinishedProcessors
}; };
:: *DriverState
= DInit !Bool !Project !MTPContinuation
| DComp !Bool !*DirCache !DriverCompilingInfo !(List String) !DriverStateRecord
| DGene !(List String) !DriverCodeGenerationInfo !DriverStateRecord
| DLink !DriverStateRecord
| DDone
:: *DriverStateRecord =
{ project :: !Project
, continue :: !MTPContinuation
, fileinfo :: !FileInfoCache
, abccache :: !*ABCCache
, libsinfo :: !StaticLibInfo
, ok :: !Bool
, newpaths :: !Bool
, modpaths :: !List String
}
BringProjectUptoDate :: !Bool CleanupCont !*GeneralSt -> *GeneralSt BringProjectUptoDate :: !Bool CleanupCont !*GeneralSt -> *GeneralSt
BringProjectUptoDate force continuation ps BringProjectUptoDate force continuation ps
# (project,ps) = getProject ps # (project,ps) = getProject ps
...@@ -256,26 +266,28 @@ where ...@@ -256,26 +266,28 @@ where
:: *DriverCodeGenerationInfo :: *DriverCodeGenerationInfo
= SyncCodeGeneration = SyncCodeGeneration
| ASyncCodeGeneration ![(Int,String,String)] !AsyncCompilingInfo // [(busy_process_number,abc_path,obj_path)] | ASyncCodeGeneration ![(Int,String,String)] !AsyncCompilingInfo // [(busy_process_number,abc_path,obj_path)]
| ASyncCodeGenerationWin ![WinCodeGeneratorProcess] /*max_n_processes*/!Int
:: *DriverState
= DInit !Bool !Project !MTPContinuation :: CodeGeneratorProcessNAndPaths
| DComp !Bool !*DirCache !DriverCompilingInfo !(List String) !DriverStateRecord = { cgp_process_n :: !Int, cgp_module_name :: !Modulename, cgp_obj_path :: !Pathname }
| DGene !(List String) !DriverCodeGenerationInfo !DriverStateRecord
| DLink !DriverStateRecord :: WinCodeGeneratorProcess = {
| DDone wcgp_process_n :: !Int,
wcgp_process_handle :: !Int,
:: *DriverStateRecord = wcgp_scg :: !StartedCodeGenerator,
{ project :: !Project wcgp_module_name :: !Modulename,
, continue :: !MTPContinuation wcgp_obj_path :: !Pathname
, fileinfo :: !FileInfoCache }
, abccache :: !*ABCCache
, libsinfo :: !StaticLibInfo get_neverTimeProfile_option :: !{#Char} Project !*GeneralSt -> (!Bool,!*GeneralSt)
, ok :: !Bool get_neverTimeProfile_option module_name project ps
, newpaths :: !Bool = case (PR_GetModuleInfo module_name project) of
, modpaths :: !List String Just modinfo
} -> (modinfo.compilerOptions.neverTimeProfile,ps)
_
//-- # (prefs,ps) = getPrefs ps
defaultCO = prefs.compopts
-> (defaultCO.neverTimeProfile,ps)
step :: !Bool !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt) step :: !Bool !*DriverState !*GeneralSt -> (!*DriverState,!*GeneralSt)
step intr (DInit force project setproject) ps step intr (DInit force project setproject) ps
...@@ -369,7 +381,7 @@ step intr (DComp force dircache (Async [] async_compiling_info=:{max_n_processes ...@@ -369,7 +381,7 @@ step intr (DComp force dircache (Async [] async_compiling_info=:{max_n_processes
# (paths,ds) = ds!modpaths # (paths,ds) = ds!modpaths
= step intr (DGene paths (ASyncCodeGeneration [] async_compiling_info) ds) ps = step intr (DGene paths (ASyncCodeGeneration [] async_compiling_info) ds) ps
step intr (DComp force dircache (AsyncWin [] {win_compiler_process_ids}) Nil ds) ps step intr (DComp force dircache (AsyncWin [] {win_compiler_process_ids,win_max_n_processes}) Nil ds) ps
// compile phase finished: remove all modules not (indirectly) imported by main module // compile phase finished: remove all modules not (indirectly) imported by main module
# project = PR_SetBuilt ds.modpaths ds.project // removes unused modules # project = PR_SetBuilt ds.modpaths ds.project // removes unused modules
# (modpaths,project) = PR_GetModulenames True IclMod project # (modpaths,project) = PR_GetModulenames True IclMod project
...@@ -377,7 +389,7 @@ step intr (DComp force dircache (AsyncWin [] {win_compiler_process_ids}) Nil ds) ...@@ -377,7 +389,7 @@ step intr (DComp force dircache (AsyncWin [] {win_compiler_process_ids}) Nil ds)
# ps = app_world_instead_of_ps (QuitCleanCompiler True win_compiler_process_ids) ps; # ps = app_world_instead_of_ps (QuitCleanCompiler True win_compiler_process_ids) ps;
# ps = showInfo (Level1 "Generating...") ps # ps = showInfo (Level1 "Generating...") ps
# (paths,ds) = ds!modpaths # (paths,ds) = ds!modpaths
= step intr (DGene paths SyncCodeGeneration ds) ps = step intr (DGene paths (ASyncCodeGenerationWin [] win_max_n_processes) ds) ps
step intr state=:(DComp force _ (Async _ _) _ _) ps step intr state=:(DComp force _ (Async _ _) _ _) ps
# ps = traceInfo (Level3 ["check_completed..."]) ps # ps = traceInfo (Level3 ["check_completed..."]) ps
...@@ -579,6 +591,10 @@ step intr (DGene Nil (ASyncCodeGeneration [] {unknown_finished_processors=NoUnkn ...@@ -579,6 +591,10 @@ step intr (DGene Nil (ASyncCodeGeneration [] {unknown_finished_processors=NoUnkn
#! ps = showInfo (Level1 "Linking...") ps #! ps = showInfo (Level1 "Linking...") ps
= step intr (DLink ds) ps = step intr (DLink ds) ps
step intr (DGene Nil (ASyncCodeGenerationWin [] _) ds) ps
#! ps = showInfo (Level1 "Linking...") ps
= step intr (DLink ds) ps
step intr (DGene (path:!rest) SyncCodeGeneration ds) ps step intr (DGene (path:!rest) SyncCodeGeneration ds) ps
| not ds.ok || intr | not ds.ok || intr
# ds = {ds & ok = False} # ds = {ds & ok = False}
...@@ -702,6 +718,76 @@ step intr (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes,comp ...@@ -702,6 +718,76 @@ step intr (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes,comp
# ds = {ds & fileinfo = fileinfo, abccache = abccache, ok = ok} # ds = {ds & fileinfo = fileinfo, abccache = abccache, ok = ok}
= cont (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) ds, ps) = cont (DGene paths (ASyncCodeGeneration busy_processes {max_n_processes=max_n_processes,compiler_process_ids=compiler_process_ids,unknown_finished_processors=unknown_finished_processors}) ds, ps)
step intr (DGene paths (ASyncCodeGenerationWin busy_processes win_max_n_processes) ds) ps
# (ok,busy_processes,project,fileinfo,ps)
= handle_finished_code_generators busy_processes ds.project ds.fileinfo ps
with
handle_finished_code_generators busy_processes=:[|_:_] project fileinfo ps
# process_handles = {wcgp_process_handle \\ {wcgp_process_handle} <- busy_processes}
# (i,ps) = wait_for_finished_code_generator process_handles ps
| i<0
= (False,busy_processes,project,fileinfo,ps)
# (finished_process,busy_processes) = remove_finished_process_from_list i busy_processes
with
remove_finished_process_from_list i [p:ps]
| i==0
= (p,ps)
# (fp,ps) = remove_finished_process_from_list (i-1) ps;
= (fp,[p:ps])
# (ok,ps) = finish_code_generator finished_process.wcgp_process_handle finished_process.wcgp_scg updateErrorWindow ps
| ok
# module_name = finished_process.wcgp_module_name
obj_path = finished_process.wcgp_obj_path
# (fileinfo,ps) = accFiles (FI_UpdateObjDate module_name obj_path fileinfo) ps
# project = PR_SetCodeGenerated module_name project
= (True,busy_processes,project,fileinfo,ps)
= (False,busy_processes,project,fileinfo,ps)
handle_finished_code_generators [|] project fileinfo ps
= (True,[],project,fileinfo,ps)
# ds = {ds & fileinfo = fileinfo, project = project, ok = ds.ok && ok && not intr}
| not ds.ok
= cont (DGene paths (ASyncCodeGenerationWin busy_processes win_max_n_processes) ds,ps)
| length busy_processes>=win_max_n_processes || (case paths of Nil -> True ; _ -> False)
= cont (DGene paths (ASyncCodeGenerationWin busy_processes win_max_n_processes) ds,ps)
# (ok,paths,busy_processes,fileinfo,abccache,ps) = start_code_generators paths busy_processes ds.fileinfo ds.abccache ps
with
start_code_generators :: (List {#Char}) [WinCodeGeneratorProcess] FileInfoCache *ABCCache !*GeneralSt
-> *(Bool,(List {#Char}),[WinCodeGeneratorProcess],FileInfoCache,*ABCCache,!*GeneralSt )
start_code_generators paths=:(mdn:!rest) busy_processes fileinfo abccache ps
| length busy_processes>=win_max_n_processes
= (True,paths,busy_processes,fileinfo,abccache,ps)
# (ps,abccache,fileinfo,gen,abc_path)
= CheckABCOutOfDate False mdn abccache fileinfo project ps
# (proc,ps) = getCurrentProc ps
# ((abccache,fileinfo,_), ps) = FI_GetFileInfo proc mdn abccache fileinfo ps
| not gen
= start_code_generators rest busy_processes fileinfo abccache ps
# module_name = GetModuleName mdn
# ps = showInfo (Level2 (
(foldl (+++) ("Generating code for "+++ module_name)
[" "+++wcgp_module_name \\ {wcgp_module_name}<-busy_processes])
)) ps
# (startupdir,ps) = getStup ps
(cgen,ps) = getCurrentCgen ps
(neverTimeProfile,ps) = get_neverTimeProfile_option module_name project ps
ao = PR_GetApplicationOptions project
timeprofile = ao.profiling && (not neverTimeProfile)
cgo = PR_GetCodeGenOptions project
# free_slot = hd (removeMembers [0..win_max_n_processes-1] [wcgp_process_n \\ {wcgp_process_n} <- busy_processes])
# (res,process_handle,scg,ps)
= start_code_generator cgen updateErrorWindow abc_path free_slot timeprofile cgo proc startupdir ps
| not res
= (False,rest,busy_processes,fileinfo,abccache,ps)
# obj_path = MakeObjSystemPathname proc mdn
# new_process = {wcgp_process_n=free_slot,wcgp_process_handle=process_handle,wcgp_scg=scg,wcgp_module_name=module_name,wcgp_obj_path=obj_path}
# busy_processes = [new_process:busy_processes]
= start_code_generators rest busy_processes fileinfo abccache ps
start_code_generators Nil busy_processes fileinfo abccache ps
= (True,Nil,busy_processes,fileinfo,abccache,ps)
# ds = {ds & fileinfo = fileinfo, abccache = abccache, ok = ok}
= cont (DGene paths (ASyncCodeGenerationWin busy_processes win_max_n_processes) ds, ps)
step intr (DLink ds=:{ok, newpaths, fileinfo, libsinfo, modpaths, abccache, project, continue}) ps step intr (DLink ds=:{ok, newpaths, fileinfo, libsinfo, modpaths, abccache, project, continue}) ps
// Check whether executable is out of date and relink it if required. // Check whether executable is out of date and relink it if required.
| intr || not ok | intr || not ok
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment