-
Notifications
You must be signed in to change notification settings - Fork 8
/
mmap-struct.lisp
149 lines (95 loc) · 4.02 KB
/
mmap-struct.lisp
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
;;;;; -*- mode: common-lisp; common-lisp-style: modern; coding: utf-8; -*-
;;;;;
(in-package :mm)
(defun compute-default-location-for-store ()
(ensure-directories-exist
(merge-pathnames #p".mm/" (user-homedir-pathname)) :verbose t))
(defvar *mmap-pathname-defaults*)
(defvar *mmap-base-pathname*)
(defvar *mmap-sharing* osicat-posix:MAP-SHARED)
(defvar *mmap-protection* (logior osicat-posix:PROT-READ osicat-posix:PROT-WRITE))
(defvar *mmap-may-allocate* t
"If this is not true, and an attempt is made to extend a memory
mapped region, an error will be signalled.")
(setf (documentation '*mmap-base-pathname* 'variable)
"The base path in which the datastore files are to be found.")
(deftype mptr ()
"A representation of a location in the memory mapped datastore.
Remains constant across remappings of the memory mapped regions to
different offsets in physical memory."
`(unsigned-byte ,+mptr-bits+))
(deftype mtag ()
`(unsigned-byte ,+mtag-bits+))
(deftype mindex ()
`(unsigned-byte ,+mindex-bits+))
(deftype machine-pointer ()
(type-of (cffi:null-pointer))
#+allegro (progn `(unsigned-byte 32) #+64bit `(unsigned-byte 64)))
(defun stored-cffi-type (type)
(let ((cffi-type
(alexandria:switch (type :test 'subtypep)
('(unsigned-byte 8) :unsigned-char)
('(unsigned-byte 64) :unsigned-long-long)
('(signed-byte 64) :long-long)
('single-float :float)
('double-float :double))))
cffi-type))
(defun stored-type-size (type)
(cffi:foreign-type-size (or (stored-cffi-type type) (stored-cffi-type 'mptr))))
(defmacro d (machine-pointer &optional (index 0) (type '(unsigned-byte 8)))
`(cffi:mem-aref ,machine-pointer ,(stored-cffi-type type) ,index))
(defmacro dw (machine-pointer &optional (index 0))
`(d ,machine-pointer ,index mptr))
(defun mptr-tag (mptr)
(declare (type mptr mptr))
(the mtag (logand mptr (1- (ash 1 +mtag-bits+))))) ; Allegro 8.1 is too stupid to optimize ldb
(declaim (ftype (function (mptr) (mindex)) mptr-index))
(defun mptr-index (mptr)
(declare (type mptr mptr))
(the mindex (ash mptr (- +mtag-bits+))))
(declaim (ftype (function (mtag mindex) mptr) make-mptr))
(defun make-mptr (tag index)
(declare (type mtag tag) (type mindex index))
(the mptr (logior (ash index +mtag-bits+) tag)))
(deftype mm-instantiator ()
`(function (mindex) t)
#+allegro `function) ;; Allegro 8.1 bug with function type specifiers and `the'
(deftype mm-walk-func ()
`(function (mptr mptr mindex) t)
#+allegro `function) ;; Allegro 8.1 bug with function type specifiers and `the'
(declaim (inline mtagmap-ptr mtagmap-len mtagmap-elem-len))
(defstruct mtagmap
(fd -1 :type fixnum)
(ptr (cffi:null-pointer) :type machine-pointer)
(len 0 :type mindex)
class
layout
instantiator
walker
(elem-len 0 :type mindex))
(deftype mtagmaps-array ()
`(simple-array (or mtagmap null) (,+mtags+)))
(defvar *mtagmaps* (the mtagmaps-array (make-array +mtags+ :initial-element nil :element-type
'(or mtagmap null))))
(declaim (type mtagmaps-array *mtagmaps*))
(defun mtagmap (mtag)
(declare (type mtag mtag))
(aref (the mtagmaps-array *mtagmaps*) mtag))
(defun (setf mtagmap) (val mtag)
(check-type mtag mtag)
(check-type val (or null mtagmap))
(setf (aref (the mtagmaps-array *mtagmaps*) mtag) val))
(defmacro mm-instantiator-for-tag (mtag)
`(the mm-instantiator (mtagmap-instantiator (the mtagmap (mtagmap ,mtag)))))
(defun next-available-tag ()
(loop for i from 0 thereis (unless (mtagmap i) i)))
(defun mpointer (mtag mindex)
(declare (type mtag mtag) (type mindex mindex))
(cffi:inc-pointer (mtagmap-ptr (the mtagmap (mtagmap mtag))) mindex))
(defun mptr-pointer (mptr)
(mpointer (mptr-tag mptr) (mptr-index mptr)))
(defun mptr-to-lisp-object (mptr)
"Deference the object at location MPTR in the memory mapped
datastore and create a Lisp representation of it."
(funcall (the mm-instantiator (mm-instantiator-for-tag (mptr-tag mptr)))
(mptr-index mptr)))