;;;--------------------------------- (define (parallel-execute . args) (map thread args)) (define (make-serializer) (let ((mutex (make-mutex))) (lambda (p) (define (serialized-p . args) (mutex 'acquire) (let ((value (apply p args))) (mutex 'release) value)) serialized-p))) (define (make-mutex) (let ((cell (make-semaphore 1))) (define (the-mutex m) (cond ((eq? m 'acquire) (semaphore-wait cell)) ((eq? m 'release) (semaphore-post cell)))) the-mutex)) ;;;------------------------------------------------ (define *SEATS* 100) (define *SEATS-SOLD* 0) ;;; DO NOT MODIFY THIS PROCEDURE (define (customer-order) (sleep (random 1)) ;customer thinks for a while 1 ;and then says "I'll take one ticket, please" ) (define (make-ticket-seller) (let ((total-tickets-sold 0)) (define (sell) (sleep (random 2)) ;sleep randomly until customer arrives (if (> *SEATS* 0) (begin (set! *SEATS* (- *SEATS* (customer-order))) ;sell a ticket and recurse (set! total-tickets-sold (+ total-tickets-sold (customer-order))) (sell)) (begin (set! *SEATS-SOLD* (+ *SEATS-SOLD* total-tickets-sold)) (print-tickets-sold total-tickets-sold *SEATS-SOLD*) ) )) sell)) (define (print-tickets-sold n m) (display "I sold ") (display n) (display " tickets out of ") (sleep 0) ; DO NOT REMOVE THIS LINE FOR FULL CREDIT. (display m) (display " total reported so far") (newline)) (define (test) (parallel-execute (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller))) (define (test25) (parallel-execute (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller) (make-ticket-seller))) ;;;------------------------------------------------------------- ;;; STREAMS (define (stream-car stream) (car stream)) (define (stream-cdr stream) (force (cdr stream))) (define-macro cons-stream (lambda (a b) `(cons ,a (delay ,b)))) (define stream-null? null?) (define the-empty-stream null) (define (stream-ref s n) (if (= n 0) (stream-car s) (stream-ref (stream-cdr s) (- n 1)))) (define (stream-map proc s) (if (stream-null? s) the-empty-stream (cons-stream (proc (stream-car s)) (stream-map proc (stream-cdr s))))) (define (stream-for-each proc s) (if (stream-null? s) 'done (begin (proc (stream-car s)) (stream-for-each proc (stream-cdr s))))) (define (stream-enumerate-interval low high) (if (> low high) the-empty-stream (cons-stream low (stream-enumerate-interval (+ low 1) high)))) (define (stream-filter pred stream) (cond ((stream-null? stream) the-empty-stream) ((pred (stream-car stream)) (cons-stream (stream-car stream) (stream-filter pred (stream-cdr stream)))) (else (stream-filter pred (stream-cdr stream))))) ;;; Printing STREAMS (define (display-stream s) (stream-for-each display-line s)) (define (display-line x) (newline) (display x)) (define display-stream-2 (let () (define (iter stream) (if (stream-null? stream) (display "]") (begin (display (stream-car stream)) (display " ") (iter (stream-cdr stream))))) (lambda (stream) (display "[") (iter stream)))) ;;Useful for looking at finite amounts of infinite streams ;;Print the first n elements of the stream s. ;;One version prints on one line, one on separate lines (define (stream-print-n s n) (if (> n 0) (begin (display (stream-car s)) (display ",") (stream-print-n (stream-cdr s) (- n 1))))) (define (stream-print-n-seperate s n) (if (> n 0) (begin (newline) (display (stream-car s)) (stream-print-n-seperate (stream-cdr s) (- n 1))))) ;;; Some useful testing functions (define (tty-stream) (cons-stream (read) (tty-stream)))