Advertisement
Guest User

Untitled

a guest
Jan 20th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.01 KB | None | 0 0
  1.  
  2.  
  3. ;; (THREADTEST2 ..) launches some threads that don't generate garbage.
  4. ;; it demonstrates that locks don't get held (are grabbed by another thread)
  5. ;;
  6. ;; tested on raspberri pi armcl dev version:
  7. ;; * "Version 1.12-dev (v1.12-dev.4-3-gdd5622e9) LinuxARM32"
  8.  
  9. ;; with
  10. ;; (threadtest2 :exercise-locking nil)
  11. ;; and nothing happens, and threads run fine.
  12.  
  13. ;; with
  14. ;; (threadtest2 :exercise-locking t)
  15. ;; the error
  16. ;;
  17. ;;ERR2 - current proc #<PROCESS Threadtest 4(63) [Active] #x14F93B76> doesn't own lock #<RECURSIVE-LOCK "glock" [ptr @ #x76105480] #x14F8FB26>, which is owned by #<PROCESS Threadtest 1(60) [Sleep] #x14F8F496>
  18. ;;
  19. ;; is generated, indicated that a thread detected that a lock it owned was stolen
  20. ;; by another thread
  21.  
  22.  
  23. (defparameter *the-glock* nil) ;; allow us to look at lock while running
  24. (defun threadtest2 (&key
  25. (thread-count 7)
  26. (loop-count 1000)
  27. ;; test locking in the threads
  28. (exercise-locking t)
  29. (count 1000))
  30. (let ((done-flags (make-array thread-count :initial-element nil))
  31. (lock (ccl:make-lock "done-flags-lock"))
  32. (glock (when exercise-locking
  33. (ccl:make-lock "glock"))))
  34. (setf *the-glock* glock)
  35. (dotimes (i thread-count)
  36. (process-run-function
  37. (format nil "Threadtest ~d" i)
  38. (lambda (i)
  39. (unwind-protect
  40. (dotimes (j loop-count)
  41. (threadfunc count glock)
  42. ))
  43. (ccl:with-lock-grabbed (lock) (setf (elt done-flags i) t)))
  44. i))
  45. (loop do
  46. (unless
  47. (ccl:with-lock-grabbed (lock)
  48. (position nil done-flags))
  49. (return)))))
  50.  
  51. ;; see https://lists.clozure.com/pipermail/openmcl-devel/2011-July/008664.html
  52. (defun recursive-lock-owner (lock)
  53. (let* ((tcr (ccl::%get-object (ccl::recursive-lock-ptr lock)
  54. target::lockptr.owner)))
  55. (unless (eql 0 tcr) (ccl::tcr->process tcr))))
  56.  
  57.  
  58. ;; a duplicate of ccl's with-lock-grabbed macro, with extra
  59. ;; code to check that the lock owner hasn't changed while lock is held
  60. (defmacro with-lock ((the-lock) &body body)
  61. `(let ((lacq (make-lock-acquisition))
  62. (lock ,the-lock))
  63. (progn (ccl::%lock-recursive-lock-object
  64. lock lacq)
  65. ;; do a pre-check that owner is OK
  66. (let ((owner (recursive-lock-owner lock)))
  67. (unless (eq owner *current-process*)
  68. (error "ERR1 - current proc ~A doesn't own lock ~A, which is owned by ~A"
  69. *current-process* lock owner)))
  70. (progn ,@body)
  71. ;; do a post-check that owner is OK
  72. (let ((owner (recursive-lock-owner lock)))
  73. (unless (eq owner *current-process*)
  74. (error "ERR2 - current proc ~A doesn't own lock ~A, which is owned by ~A"
  75. *current-process* lock owner)))
  76. (when (ccl::lock-acquisition.status lacq)
  77. (release-lock lock)))))
  78.  
  79.  
  80.  
  81.  
  82. ;; locking in threads -- just sleep, with no garbage generation
  83. (defun threadfunc (count lock)
  84. (loop for i below count
  85. collect (cond (lock ;; using normal locking
  86. (with-lock (lock)
  87. (sleep 0.000001)))
  88. (t ;; no locks
  89. (sleep 0.000001)))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement