# HG changeset patch # User Mike Pavone # Date 1290157454 18000 # Node ID a68e6828d8960a12deb98f829a8c34f1e2058474 # Parent 1411de6050e153321dbad8e6e61da6f9b9948d0f Global stores and transactions are working. Definately leaks memory on retries. Probably a fair number of bugs to work out. However, a basic test program works. diff -r 1411de6050e1 -r a68e6828d896 backendutils_c.rhope --- a/backendutils_c.rhope Tue Nov 16 21:53:18 2010 -0500 +++ b/backendutils_c.rhope Fri Nov 19 04:04:14 2010 -0500 @@ -164,6 +164,27 @@ out <- op } +Blueprint Global Get +{ + Store + Var +} + +Global Get[store,var:out] +{ + out <- [[Build[Global Get()]]Store <<[store]]Var <<[var] +} + +Make Op@Global Get[get,func:out] +{ + out <- [func]Global Reference[[get]Store >>, [get]Var >>] +} + +Strip Addref@Global Get[get:out] +{ + out <- get +} + Blueprint Check Result { Output Num diff -r 1411de6050e1 -r a68e6828d896 cbackend_c.rhope --- a/cbackend_c.rhope Tue Nov 16 21:53:18 2010 -0500 +++ b/cbackend_c.rhope Fri Nov 19 04:04:14 2010 -0500 @@ -244,6 +244,30 @@ } } +_Global Type Defs C[text,store,p:out] +{ + estore <- Escape Rhope Name[[store]Name >>, p] + varnames <- Map[Keys[[store]Vars >>], Escape Rhope Name[?, p]] + out <- [text]Append[ + [[[[[[[[["typedef struct {\n\tobject header;\n\t" + ]Append[ [[ Map[varnames, ["object * gs_"]Append[?]] ]Join[";\n\t"] + ]Append[";\n} mutt_"]] + ]Append[estore] + ]Append[[[";\nmutable_object * gs_"]Append[estore]]Append[";\n\n"]] + ]Append[[["void gscopy_"]Append[estore]]Append[[["(object * obj)\n{\n\tmutt_"]Append[estore]]Append[[[" *mutt_obj = (mutt_"]Append[estore]]Append[" *)obj;\n\t"]]]] + ]Append[ [Map[varnames, ["add_ref(mutt_obj->gs_"]Append[?]]]Join[");\n\t"] ] + ]Append[");\n}\n\n"] + ]Append[[["void gscleanup_"]Append[estore]]Append[[["(object * obj)\n{\n\tmutt_"]Append[estore]]Append[[[" *mutt_obj = (mutt_"]Append[estore]]Append[" *)obj;\n\t"]]]] + ]Append[ [Map[varnames, ["release_ref(mutt_obj->gs_"]Append[?]]]Join[");\n\t"] ] + ]Append[");\n}\n\n"] ] +} + +_Global Type Inits C[text,store,p:out] +{ + estore <- Escape Rhope Name[[store]Name >>, p] + out <- [text]Append[ [[[[[[[[["\tbp = register_type(sizeof(mutt_"]Append[estore]]Append[ [[[")-sizeof(object), NULL, gscopy_"]Append[estore]]Append[", gscleanup_"]]Append[estore] ]]Append[");\n\tgs_"]]Append[estore]]Append[" = (mutable_object *)new_object(TYPE_MUTABLEGLOBAL);\n\tgs_"]]Append[estore]]Append["->data = new_object_bp(bp);\n\tgs_"]]Append[estore]]Append["->version = 0;"] ] +} + _Type Init C[type name,method reg,text,method,p:out] { out <- [[text]Append[[["\n\tadd_method(bp, "]Append[ [method reg]Method ID[method] ]]Append[ [[", MethodName("]Append[Escape Rhope Name[method,p]]]Append[[","]Append[Escape Rhope Name[type name,p]]]]]]Append["));"] @@ -408,6 +432,7 @@ Constants Input Types Output Types + Uses Resume Index Last NumParams Escape Pattern @@ -420,7 +445,7 @@ C Function With Registry[name,inputs,outputs,convention,registry,field reg,type reg,p:out] { - out <- [[[[[[[[[[[[[[[Build[C Function()] + out <- [[[[[[[[[[[[[[[[Build[C Function()] ]Name <<[name] ]Inputs <<[inputs] ]Outputs <<[outputs] @@ -436,6 +461,7 @@ ]Resume Index <<[1] ]Last NumParams <<[-1] ]Escape Pattern <<[p] + ]Uses <<[()] } Set Input Type@C Function[func,type,input num:out] @@ -652,8 +678,22 @@ result op <- Field Ref[var,field] } +Global Reference@C Function[func,store,var:out] +{ + + estore <- Escape Rhope Name[store,[func]Escape Pattern >>] + out <- [[[[[ [["((mutt_"]Append[estore]]Append["*)lv_"]]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->gs_"]]Append[estore]]Append["->local_data)->gs_"]]Append[Escape Rhope Name[var,[func]Escape Pattern >>]] +} - +Set Global@C Function[func,store,var,src:out] +{ + estore <- Escape Rhope Name[store,[func]Escape Pattern >>] + cell pointer <- [[["lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->gs_"]]Append[estore] + out <- [[[[func]Add Statement[[["tmp = copy_object("]Append[[cell pointer]Append["->local_data"]]]Append[")"]] + ]Add Statement[ [[[["((mutt_"]Append[estore]]Append[" *)tmp)->gs_"]]Append[Escape Rhope Name[var, [func]Escape Pattern >>]]]Append[[" = "]Append[[src]Make Op[func]]] ] + ]Add Statement[[cell pointer]Append["->local_data = tmp"]] + ]Add Statement[[cell pointer]Append["->local_version++"]] +} Set Field Null@C Function[func,var,field:out] { @@ -983,6 +1023,10 @@ { out <- [[[string]Append[ ["\t"]Append[Rhope Type to C[type,p]] ]]Append[[" "]Append[Escape Rhope Name[varname,p]]]]Append[";\n"] } +_Global Cell Defs C[func,p,string,store:out] +{ + out <- [string]Append[ [["\ttrans_cell *gs_"]Append[Escape Rhope Name[store,p]]]Append[";\n"] ] +} Definitions@C Function[func:out] @@ -991,7 +1035,7 @@ { If[ [[[func]Convention >>] = ["rhope"]] And [[ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] > [0]] ] { - localtype <- [[[Fold[_Output Defs C[?, ?, ?, func], Fold[_Var Defs C[?,?,?,[func]Escape Pattern >>],"typedef struct {\n", [func]Variables >>], [func]Outputs >>]]Append["} lt_"]]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append[";\n"] + localtype <- [[[Fold[_Global Cell Defs C[func,[func]Escape Pattern >>,?], Fold[_Output Defs C[?, ?, ?, func], Fold[_Var Defs C[?,?,?,[func]Escape Pattern >>],"typedef struct {\n", [func]Variables >>], [func]Outputs >>], [func]Uses >>]]Append["} lt_"]]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append[";\n"] }{ localtype <- "" } @@ -1062,6 +1106,12 @@ } } +Find Trans Cell@C Function[func,text,store:out] +{ + estore <- Escape Rhope Name[store,[func]Escape Pattern >>] + out <- [text]Append[ [[[["lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->gs_"]]Append[estore]]Append[[[" = find_obj_cell(ct->transaction, gs_"]Append[estore]]Append[");\n"]] ] +} + Text@C Function[func:out] { Print[["Text@C Function: "]Append[[func]Name >>]] @@ -1081,7 +1131,7 @@ } fname <- Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>] param check <- Fold[Check Param Type C[?, ?, ?, func], "", [func]Input Types >>] - If[ [ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] = [0] ] + If[ [ [[[[func]Variables >>]Length]+[[[func]Outputs >>]Length]]+[[[func]Uses >>]Length] ] = [0] ] { out <- [[[[[[[[ [type]Append["NoLocals("] ]Append[cname] @@ -1099,14 +1149,29 @@ }{ freecall <- "\n\tFreeCall\n" } - out <- [[[[[[[[[[ [type]Append["("] + If[[[func]Uses >>]Length] + { + begin trans <- [[[["\tbegin_transaction(ct, "]Append[ String[[[func]Uses >>]Length] ]]Append[", "]]Append[ [Map[Map[[func]Uses >>, Escape Rhope Name[?, [func]Escape Pattern >>]], ["gs_"]Append[?]]]Join[", "] ]]Append[");\n"] + init trans <- [[Fold[Find Trans Cell[func,?], begin trans, [func]Uses >>] + ]Append[[["transretry_"]Append[fname]]Append[":\n"]] + ]Append["\tfor(idx = 0; idx < cdata->num_params; ++idx) { add_ref(cdata->params[idx]); }\n"] + //TODO: Figure out whether this is a readonly or write transaction + commit trans <- [[["\tif(!commit_transaction(ct, 0)) { prep_retry(ct); goto transretry_"]Append[fname]]Append["; }\n"] + ]Append["\tfor(idx = 0; idx < cdata->num_params; ++idx) { release_ref(cdata->params[idx]); }\n"] + }{ + init trans <- "" + commit trans <- "" + } + out <- [[[[[[[[[[[[ [type]Append["("] ]Append[cname] ]Append[",\n\tNumParams "] ]Append[ String[[[func]Inputs >>]Length] ] ]Append[")\n\n"] ]Append[param check] + ]Append[init trans] ]Append[ [[func]Statements >>]Join[""] ] ]Append[freecall] + ]Append[commit trans] ]Append[[func]Set Outputs] ]Append[[["EndFunc("]Append[fname]]Append[")\n"]] ]Append["DISPATCH"] @@ -1129,6 +1194,7 @@ Field Registry Type Registry Libraries + Global Stores Escape Pattern } @@ -1136,7 +1202,7 @@ { p <- Pattern[("_", "@", " ", ":", "?", "+", "-", "*", "/", "<", ">", "(", ")", "!", "=", "'", "\"", "\t", ",", ".", "\n", "{", "}", "[", "]", "#", "\\", "\r", ";", "&", "|", "%", "^", "`", "~")] - out <- [[[[[[Build[C Program()]]Functions <<[Dictionary[]]]Method Registry <<[C Method Registry[]]]Type Registry <<[C Type Registry[p]]]Field Registry <<[C Field Registry[]]]Libraries <<[Dictionary[]]]Escape Pattern <<[p] + out <- [[[[[[[Build[C Program()]]Functions <<[Dictionary[]]]Method Registry <<[C Method Registry[]]]Type Registry <<[C Type Registry[p]]]Field Registry <<[C Field Registry[]]]Libraries <<[Dictionary[]]]Escape Pattern <<[p]]Global Stores <<[Dictionary[]] } Supported Number Types@C Program[program:out] @@ -1373,6 +1439,17 @@ } } +_Global Var Init C[text,value,name,storevar,type reg:out] +{ + out <- [[[[[text]Append[storevar]]Append[Escape Rhope Name[name, [type reg]Escape Pattern >>]]]Append[" = "]]Append[Const Construct C[value, type reg]]]Append[";\n"] +} + +_Global Store Inits C[text,store,type reg:out] +{ + estore <- Escape Rhope Name[[store]Name >>, [type reg]Escape Pattern >>] + out <- Fold[_Global Var Init C[?,?,?, [[[["\t((mutt_"]Append[estore]]Append[" *)(gs_"]]Append[estore]]Append["->data))->gs_"], type reg], text, [store]Vars >>] +} + _Dispatch Switch Sub[text, num, name:out] { out <- [[[[[text @@ -1533,9 +1610,10 @@ #include \"worker.h\" #include \"bool.h\" #include \n\n" - out <- [[[[[[[[[[[[[[[[[[headers + out <- [[[[[[[[[[[[[[[[[[[[[headers ]Append[[program]Dispatch[all methods]] ]Append[[[program]Type Registry >>]Type Defs] + ]Append[Fold[_Global Type Defs C[?,?,p], "", [program]Global Stores >>]] ]Append[Fold[_Consts C Program[?,?,?,p], Fold[_Defs C Program[?], "", [program]Functions >>], constants]] @@ -1556,6 +1634,7 @@ #endif uint16_t resume,idx, vcparam_offset, last_vcparam; context * ct; + void *tmp; calldata * cdata, *temp_cdata, *my_cdata; DispatchVar FuncDef(Build) @@ -1652,10 +1731,13 @@ int numret; int idx; object * inout[3]; - register_builtin_types();\n\n"] + register_builtin_types(); + register_type_byid(TYPE_MUTABLEGLOBAL, sizeof(mutable_object)-sizeof(object), NULL, NULL, NULL);\n\n"] ]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ] + ]Append[Fold[_Global Type Inits C[?, ?, p], "", [program]Global Stores >>]] ]Append[Fold[_Set Consts C Program[?, ?, ?, [program]Type Registry >>], "", constants]] ]Append[Fold[_Set Late Consts C[?, ?, ?, [program]Type Registry >>], "", constants]] + ]Append[Fold[_Global Store Inits C[?, ?, [program]Type Registry >>], "", [program]Global Stores >>]] ]Append[Fold[Init Type Names[?, ?, ?, [program]Type Registry >>], "", [[program]Type Registry >>]Lookup >>]] ]Append[" rhope(FUNC_List, inout, 0, 1); diff -r 1411de6050e1 -r a68e6828d896 ctobin --- a/ctobin Tue Nov 16 21:53:18 2010 -0500 +++ b/ctobin Fri Nov 19 04:04:14 2010 -0500 @@ -20,8 +20,8 @@ file=$1 shift -echo "$CC -o $bin $@ $file.c blueprint.c context.c fixed_alloc.c object.c" -$CC -o $bin $@ "$file.c" blueprint.c context.c fixed_alloc.c object.c +echo "$CC -o $bin $@ $file.c blueprint.c context.c fixed_alloc.c object.c transaction.c" +$CC -o $bin $@ "$file.c" blueprint.c context.c fixed_alloc.c object.c transaction.c cd .. diff -r 1411de6050e1 -r a68e6828d896 nworker_c.rhope --- a/nworker_c.rhope Tue Nov 16 21:53:18 2010 -0500 +++ b/nworker_c.rhope Fri Nov 19 04:04:14 2010 -0500 @@ -296,7 +296,7 @@ NWorker[convention:out] { - out <- [[[[[[[[[Build[NWorker()]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]]Input Types <<[()]]Output Types <<[()]]Name <<["Anonymous"]]Builtin? <<[No]]Library << [""] + out <- [[[[[[[[[[Build[NWorker()]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]]Input Types <<[()]]Output Types <<[()]]Name <<["Anonymous"]]Builtin? <<[No]]Library << [""]]Uses <<[()] } String@NWorker[worker:out] @@ -393,62 +393,68 @@ out <- nodelist }{ - [node]Has Input Types? + If[[[node]Type >>] = ["getglobal"]] { - If[[[node]Type >>] = ["setfield"]] + nextnode <- [node]Output Types <<[ [()]Append[Type Instance["Any Type"]] ] + }{ + [node]Has Input Types? { - nextnode <- [node]Output Types <<[ [()]Append[ [[[node]Input Types >>]Index[0]]Index[0] ] ] - }{ - If[[[node]Type >>] = ["getfield"]] + If[[[node]Type >>] = ["setfield"]] { - type <- [[[node]Input Types >>]Index[0]]Index[0] - If[[[type]Name >>] = ["Any Type"]] + nextnode <- [node]Output Types <<[ [()]Append[ [[[node]Input Types >>]Index[0]]Index[0] ] ] + }{ + If[[[node]Type >>] = ["getfield"]] { - outtype <- Val[type] - }{ - outtype <- [prog]Find Field[[node]Data >>, type] {} + type <- [[[node]Input Types >>]Index[0]]Index[0] + If[[[type]Name >>] = ["Any Type"]] { - //TODO: Return errors rather than printing them - Print[ - [[[[["Type " - ]Append[[type]Name >>] - ]Append[" does not have a field named "] - ]Append[[node]Data >>] - ]Append[" in worker "] - ]Append[worker name]] - } - } - nextnode <- [node]Output Types <<[ [()]Append[outtype] ] - }{ - worker name <- [[node]Data >>]Name >> - [prog]Is Method?[worker name] - { - first arg type <- [[[node]Input Types >>]Index[0]]Index[0] - If[[[first arg type]Name >>] = ["Any Type"]] - { - outtypes <- Fold[Append[?, Type Instance["Any Type"]], (), Range[0, [node]Inputs >>]] + outtype <- Val[type] }{ - worker def <- [prog]Find Method[worker name, first arg type] {} + outtype <- [prog]Find Field[[node]Data >>, type] {} { - //TODO: Return errors instead of printing them + //TODO: Return errors rather than printing them Print[ [[[[["Type " - ]Append[[first arg type]Name >>] - ]Append[" does not support method "] - ]Append[worker name] + ]Append[[type]Name >>] + ]Append[" does not have a field named "] + ]Append[[node]Data >>] ]Append[" in worker "] - ]Append[ [worker]Name >> ]] + ]Append[worker name]] } } + nextnode <- [node]Output Types <<[ [()]Append[outtype] ] }{ - worker def <- [prog]Find Worker Def[worker name] + + worker name <- [[node]Data >>]Name >> + [prog]Is Method?[worker name] + { + first arg type <- [[[node]Input Types >>]Index[0]]Index[0] + If[[[first arg type]Name >>] = ["Any Type"]] + { + outtypes <- Fold[Append[?, Type Instance["Any Type"]], (), Range[0, [node]Inputs >>]] + }{ + worker def <- [prog]Find Method[worker name, first arg type] {} + { + //TODO: Return errors instead of printing them + Print[ + [[[[["Type " + ]Append[[first arg type]Name >>] + ]Append[" does not support method "] + ]Append[worker name] + ]Append[" in worker "] + ]Append[ [worker]Name >> ]] + } + } + }{ + worker def <- [prog]Find Worker Def[worker name] + } + outtypes <- [worker def]Output Types >> + nextnode <- [node]Output Types <<[ outtypes ] } - outtypes <- [worker def]Output Types >> - nextnode <- [node]Output Types <<[ outtypes ] } + }{ + out <- nodelist } - }{ - out <- nodelist } } } @@ -737,6 +743,16 @@ }{ out <- Constant[Const Name[[node]Data >>, [noderef]Index >>, [worker]Name >>]] } + }{ + If[[[node]Type >>]=["getglobal"]] + { + [conditions]Empty? + { + out <- AddRef[Result Var Name[[noderef]IO Num >>, [noderef]Index >>]] + }{ + out <- AddRef[Global Get[[[node]Data >>]Index[0], [[node]Data >>]Index[1]]] + } + } } } } @@ -905,14 +921,40 @@ nfunc <- Val[withconst] } }{ - [conditions]For Backend + If[[[node]Type >>]=["getglobal"]] { - input name <- [[worker]Inputs >>]Index[ [node]Data >> ] - stream <- [[func]Instruction Stream - ]Move[input name, Result Var Name[0, node index]] - nfunc <- [func]Do If[~, stream] + [conditions]For Backend + { + stream <- [[func]Instruction Stream + ]Move[Global Get[[[node]Data >>]Index[0], [[node]Data >>]Index[1]], Result Var Name[0, node index]] + nfunc <- [func]Do If[~, stream] + }{ + nfunc <- Val[func] + } }{ - nfunc <- Val[func] + If[[[node]Type >>]=["setglobal"]] + { + inputs <- [worker]Collect Inputs[node] + [conditions]For Backend + { + stream <- [func]Instruction Stream + nfunc <- [func]Do If[~, nstream] + }{ + stream <- Val[func] + nfunc <- Val[nstream] + } + nstream <- [stream]Set Global[[[node]Data >>]Index[0], [[node]Data >>]Index[1], [inputs]Index[0]] + }{ + [conditions]For Backend + { + input name <- [[worker]Inputs >>]Index[ [node]Data >> ] + stream <- [[func]Instruction Stream + ]Move[input name, Result Var Name[0, node index]] + nfunc <- [func]Do If[~, stream] + }{ + nfunc <- Val[func] + } + } } } @@ -1225,7 +1267,7 @@ }{ If[[[worker]Library >>] = [""]] { - ifunc <- Fold[Set Output Type[?], Fold[Set Input Type[?], [program]Create Function[name,[worker]Inputs >>, [worker]Outputs >>, [worker]Convention >>], [worker]Input Types >>], [worker]Output Types >>] + ifunc <- Fold[Set Output Type[?], Fold[Set Input Type[?], [[program]Create Function[name,[worker]Inputs >>, [worker]Outputs >>, [worker]Convention >>]]Uses <<[[worker]Uses >>], [worker]Input Types >>], [worker]Output Types >>] groups <- [worker]Dependency Groups @@ -1450,15 +1492,17 @@ Workers Worker Refs Numtypes + Global Stores } NProgram[:out] { - out <- [[[[Build[NProgram()] + out <- [[[[[Build[NProgram()] ]Blueprints <<[Dictionary[]] ]Workers <<[Dictionary[]] ]Worker Refs <<[Dictionary[]] ]Numtypes << [("Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64")] + ]Global Stores <<[Dictionary[]] } Supported Number Types@NProgram[program:out] @@ -1507,7 +1551,7 @@ Compile Program@NProgram[prog, backend:out] { - backend with bps <- Generate Boolean Methods[Generate Number Methods[Fold[_Compile Program BP Special[?], Fold[_Compile Program BP[?], backend, [prog]Blueprints >>], [prog]Blueprints >>]]] + backend with bps <- Generate Boolean Methods[Generate Number Methods[Fold[_Compile Program BP Special[?], Fold[_Compile Program BP[?], [backend]Global Stores <<[[prog]Global Stores >>], [prog]Blueprints >>], [prog]Blueprints >>]]] workers with infer <- Map[[prog]Workers >>, Infer Types[?, prog]] out <- Fold[_Compile Program[?], backend with bps, workers with infer] } diff -r 1411de6050e1 -r a68e6828d896 parser_old_c.rhope --- a/parser_old_c.rhope Tue Nov 16 21:53:18 2010 -0500 +++ b/parser_old_c.rhope Fri Nov 19 04:04:14 2010 -0500 @@ -44,11 +44,12 @@ Hex Escape Escape Map Foreign + Globals } Parser[:out] { - out <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build[Parser()] + out <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build[Parser()] ]Arg Begin << ["["] ]Arg End <<["]"] ]Line Comment <<["//"] @@ -79,6 +80,7 @@ ]Uses <<["uses"] ]Escape Map <<[[[[Dictionary[]]Set["n","\n"]]Set["r","\r"]]Set["t","\t"]] ]Foreign <<["Foreign"] + ]Globals <<["Globals"] } Blueprint Output Reference @@ -124,23 +126,41 @@ ]Name <<[library] } +Blueprint Global Store +{ + Name + Vars +} + +Global Store[name:out] +{ + out <- [[Build[Global Store()]]Name <<[name]]Vars <<[Dictionary[]] +} + Blueprint Parse Program { Workers Imports Blueprints + Global Stores Errors } Parse Program[:out] { - out <- [[[[Build[Parse Program()] + out <- [[[[[Build[Parse Program()] ]Workers <<[Dictionary[]] ]Imports <<[Dictionary[]] ]Blueprints <<[Dictionary[]] + ]Global Stores <<[Dictionary[]] ]Errors <<[()] } +Add Global Store@Parse Program[tree,store:out] +{ + out <- [tree]Global Stores <<[ [[tree]Global Stores >>]Set[[store]Name >>, store] ] +} + Blueprint Blueprint Definition { Name @@ -1397,6 +1417,57 @@ } } +Parse Global Vars[string,params,store:out] +{ + trimmed <- Left Trim[string, "\r\n\t "] + If[trimmed] + { + ,,after <- [trimmed]Partition[[params]Assign >>] + { + varname <- Right Trim[~, "\r\n\t "] + } {} { + valstring <- [~]Partition["\n"] {} {} + { + out <- Parse Global Vars[~,params,next store] + }{ + valstring <- Val[after] + out <- Val[next store] + } + Val[valstring] + { + value <- [Named Pipe or Literal[Trim[~, "\r\n\t "], params]]Value >> + next store <- [store]Vars <<[ [[store]Vars >>]Set[varname, value] ] + } + } + }{ + out <- store + } +} + +Parse Globals[string,params,tree,lines:out] +{ + ,after globals <- [string]Slice[[[params]Globals >>]Length] + [after globals]Partition[[params]Block Begin >>] + { + store <- Global Store[Trim[~, "\r\n\t "]] + } {} { + + [~]Partition[[params]Block End >>] + { + next tree <- [tree]Add Global Store[Parse Global Vars[~, params, store]] + } {} { + out <- Null[~,params,next tree,lines] + }{ + Print["Error: Globals declaration missing block close symbol"] + out <- tree + } + } { + Print["Error: Globals declaration without block"] + out <- tree + } +} + + Null[string,params,tree,lines:out] { trimmed <- Comment Left Trim[string, " \n\r\t", params] @@ -1413,11 +1484,16 @@ { out <- Parse Foreign[trimmed, params, tree, current line] }{ - If[trimmed] + If[[trimmed]Starts With[[params]Globals >>]] { - out <- Worker Name[trimmed, params, tree, current line] + out <- Parse Globals[trimmed, params, tree, current line] }{ - out <- tree + If[trimmed] + { + out <- Worker Name[trimmed, params, tree, current line] + }{ + out <- tree + } } } } @@ -1483,7 +1559,7 @@ Tree to Program Native[parse tree,number types:out] { - registered <- Fold[Register Workers Compile[?], [Fold[Add Blueprint Compile[?], [NProgram[]]Numtypes <<[number types], [parse tree]Blueprints >>]]Register Builtins, [parse tree]Workers >>] + registered <- Fold[Register Workers Compile[?], [Fold[Add Blueprint Compile[?], [[NProgram[]]Numtypes <<[number types]]Global Stores <<[[parse tree]Global Stores >>], [parse tree]Blueprints >>]]Register Builtins, [parse tree]Workers >>] out <- Fold[Add Workers Compile[?], registered, [parse tree]Workers >>] { Print["Transformed AST to dataflow graph "] } } diff -r 1411de6050e1 -r a68e6828d896 runtime/builtin.h --- a/runtime/builtin.h Tue Nov 16 21:53:18 2010 -0500 +++ b/runtime/builtin.h Fri Nov 19 04:04:14 2010 -0500 @@ -25,6 +25,7 @@ TYPE_METHODMISSINGEXCEPTION, TYPE_FIELDMISSINGEXCEPTION, TYPE_WRONGTYPEEXCEPTION, + TYPE_MUTABLEGLOBAL, TYPE_FIRST_USER //Insert new builtin types before this one }; diff -r 1411de6050e1 -r a68e6828d896 runtime/context.c --- a/runtime/context.c Tue Nov 16 21:53:18 2010 -0500 +++ b/runtime/context.c Fri Nov 19 04:04:14 2010 -0500 @@ -18,6 +18,7 @@ context * c = malloc(sizeof(context)); c->stack_begin = new_stack(); c->current_stack = c->stack_begin; + c->transaction = NULL; return c; } diff -r 1411de6050e1 -r a68e6828d896 runtime/context.h --- a/runtime/context.h Tue Nov 16 21:53:18 2010 -0500 +++ b/runtime/context.h Fri Nov 19 04:04:14 2010 -0500 @@ -4,6 +4,7 @@ #include "thread.h" #include "plat_types.h" #include "func.h" +#include "transaction.h" #define STACK_CHUNK_SIZE 4096-(sizeof(struct stackchunk *)*2+sizeof(char *)) @@ -17,6 +18,7 @@ typedef struct context { stackchunk *stack_begin; stackchunk *current_stack; + transaction *transaction; } context; stackchunk * new_stack(); diff -r 1411de6050e1 -r a68e6828d896 runtime/object.c --- a/runtime/object.c Tue Nov 16 21:53:18 2010 -0500 +++ b/runtime/object.c Fri Nov 19 04:04:14 2010 -0500 @@ -338,6 +338,11 @@ return registered_types[type]; } +blueprint * register_type(int32_t size, special_func init, special_func copy, special_func cleanup) +{ + return register_type_byid(max_registered_type, size, init, copy, cleanup); +} + void add_method(blueprint * bp, uint32_t methodid, rhope_func impl) { rhope_func * temp; diff -r 1411de6050e1 -r a68e6828d896 runtime/object.h --- a/runtime/object.h Tue Nov 16 21:53:18 2010 -0500 +++ b/runtime/object.h Fri Nov 19 04:04:14 2010 -0500 @@ -78,6 +78,7 @@ multisize * new_multisize(uint32_t type, uint32_t size); void release_ref(object * obj); blueprint * register_type_byid(uint32_t type, int32_t size, special_func init, special_func copy, special_func cleanup); +blueprint * register_type(int32_t size, special_func init, special_func copy, special_func cleanup); blueprint * new_blueprint(uint32_t type, int32_t size, special_func init, special_func copy, special_func cleanup); void add_method(blueprint * bp, uint32_t methodid, rhope_func impl); void add_getter(blueprint * bp, uint32_t fieldid, rhope_func impl); diff -r 1411de6050e1 -r a68e6828d896 runtime/transaction.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime/transaction.c Fri Nov 19 04:04:14 2010 -0500 @@ -0,0 +1,255 @@ +#include "transaction.h" +#include +#include +#include + +rh_mutex(trans_lock) + +trans_cell * find_obj_cell(transaction * trans, mutable_object * to_find) +{ + int32_t idx; + while(trans) + { + for (idx = 0; idx < trans->num_cells; ++idx) + if (trans->cells[idx].obj = to_find) + return &(trans->cells[idx]); + trans = trans->chain; + } + return NULL; +} + +void begin_transaction(context * ct, int numobjs,...) +{ + mutable_object *obj; + transaction *parent; + va_list args; + int32_t idx,got_global_lock=0; + + parent = ct->transaction ? ct->transaction : NULL; + + ct->transaction = malloc(sizeof(transaction)+((numobjs-1)*sizeof(trans_cell))); + ct->transaction->parent = parent; + ct->transaction->chain = NULL; + rh_mutex_init(ct->lock); + ct->transaction->num_cells = numobjs; + va_start(args, numobjs); + if (parent) + { + rh_lock(parent->lock); + for (idx = 0; idx < numobjs; ++idx) + { + obj = va_arg(args, mutable_object *); + ct->transaction->cells[idx].obj = obj; + ct->transaction->cells[idx].parent = find_obj_cell(parent, obj); + if (ct->transaction->cells[idx].parent) + { + ct->transaction->cells[idx].local_data = ct->transaction->cells[idx].parent->local_data; + ct->transaction->cells[idx].orig_version = ct->transaction->cells[idx].parent->local_version; + } else { + if (!got_global_lock) + { + rh_lock(trans_lock); + got_global_lock = 1; + } + ct->transaction->cells[idx].local_data = obj->data; + ct->transaction->cells[idx].orig_version = obj->version; + } + ct->transaction->cells[idx].local_version = 0; + } + if (got_global_lock) + { + rh_unlock(trans_lock); + } + rh_unlock(parent->lock); + } else { + rh_lock(trans_lock); + for (idx = 0; idx < numobjs; ++idx) + { + obj = va_arg(args, mutable_object *); + ct->transaction->cells[idx].obj = obj; + ct->transaction->cells[idx].parent = NULL; + ct->transaction->cells[idx].local_data = add_ref(obj->data); + ct->transaction->cells[idx].orig_version = obj->version; + ct->transaction->cells[idx].local_version = 0; + } + rh_unlock(trans_lock); + } +} + +void free_trans(transaction * trans) +{ + if (trans) + { + free_trans(trans->chain); + free(trans); + } +} + +int32_t commit_transaction(context * ct, int32_t readonly) +{ + transaction *tmp_trans, *current; + object * tmp_obj; + int32_t idx,numaddparent; + + if (ct->transaction->parent) + { + rh_lock(ct->transaction->parent->lock); + current = ct->transaction; + while(current) + { + for (idx = 0; idx < current->num_cells; ++idx) + { + if (current->cells[idx].parent) + { + if (current->cells[idx].parent->local_version != current->cells[idx].orig_version) + { + rh_unlock(ct->transaction->parent->lock); + return 0; + } + } else { + if(find_obj_cell(ct->transaction->parent->chain, current->cells[idx].obj)) + { + rh_unlock(ct->transaction->parent->lock); + return 0; + } else + numaddparent++; + } + } + current = current->chain; + } + if (numaddparent) + { + tmp_trans = malloc(sizeof(transaction)+(numaddparent - 1)*sizeof(trans_cell)); + tmp_trans->chain = ct->transaction->parent->chain; + tmp_trans->num_cells = 0; + ct->transaction->parent->chain = tmp_trans; + } + current = ct->transaction; + while(current) + { + for (idx = 0; idx < ct->transaction->num_cells; ++idx) + { + if (ct->transaction->cells[idx].parent) + { + //Only commit a particular object if a change has been made + if (ct->transaction->cells[idx].local_version) + { + tmp_obj = ct->transaction->cells[idx].parent->local_data; + ct->transaction->cells[idx].parent->local_data = ct->transaction->cells[idx].local_data; + release_ref(tmp_obj); + ct->transaction->cells[idx].parent->local_version++; + } else { + release_ref(ct->transaction->cells[idx].local_data); + } + } else { + memcpy(&(tmp_trans->cells[tmp_trans->num_cells++]), &(ct->transaction->cells[idx]), sizeof(trans_cell)); + } + } + current = current->chain; + } + rh_unlock(ct->transaction->parent->lock); + } else { + if(readonly) + { + for (idx = 0; idx < ct->transaction->num_cells; ++idx) + { + release_ref(ct->transaction->cells[idx].local_data); + } + } else { + rh_lock(trans_lock); + current = ct->transaction; + while(current) + { + for (idx = 0; idx < current->num_cells; ++idx) + { + if (current->cells[idx].obj->version != current->cells[idx].orig_version) + { + rh_unlock(trans_lock); + return 0; + } + } + current = current->chain; + } + current = ct->transaction; + while(current) + { + for (idx = 0; idx < current->num_cells; ++idx) + { + //Only commit a particular object if a change has been made + if (current->cells[idx].local_version) + { + tmp_obj = current->cells[idx].obj->data; + current->cells[idx].obj->data = current->cells[idx].local_data; + release_ref(tmp_obj); + current->cells[idx].obj->version++; + } else { + release_ref(current->cells[idx].local_data); + } + } + current = current->chain; + } + rh_unlock(trans_lock); + } + } + rh_mutex_del(ct->transaction->lock); + tmp_trans = ct->transaction->parent; + free_trans(ct->transaction); + ct->transaction = tmp_trans; + return 1; +} + +void prep_retry(context * ct) +{ + transaction * current; + int32_t idx,got_global_lock=0; + if (ct->transaction->parent) + { + rh_lock(ct->transaction->parent->lock); + current = ct->transaction; + while(current) + { + for (idx = 0; idx < current->num_cells; ++idx) + { + release_ref(current->cells[idx].local_data); + current->cells[idx].local_version = 0; + if (!current->cells[idx].parent) + current->cells[idx].parent = find_obj_cell(ct->transaction->parent, current->cells[idx].obj); + if (current->cells[idx].parent) + { + current->cells[idx].local_data = current->cells[idx].parent->local_data; + current->cells[idx].orig_version = current->cells[idx].parent->local_version; + } else { + if (!got_global_lock) + { + rh_lock(trans_lock); + got_global_lock = 1; + } + current->cells[idx].local_data = current->cells[idx].obj->data; + current->cells[idx].orig_version = current->cells[idx].obj->version; + } + } + current = current->chain; + } + if (got_global_lock) + { + rh_unlock(trans_lock); + } + rh_unlock(ct->transaction->parent->lock); + } else { + rh_lock(trans_lock); + current = ct->transaction; + while(current) + { + for (idx = 0; idx < current->num_cells; ++idx) + { + release_ref(current->cells[idx].local_data); + current->cells[idx].local_version = 0; + current->cells[idx].local_data = current->cells[idx].obj->data; + current->cells[idx].orig_version = current->cells[idx].obj->version; + } + current = current->chain; + } + rh_unlock(trans_lock); + } +} + diff -r 1411de6050e1 -r a68e6828d896 runtime/transaction.h --- a/runtime/transaction.h Tue Nov 16 21:53:18 2010 -0500 +++ b/runtime/transaction.h Fri Nov 19 04:04:14 2010 -0500 @@ -1,7 +1,8 @@ -#ifndef THREAD_H_ -#define THREAD_H_ +#ifndef TRANSACTION_H_ +#define TRANSACTION_H_ #include "object.h" +#include "thread.h" typedef struct { @@ -10,12 +11,13 @@ int32_t version; } mutable_object; -typedef struct +typedef struct trans_cell { - mutable_object *obj; - object **commit_loc; - int32_t orig_version; - int32_t local_version; + mutable_object *obj; + struct trans_cell *parent; + object *local_data; + int32_t orig_version; + int32_t local_version; } trans_cell; @@ -23,8 +25,16 @@ { struct transaction *parent; rh_mutex(lock) + struct transaction *chain; int32_t num_cells; - trans_cell[1] cells; + trans_cell cells[1]; } transaction; -#endif //THREAD_H_ +#include "context.h" + +trans_cell * find_obj_cell(transaction * trans, mutable_object * to_find); +void begin_transaction(struct context * ct, int numobjs,...); +int32_t commit_transaction(struct context * ct, int32_t readonly); +void prep_retry(struct context * ct); + +#endif //TRANSACTION_H_ diff -r 1411de6050e1 -r a68e6828d896 testglobal.rhope --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testglobal.rhope Fri Nov 19 04:04:14 2010 -0500 @@ -0,0 +1,22 @@ + +Globals Increment +{ + Num <- 0 +} + +Do Incr[:out] uses Increment +{ + out <- Increment::Num + Increment::Num <- [Increment::Num]+[1] +} + +Main[:out] +{ + Do Incr[] + { Print[~] + { Do Incr[] + { Print[~] + { Do Incr[] + { out <- Print[~] }}}}} +} +