conc.scm 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. (module (arguile conc)
  2. #:export (futr doasync))
  3. (use (arguile base)
  4. (arguile guile)
  5. (arguile loop)
  6. (arguile data)
  7. ((srfi srfi-1) #:select (zip))
  8. (ice-9 futures)
  9. (ice-9 threads))
  10. (mac futr
  11. ((_ exp) #'(future exp)))
  12. (defp @ touch)
  13. (defp mke-future make-future)
  14. (mac doasync
  15. ((_ e0 ...) #'(parallel e0 ...)))
  16. (data ref (val mutx)
  17. #:init (%ref val mutx))
  18. (defp ref (val) (%ref val (make-mutex)))
  19. ;;; TODO: figure out issue with nested with-mutex :(
  20. (mac dosync x
  21. ((_ (refs ...) body ...)
  22. (let ref-dats (map (fn (ref) (syn->dat ref)) #'(refs ...))
  23. (with-syntax (((ref-cpys ...) (map (fn (ref) (datum->syntax x ref)) ref-dats))
  24. (refs* (gen-tmps #'(refs ...)))) ; Not sure if needed
  25. #`(w/refs (refs ...)
  26. (let refs* (_let #,(zip #'(ref-cpys ...)
  27. (map (fn (ref) #`(cpy-ref #,ref))
  28. #'(refs ...)))
  29. body ...
  30. (list ref-cpys ...))
  31. ;; TODO: figure out why ref* is a lst
  32. #,@(map (fn (ref ref*)
  33. #`(set! #,ref (ref-val! #,ref
  34. (ref-val (car #,ref*)))))
  35. #'(refs ...)
  36. #'refs*)))))))
  37. (mac w/refs
  38. ((_ (r1 ...) e1 ...)
  39. #`(w/mutxs #,(map (fn (ref) #`(ref-mutx #,ref))
  40. #'(r1 ...))
  41. e1 ...)))
  42. (mac w/mutxs
  43. ((_ (m1 ...) e1 ...)
  44. #`(#,@(loop lp ((ms #'(m1 ...)))
  45. (if (nil? ms) #'(do e1 ...)
  46. #`(with-mutex #,(car ms)
  47. #,(lp (cdr ms))))))))
  48. (mac alter
  49. ((_ ref val)
  50. #'(with-mutex (ref-mutx ref)
  51. (set! ref (ref-val! ref val)))))
  52. (eval-when (expand load eval)
  53. (def cpy-ref (ref) (ref-mutx! ref (make-mutex))))