home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
mmap-177.zip
/
MMAP.TXT
< prev
Wrap
Text File
|
1999-08-21
|
10KB
|
226 lines
Memory Mapped Files Emulation Layer v1.77
(c) 1998, 1999 Maurilio Longo - md2520@mclink.it
- * -
This is a brief document about mmap.dll, if you don't know what memory mapped
files are then this .dll is not for you :-)
This .dll is freeware (you can use and redistribute it whitout any charge) but
I retain all rights upon it. Standard disclaimer applies :-) i.e. I'm not
responsible for any damages arising from its use or misuse.
USE IT AT YOUR OWN RISK.
This .dll provides mmap() services to OS/2 processes. It is intended as a tool
for programmers porting unix software to OS/2 and / or for programmers
developing native OS/2 programs.
It is already used on mSLQ/2 (actually it was developed for mSQL/2). You can find
more info about mSQL at this address: http://blnet.com/msqlpc/
In this package you'll find several files:
mmap.dll : the emulation layer, it should go on a directory listed on your
LIBPATH;
mmap.lib : import library for OMF linker (like link386.exe);
mmap.a : import library for EMX/GCC ld.exe (a.out format);
mman.h : include file for C programmers;
mmap.txt : this text file you're already reading :-)
history.txt : list of changes.
ealib.h : Extended Attribute Library include file, added since this version
uses it and copyright requires its presence.
Since it is an *emulation* of mmap() services it has a few restrictions/limits
that you should be aware of and care:
1) You can have only one mapped region per file, this is a limit which will be
raised on a future release.
2) You cannot share a mapped region between processes (or address spaces), this
is a permanent restriction arising from the fact that mmap.dll runs with
user privileges and needs to be able to commit / decommit memory pages.
2b)Starting with version 1.75 MAP_SHARED is supported inside same address space,
ie you can have, for example, more than one thread which issues a mmap() call
with MAP_SHARED for the same file descriptor.
3) On Warp Server Advanced SMP and Aurora HighMemory is used so you can map up
to 2Gb of address space.
On Warp 3 and 4 you cannot mmap() more than 300 / 350 Mb per process, this is
a limit of OS/2.
On WSA SMP and Aurora you can have VIRTUALADDRESSLIMIT=3072 in your config.sys,
but be aware of the fact that mmap.dll can handle a maximum of 2Gb of addresses.
So if OS/2 returns an address > 2Gb behaviour is unpredictable.
4) All standard flags of mman.h are defined but only a few are used. You cannot
protect or lock memory regions and you should not rely on access flags.
All mapped pages are read only until a write access occurs.
This is a permanent restriction.
5) Starting with version 1.77 msync() can be synchronous or asynchronous and should be
called from time to time to sync modified pages to disk.
If you never call it syncing will be done at the time of munmap() call.
MS_INVALIDATE is supported and causes all pages to be discarded without writing
modified ones to disk.
6) There is a non-standard constant MS_MUNMAP (0x10) which is used by munmap()
to signal to msync() that it has been called by munmap(). This makes msync()
faster.
7) There is a non-standard function merror() which returns last error of calling
thread (and resets it).
8) Starting with version 1.75 there are two functions to register/deregister mmap()
services on a per thread basis.
To succeed in registering mmap() you should define a variable of type mmap_reg_t
on the stack of the calling thread.
ie, in C pseudo code :-)
void main()
{
...
mmap_reg_t mmap_reg
...
if (mregister(&mmap_reg) == 0) {
...
... mmap(....)
... munmap(...)
...
mderegister(&mmap_reg)
}
...
return 0
}
8b) mmap() works using an exception handler, so if you register your own exception handler
mregister() should be called AFTER your call to register your own exception handler
or mmap() could never be called to handle access to mmapped pages. mmap() gives
control back to OS/2 exceptions handling chain if the exception is not an access
violation and the address is not inside a mmapped object.
9) MAP_SHARED support uses EAs to keep track of mappings. Every effort has been made to
try to clean mmapped files from EA used by mmap(). If, nonetheless, the process using
mmap() is killed or the PC running it is reset EAs may remain.
The EA used is MMAP.HFILE and is of type ASCII. Every time a file is mmapped with
MAP_SHARED this EA is added to it and the value is a string of the form NNNNN:FFFF
were NNNNN: is the number of milliseconds since last reboot at the time of mmap.dll
initialization and FFFF is the file handle of first mmapping.
Since EAs are used the filesystem holding mmapped files has to support them
(ext2, for example, has no support for them, while JFS is OK).
Mmap.dll makes no test to ensure that EAs are supported. So you (the programmer
using this .dll) have to make this test and complain if something is wrong.
The mmap() emulation dll exports the following functions (here listed using
pascal notation since this library has been developed with VirtualPascal/2 v1.1):
Type
caddr_t = Pointer; // C types for mmap functions
off_t = longint;
size_t = longint;
int = longint;
mmap_reg_t = ExceptionRegistrationRecord;
// Returns size in bytes of a memory page
function getpagesize: int;
// Stub function, returns -1 and sets merror to EAGAIN
function mprotect(pAddr: caddr_t; cbLen, fProtection: int): int;
// Stub function, returns -1 and sets merror to EAGAIN
function mlockall(fFlags: int): int;
// Maps a file to a range of addresses in memory.
// pAddr must be 0, otherwise call fails
// cbLen is dimension of region of file to map
// fProtection is here only for compatibility, all pages are readonly and become read/write after a
// write access to them
// hFile is the handle of mapping file; only one mapping region is available as of version 1.0 of mmap.dll
// cbOffest position in file from which mapping starts
// if something goes wrong it returns -1 and sets merror to appropriate error code
function mmap(pAddr: caddr_t; cbLen: size_t; fProtection, fFlags, hFile: int; cbOffset: off_t): caddr_t;
// Synchronizes pages accessed with a write operation to file, after synchronization pages are converted to
// readonly access; pages with readonly access are decomitted.
// It accepts starting address and len of a mapped region. fFlags is not used but for value
// MS_UNMAP which tells msync that is being called by munmap and so decommitting of readonly pages
// is not necessary.
function msync(pAddr: caddr_t; cbLen: size_t; fFlags: int): int;
// Stub function, always returns 0
function munlockall: int;
// Unmaps a previously mapped region and syncs it to file if necessary
function munmap(pAddr: caddr_t; cbLen: size_t): int;
// Returns, and clears, last error of calling thread
function merror: int;
// Registers mmap services on a per thread basis
function mregister(var Reg: mmap_reg_t): int;
// Deregisters them
function mderegister(var Reg: mmap_reg_t): int;
merror() returns last error occurred to calling thread and clears it; defined
errors are as follows:
EPERM = 1; // Operation not permitted
EIO = 5; // Input/output error
ENXIO = 6; // Device not configured
EBADF = 9; // Bad file descriptor
ENOMEM = 12; // Cannot allocate memory
EACCES = 13; // Permission denied
EBUSY = 16; // Device busy
ENODEV = 19; // Operation not supported by device
EINVAL = 22; // Invalid argument
EMFILE = 24; // Too many open files
EAGAIN = 35; // Resource temporarily unavailable
This library defines standard flags for mmap(), msync() and munmap() but does
use only a few; so you should not rely on them but at the same time they are
reserved for future use.
HAVE_MSYNC = $1; // msync available
PROT_READ = $0001; // read only access - not used
PROT_WRITE = $0002; // write access - not used
PROT_EXEC = $0004; // execute access - not used
PROT_NONE = $0000; // no access - not used
MAP_SHARED = $1; // shared mapping - supported inside same address space
MAP_PRIVATE = $2; // private mapping
MAP_FIXED = $10; // fixed address - not supported
MCL_CURRENT = $1; // locking options are not supported
MCL_FUTURE = $2;
MS_ASYNC = $1; // asynchronous syncing
MS_INVALIDATE = $2; // invalidate pages
MS_SYNC = $4; // synchronous syncing
MS_MUNMAP = $10; // Used by munmap() when calling msync()
It's possible to set an environment variable to force the mmap.dll to show infos
about its inner workings. To enable this capability use
SET MMAPDLL=DEBUG
before starting any process which will use mmap() services.
It's possible to find a more detailed documentation about memory mapped files
at this address http://hoth.stsci.edu/man/man2/mmap.html but please bear in
mind that those are pages about linux / freebsd memory mapped services so they
list capabilities and functions not available with my emulation.
I would like to thank Yuri Dario (mc6530@mclink.it) for his help and tests
of my .dll.
Ok, that's all. Please bear with my poor english and happy mmapping :-))
I'd like to be informed if you decide to use my library in a program of yours.