comparison src/sqlcache.sml @ 2288:98f96a976ede

Finish locking, but it's not yet tested rigorously.
author Ziv Scully <ziv@mit.edu>
date Fri, 13 Nov 2015 11:03:09 -0500
parents 0bdfec16a01d
children 78820fa8f5a7
comparison
equal deleted inserted replaced
2287:08203f93dbc3 2288:98f96a976ede
911 911
912 (*************************************) 912 (*************************************)
913 (* Program Instrumentation Utilities *) 913 (* Program Instrumentation Utilities *)
914 (*************************************) 914 (*************************************)
915 915
916 val {check, store, flush, ...} = getCache () 916 val {check, store, flush, lock, ...} = getCache ()
917 917
918 val dummyTyp = (TRecord [], dummyLoc) 918 val dummyTyp = (TRecord [], dummyLoc)
919 919
920 fun stringExp s = (EPrim (Prim.String (Prim.Normal, s)), dummyLoc) 920 fun stringExp s = (EPrim (Prim.String (Prim.Normal, s)), dummyLoc)
921 921
1429 1429
1430 (***********) 1430 (***********)
1431 (* Locking *) 1431 (* Locking *)
1432 (***********) 1432 (***********)
1433 1433
1434 (* TODO: do this less evil-ly by not relying on specific FFI names, please? *) 1434 (* TODO: do this less evilly by not relying on specific FFI names, please? *)
1435 fun locksNeeded file = 1435 fun locksNeeded file =
1436 transitiveAnalysis 1436 transitiveAnalysis
1437 (fn ((_, name, _, e, _), state) => 1437 (fn ((_, name, _, e, _), state) =>
1438 MonoUtil.Exp.fold 1438 MonoUtil.Exp.fold
1439 {typ = #2, 1439 {typ = #2,
1440 exp = fn (EFfiApp ("Sqlcache", x, _), state as {store, flush}) => 1440 exp = fn (EFfiApp ("Sqlcache", x, _), state as {store, flush}) =>
1441 (case Int.fromString (String.extract (x, 5, NONE)) of 1441 (case Int.fromString (String.extract (x, 5, NONE)) of
1442 NONE => raise Match 1442 NONE => state
1443 | SOME index => 1443 | SOME index =>
1444 if String.isPrefix "store" x 1444 if String.isPrefix "flush" x
1445 then {store = store, flush = IIMM.insert (flush, name, index)}
1446 else if String.isPrefix "store" x
1445 then {store = IIMM.insert (store, name, index), flush = flush} 1447 then {store = IIMM.insert (store, name, index), flush = flush}
1446 else if String.isPrefix "flush" x
1447 then {store = store, flush = IIMM.insert (flush, name, index)}
1448 else state) 1448 else state)
1449 | _ => state} 1449 | (_, state) => state}
1450 state 1450 state
1451 e) 1451 e)
1452 {store = IIMM.empty, flush = IIMM.empty} 1452 {store = IIMM.empty, flush = IIMM.empty}
1453 file 1453 file
1454 1454
1457 | ((DTask _, _), _) => raise Fail "Sqlcache doesn't yet support tasks." 1457 | ((DTask _, _), _) => raise Fail "Sqlcache doesn't yet support tasks."
1458 | (_, ns) => ns) 1458 | (_, ns) => ns)
1459 IS.empty 1459 IS.empty
1460 decls 1460 decls
1461 1461
1462 (* fun addLocking file = *) 1462 fun wrapLocks (locks, (exp', loc)) =
1463 (* let *) 1463 case exp' of
1464 (* val whichLocks = locksNeeded file *) 1464 EAbs (s, t1, t2, exp) => (EAbs (s, t1, t2, wrapLocks (locks, exp)), loc)
1465 (* val needsLocks = exports file *) 1465 | _ => (List.foldr (fn (l, e') => sequence [lock l, e']) exp' locks, loc)
1466 (* in *) 1466
1467 1467 fun addLocking file =
1468 (* end *) 1468 let
1469 val {store, flush} = locksNeeded file
1470 fun locks n =
1471 let
1472 val wlocks = IIMM.findSet (flush, n)
1473 val rlocks = IIMM.findSet (store, n)
1474 val ls = map (fn i => (i, true)) (IS.listItems wlocks)
1475 @ map (fn i => (i, false)) (IS.listItems (IS.difference (rlocks, wlocks)))
1476 in
1477 ListMergeSort.sort (fn ((i, _), (j, _)) => i > j) ls
1478 end
1479 val expts = exports file
1480 fun doVal (v as (x, n, t, exp, s)) =
1481 if IS.member (expts, n)
1482 then (x, n, t, wrapLocks ((locks n), exp), s)
1483 else v
1484 val doDecl =
1485 fn (DVal v, loc) => (DVal (doVal v), loc)
1486 | (DValRec vs, loc) => (DValRec (map doVal vs), loc)
1487 | decl => decl
1488 in
1489 mapFst (map doDecl) file
1490 end
1491
1469 1492
1470 (************************) 1493 (************************)
1471 (* Compiler Entry Point *) 1494 (* Compiler Entry Point *)
1472 (************************) 1495 (************************)
1473 1496
1492 val (datatypes, others) = List.partition (fn (DDatatype _, _) => true | _ => false) decls 1515 val (datatypes, others) = List.partition (fn (DDatatype _, _) => true | _ => false) decls
1493 in 1516 in
1494 (datatypes @ newDecls @ others, sideInfo) 1517 (datatypes @ newDecls @ others, sideInfo)
1495 end 1518 end
1496 1519
1497 val go' = addFlushing o addCaching o simplifySql o inlineSql 1520 val go' = addLocking o addFlushing o addCaching o simplifySql o inlineSql
1498 1521
1499 fun go file = 1522 fun go file =
1500 let 1523 let
1501 (* TODO: do something nicer than [Sql] being in one of two modes. *) 1524 (* TODO: do something nicer than [Sql] being in one of two modes. *)
1502 val () = (resetFfiInfo (); Sql.sqlcacheMode := true) 1525 val () = (resetFfiInfo (); Sql.sqlcacheMode := true)