From: Daniel B. <da...@te...> - 2003-05-28 15:46:01
|
=2D----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Rudi Schlatte <ru...@co...> writes: > * Define the system calls mmap, munmap, getpagesize in sb-posix Looks good, provided the user is aware he may injure himself terribly when using this stuff. > * Export syscall-error, so conditions of this type can be handled > outside of the sb-posix package Well spotted. > The sap-or-nil parameter is debatable, it could be canned for > aesthetic reasons, or if mmap is the only call that treats (void *)0 > as "don't care". Also, keep a barf bag handy when looking at the > error predicate for mmap. I was thinking about the whole foreign-memory issue on Monday, though =2D From the perspective of a "standard" interface rather than SBCL specifically. This is marginally related. Some implementations have efficient means for letting foreign code write into Lisp space - e.g. a character or (unsigned-byte 8) array. Some (e.g. OpenMCL) can't. We _could_ say that posix:read always takes a Lisp array as argument, but this would suck if all we wanted to do with the array was write it out again, because we'd have to do all that copying for no reason. So, there should be some way to say "leave this in foreign space" for implementations that would make this faster. Sometimes we have to do format conversions and stuff as well. For example, whatever we read from a file is going to be in some native-to-the-system encoding (probably utf8) and will need converting into unicode or iso-8859-15 or whatever else the Lisp uses. So: a buffer is an opaque object which has a start address and optionally also a size. A buffer-designator is=20 =2D - NIL, meaning either #<buffer :start 0 :length 0> or "allocate your own buffer", depending on context. (yuck, context-dependence. I hope it should be obvious which behaviour is appropriate for any given call but haven't thought about it too hard yet) =2D - a buffer, as returned by (allocate-buffer :length l) ; allocates new buffer somewhere appropriate (get-buffer :start s :length l)=20 ; creates a buffer pointing to existing VM. length is optional [ Open to better names for that latter ] =2D - a vector of (unsigned-byte 8), whose contents are made available as a buffer of appropriate start and length, using an identity mapping. This may or may not involve creating a copy of the data. =2D - a vector of character, which is turned into a buffer using some implementation-defined transformation that obviously depends on the implementation's representation of characters. This may or may not involve creating a copy of the data. (perhaps this wants to be a string designator, not exclusively a string) =2D - implementations may optionally extend this if they want [e.g. SBCL could also take a SAP] Notes:=20 1) optional size? yes, because the 'size' arguments to system calls are optional too, when the size can be inferred from the object passed. If you're mmaping at fixed addresses you probably want to write (posix:mmap (get-buffer 1000) 4096 posix:prot-read 0 -1 0) so that =20 your argument list matches the C binding more closely If you're writing a string to a file descriptor, on the other hand,=20 we already know how long it is, and that knowledge needs to be passed in somehow so that the existing rules for defaulting length arguments work (posix:write 1 (format nil "hello world~%")) 2) Remember that this is a one-way transformation: you can't expect to portably do =20 (let ((v (make-string 10))) (posix:read 0 v)) because the mutated buffer isn't automatically transformed back again. You have to pass posix:read a buffer. This is slightly ungainly but not so philosophically different from what the rest of the interface does: calling (posix:dup *standard-input*) returns an integer, not a stream We do need some functions to convert buffers back into these lispy objects. In fact, this goes for all the designators: we also need functions that convert other all kinds of C objects that we have designators for (currently file descriptors, pathnames) into usefully Lisp-like objects. "Buffer" is not a name I'm particularly attached to, though in the sense that it's a holding area for results passed back from C functions that may need further processing before Lisp sees them, I'm not sure it's actually such a bad one. It avoids the whole "should we call it _foreign_ memory or _native_ memory?" issue, at least. Comments? =2D -dan =2D --=20 http://www.cliki.net/ - Link farm for free CL-on-Unix resources=20 =2D----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) iD8DBQE+1NmZHDK5ZnWQiRMRArk+AJ9LjVWGLeK/IYHhhrEmsDukzFttpgCdHd7B +2UfvkxMZxdKHjyRZ+1U6ZQ=3D =3DfdcA =2D----END PGP SIGNATURE----- |