File: io-mmap.lisp

package info (click to toggle)
acl2 8.6%2Bdfsg-2
  • links: PTS
  • area: main
  • in suites: trixie
  • size: 1,111,420 kB
  • sloc: lisp: 17,818,294; java: 125,359; python: 28,122; javascript: 23,458; cpp: 18,851; ansic: 11,569; perl: 7,678; xml: 5,591; sh: 3,976; makefile: 3,833; ruby: 2,633; yacc: 1,126; ml: 763; awk: 295; csh: 233; lex: 197; php: 178; tcl: 49; asm: 23; haskell: 17
file content (115 lines) | stat: -rw-r--r-- 5,591 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
(in-package #:3bz)
;; we restrict size of these types a bit more on 64 bit platforms to
;; ensure intermediate results stay in reasonable range for
;; performance. 32bit probably needs tuned, might want to allow larger
;; than fixnum offsets for FFI use with implementations with small
;; fixnums?
(deftype size-t () (if (= 8 (cffi:foreign-type-size :pointer))
                       `(unsigned-byte
                         ,(min 60 (1- (integer-length most-positive-fixnum))))
                       `(unsigned-byte
                         ,(min 30 (integer-length most-positive-fixnum)))))
;; slightly larger so incrementing a size-t still fits
(deftype offset-t () (if (= 8 (cffi:foreign-type-size :pointer))
                         `(unsigned-byte
                           ,(min 61 (integer-length most-positive-fixnum)))
                         `(unsigned-byte
                           ,(min 31 (integer-length most-positive-fixnum)))))



(defclass octet-pointer ()
  ((base :reader base :initarg :base)
   (size :reader size :initarg :size) ;; end?
   (scope :reader scope :initarg :scope)))

(defmacro with-octet-pointer ((var pointer size) &body body)
  (with-gensyms (scope)
    (once-only (pointer size)
     `(let* ((,scope (cons t ',var)))
        (unwind-protect
             (let ((,var (make-instance 'octet-pointer :base ,pointer
                                                       :size ,size
                                                       :scope ,scope)))
               ,@body)
          (setf (car ,scope) nil))))))

(defun valid-octet-pointer (op)
  (and (car (scope op))
       (not (cffi:null-pointer-p (base op)))
       (plusp (size op))))

(defclass octet-pointer-context ()
  ((op :reader op :initarg :op)
   (pointer :reader %pointer :initarg :pointer)
   (boxes :reader boxes :initarg :boxes)))

(defun make-octet-pointer-context (octet-pointer
                                   &key (start 0) (offset 0)
                                     (end (size octet-pointer)))
  (make-instance 'octet-pointer-context
                 :op octet-pointer
                 :pointer (base octet-pointer)
                 :boxes (make-context-boxes
                         :start start :offset offset :end end)))


(defmacro with-pointer-context ((context) &body body)
  (with-gensyms (boxes pointer)
    (once-only (context)
      `(let* ((,boxes (boxes ,context))
              (,pointer (base (op ,context))))
         (declare (optimize speed)
                  (ignorable ,pointer ,boxes)
                  (type context-boxes ,boxes))
         (assert (valid-octet-pointer (op ,context)))
         (context-common (,boxes)
           (macrolet ((word64 ()
                        (with-gensyms (available result)
                          `(let ((,available (octets-left)))
                             (if (>= ,available 8)
                                 (let ((,result (cffi:mem-ref
                                                 ,',pointer :uint64 (pos))))
                                   (incf (pos) 8)
                                   (values ,result 8))
                                 (let ((,result 0))
                                   (declare (type (unsigned-byte 64) ,result))
                                   (loop
                                     for i fixnum below (min 8 ,available)
                                     do (setf ,result
                                              (ldb (byte 64 0)
                                                   (logior
                                                    ,result
                                                    (ash
                                                     (cffi:mem-ref
                                                      ,',pointer
                                                      :uint8
                                                      (+ (pos) i))
                                                     (* i 8))))))
                                   (incf (pos) ,available)
                                   (values ,result ,available))))))
                      (word32 ()
                        (with-gensyms (available result)
                          `(let ((,available (octets-left)))
                             (if (>= ,available 4)
                                 (let ((,result (cffi:mem-ref
                                                 ,',pointer :uint32 (pos))))
                                   (incf (pos) 4)
                                   (values ,result 4))
                                 (let ((,result 0))
                                   (declare (type (unsigned-byte 32) ,result))
                                   (loop
                                     for i of-type (unsigned-byte 2) below (min 4 ,available)
                                     do (setf ,result
                                              (ldb (byte 32 0)
                                                   (logior
                                                    ,result
                                                    (ash
                                                     (cffi:mem-ref
                                                      ,',pointer
                                                      :uint8
                                                      (+ (pos) i))
                                                     (* i 8))))))
                                   (incf (pos) ,available)
                                   (values ,result ,available)))))))
             ,@body))))))