|
|
@@ -69,66 +69,80 @@
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;; Experimental multi-thread code below ;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
-(defparameter *channel* nil)
|
|
|
-(defparameter *dead-channel* nil)
|
|
|
(defparameter *END-THREAD* #xdeadbeef)
|
|
|
(defparameter *MAX-THREADS* 4)
|
|
|
|
|
|
+(defstruct chanl-results
|
|
|
+ name
|
|
|
+ mp3-count
|
|
|
+ mp4-count
|
|
|
+ other-count)
|
|
|
+
|
|
|
(defun mp-do-audio-dir (&optional (dir "Queen") &key (file-system-encoding :utf-8)
|
|
|
(mp3-func #'mp3-tag:show-tags)
|
|
|
(mp4-func #'mp4-tag:show-tags))
|
|
|
"Walk :DIR and FUNCALL specified function for each file (MP4/MP3) found."
|
|
|
(set-pathname-encoding file-system-encoding)
|
|
|
- (let ((mp3-count 0)
|
|
|
+ (let ((channel (make-instance 'chanl:unbounded-channel))
|
|
|
+ (dead-channel (make-instance 'chanl:unbounded-channel))
|
|
|
+ (mp3-count 0)
|
|
|
(mp4-count 0)
|
|
|
(other-count 0))
|
|
|
-
|
|
|
- (setf *channel* (make-instance 'chanl:unbounded-channel))
|
|
|
- (setf *dead-channel* (make-instance 'chanl:unbounded-channel))
|
|
|
-
|
|
|
(labels ((thread-reader ()
|
|
|
- (let ((me (chanl:thread-name (chanl:current-thread)))
|
|
|
- (f))
|
|
|
- ;(format t "Thread ~a starting~%" me)
|
|
|
+ (declare (special *me*))
|
|
|
+ (let ((f)
|
|
|
+ (results (make-chanl-results :name *me* :mp3-count 0 :mp4-count 0 :other-count 0)))
|
|
|
(loop
|
|
|
- (setf f (chanl:recv *channel*))
|
|
|
- ;(format t "Thread ~a read: ~a~%" me f)
|
|
|
- (when (and (typep f 'integer)
|
|
|
- (= f *END-THREAD*))
|
|
|
- ;(format t "Thread ~a exiting~%" me)
|
|
|
- (chanl:send *dead-channel* me)
|
|
|
- (return-from thread-reader nil))
|
|
|
- (do-audio-file f)))))
|
|
|
+ (with-slots (name mp3-count mp4-count other-count) results
|
|
|
+ (setf f (chanl:recv channel))
|
|
|
+ (when (and (typep f 'integer)
|
|
|
+ (= f *END-THREAD*))
|
|
|
+ (chanl:send dead-channel results)
|
|
|
+ (return-from thread-reader nil))
|
|
|
+
|
|
|
+ (do-audio-file f :func (lambda (s)
|
|
|
+ (cond ((typep s 'mp3-file-stream)
|
|
|
+ (incf mp3-count)
|
|
|
+ (when mp3-func (funcall mp3-func s)))
|
|
|
+ ((typep s 'mp4-file-stream)
|
|
|
+ (incf mp4-count)
|
|
|
+ (when mp4-func (funcall mp4-func s)))
|
|
|
+ ((null s) (incf other-count))))))))))
|
|
|
|
|
|
(cl-fad:walk-directory dir (lambda (f)
|
|
|
- (chanl:send *channel* f)))
|
|
|
+ (chanl:send channel f)))
|
|
|
+
|
|
|
(dotimes (i *MAX-THREADS*)
|
|
|
- (chanl:send *channel* *END-THREAD*))
|
|
|
+ (chanl:send channel *END-THREAD*))
|
|
|
(dotimes (i *MAX-THREADS*)
|
|
|
- (chanl:pcall #'thread-reader :name (format nil "reader-thread-~d" i)))
|
|
|
+ (chanl:pcall #'thread-reader :initial-bindings `((*me* ,(format nil "reader-thread-~d" i)))))
|
|
|
+
|
|
|
(block thread-reap
|
|
|
- (let ((i 0))
|
|
|
+ (let ((i 0)
|
|
|
+ results)
|
|
|
+
|
|
|
+ (format t "Waiting on ~d threads~%" *MAX-THREADS*)
|
|
|
(loop
|
|
|
- (format t "Waiting on ~d threads~%" *MAX-THREADS*)
|
|
|
- (format t "~a died~%" (chanl:recv *dead-channel*))
|
|
|
+ (force-output *standard-output*)
|
|
|
+ (setf results (chanl:recv dead-channel))
|
|
|
+ (format t "~4t~a died, ~:d MP3s, ~:d MP4s, ~:d Others~%"
|
|
|
+ (chanl-results-name results)
|
|
|
+ (chanl-results-mp3-count results)
|
|
|
+ (chanl-results-mp4-count results)
|
|
|
+ (chanl-results-other-count results))
|
|
|
+ (force-output *standard-output*)
|
|
|
+
|
|
|
+ (incf mp3-count (chanl-results-mp3-count results))
|
|
|
+ (incf mp4-count (chanl-results-mp4-count results))
|
|
|
+ (incf other-count (chanl-results-other-count results))
|
|
|
(incf i)
|
|
|
(when (= i *MAX-THREADS*)
|
|
|
(return-from thread-reap *MAX-THREADS*)))))
|
|
|
- (format t "All threads done~%"))))
|
|
|
-
|
|
|
- ;; (do-audio-file f :func (lambda (s)
|
|
|
- ;; (cond ((typep s 'mp3-file-stream)
|
|
|
- ;; (incf mp3-count)
|
|
|
- ;; (when mp3-func
|
|
|
- ;; (funcall mp3-func s)))
|
|
|
- ;; ((typep s 'mp4-file-stream)
|
|
|
- ;; (incf mp4-count)
|
|
|
- ;; (when mp4-func
|
|
|
- ;; (funcall mp4-func s)))
|
|
|
- ;; ((null s) (incf other-count)))))))
|
|
|
-
|
|
|
- ;; (format t "~&~:d MP3s, ~:d MP4s, ~:d Others, for a total of ~:d~%"
|
|
|
- ;; mp3-count mp4-count other-count (+ mp3-count mp4-count other-count))))
|
|
|
+
|
|
|
+ (format t "All threads done~%")
|
|
|
+ (format t "~&~:d MP3s, ~:d MP4s, ~:d Others, for a total of ~:d~%"
|
|
|
+ mp3-count mp4-count other-count (+ mp3-count mp4-count other-count)))))
|
|
|
+
|
|
|
(defun mp-time-test (&optional (dir "Queen") &key (file-system-encoding :utf-8) (do-audio-processing t))
|
|
|
"Time parsing of DIR."
|
|
|
(let ((audio-streams:*get-audio-info* do-audio-processing))
|