[Shootout-list] Haskell killer prodcons implementation - fair?
Raymond Racine
rracine@adelphia.net
Sun, 03 Oct 2004 01:49:47 -0400
--=-TaOqzEFh5ApALIqxPPPq
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
On Sat, 2004-10-02 at 19:46, Brent Fulgham wrote:
> It seems fair. The MVar construct provides the concurrency
> synchronization
> we need to verify that one "thread" is not reading the value at the
> same time
> the other is writing to the buffer.
SML has a (unoffical) standard for concurrency as well, CML.
See http://cml.cs.uchicago.edu/
It should work for both SML/NJ and MLton. I only tested MLton however.
The MLton port of CML is fairly new and may or may not be available
depending on what version of MLton you have. The new prodcon.sml
version is smaller, easier to understand and I believe faster. (Can't
confirm because the current prodcon.sml will not compile. I believe the
thread sig has changed in the lastest CVS head for MLton.)
BTW I think the latest Haskell version is hand waving the
consumer/producer count/increment requirement a tad. Though I agree the
mVar approach itself is fair.
Ray
--=-TaOqzEFh5ApALIqxPPPq
Content-Disposition: attachment; filename=prodcon.mlb
Content-Type: text/plain; name=prodcon.mlb; charset=UTF-8
Content-Transfer-Encoding: 7bit
$(MLTON_ROOT)/basis/basis.mlb
$(MLTON_ROOT)/cml/cml.mlb
local
prodcon.sml
in
structure Main
end
--=-TaOqzEFh5ApALIqxPPPq
Content-Disposition: attachment; filename=prodcon.sml
Content-Type: application/x-smil; name=prodcon.sml
Content-Transfer-Encoding: 7bit
(* See conccurnt CML library for SML
http://cml.cs.uchicago.edu/ *)
structure Main =
struct
val consumed = ref 0
val produced = ref 0
fun cinc() = consumed := !consumed + 1
fun pinc() = produced := !produced + 1
fun consumer (chan,n) = CML.spawn (fn () => while !consumed < n do (CML.recv chan; cinc()))
fun producer (chan,n) = CML.spawn (fn () => while !produced < n do (CML.send (chan,!produced); pinc()))
fun doit n = let fun run () = let val chan = CML.channel()
val ctid = consumer (chan,n)
val ptid = producer (chan,n)
in
CML.sync (CML.joinEvt ctid);
RunCML.shutdown OS.Process.success
end
in
RunCML.doit (run, NONE);
print (Int.toString (!consumed) ^ " " ^ Int.toString (!produced))
end
end
val _ = let val arg0 = List.hd (CommandLine.arguments())
in
Main.doit (Option.getOpt (Int.fromString arg0,0))
end
--=-TaOqzEFh5ApALIqxPPPq--