MMAP on Windows

967 views
Skip to first unread message

Simonr

unread,
Aug 18, 2010, 7:18:44 AM8/18/10
to C++ RTMP Server
Hi,

If anybodies interested... I have implemented MMAP for the windows
code:

Add the following to Win32platform.h:

#define MAP_NOCACHE (0)
#define MAP_NOEXTEND 0x0100 /* for MAP_FILE, don't change file size
*/
#define MAP_FAILED ((void *) -1)
#define O_RDONLY 0x0000
#define O_RDWR 0x0002

#define PROT_READ 0x1 /* Page can be read. */
#define PROT_WRITE 0x2 /* Page can be written. */
#define PROT_EXEC 0x4 /* Page can be executed. */
#define PROT_NONE 0x0 /* Page can not be accessed.
*/

#define MAP_SHARED 0x01 /* Share changes. */
#define MAP_PRIVATE 0x02 /* Changes are private. */
#define MAP_FIXED 0x10 /* Interpret addr exactly.
*/

DLLEXP long getpagesize (void);
DLLEXP long getregionsize (void);
DLLEXP void *mmap(void *start, size_t len, int prot, int flags, int
fd, off_t offset);
DLLEXP int munmap(void *start, size_t len);

Add the following to Win32platform.cpp

long getpagesize (void) {
static long g_pagesize = 0;
if (! g_pagesize) {
SYSTEM_INFO system_info;
GetSystemInfo (&system_info);
g_pagesize = system_info.dwPageSize;
}
return g_pagesize;
}
long getregionsize (void) {
static long g_regionsize = 0;
if (! g_regionsize) {
SYSTEM_INFO system_info;
GetSystemInfo (&system_info);
g_regionsize = system_info.dwAllocationGranularity;
}
return g_regionsize;
}

void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t
offset) {

/*
This is a minimal implementation supporting:
PROT_NONE, PROT_READ, PROT_WRITE, PROT_EXEC
It handles the following mapping flags:
MAP_NOCACHE, MAP_FIXED, MAP_SHARED, MAP_PRIVATE
*/

void *ret = MAP_FAILED;
HANDLE hmap = NULL;
long wprot = 0, wflags = 0;
HANDLE hfile = (HANDLE)_get_osfhandle(fd);
long file_len = _filelength(fd);

/* map *NIX protections and flags to their WIN32 equivalents */
if ((prot & PROT_READ) && (~prot & PROT_WRITE)) {
/* read only, maybe exec */
wprot = (prot & PROT_EXEC) ? (PAGE_EXECUTE_READ) :
(PAGE_READONLY);
wflags = (prot & PROT_EXEC) ? (FILE_MAP_EXECUTE) :
(FILE_MAP_READ);
if (flags & MAP_NOCACHE)
wprot = wprot| SEC_NOCACHE;
}
else if (prot & PROT_WRITE) {
/* read/write, maybe exec */
if ((flags & MAP_SHARED) && (~flags & MAP_PRIVATE)) {
/* changes are committed to the file */
wprot = (prot & PROT_EXEC) ? (PAGE_EXECUTE_READWRITE) :
(PAGE_READWRITE);
wflags = (prot & PROT_EXEC) ? (FILE_MAP_EXECUTE) :
(FILE_MAP_WRITE);
}
else if ((flags & MAP_PRIVATE) && (~flags & MAP_SHARED)) {
/* does not affect the original file */
wprot = PAGE_WRITECOPY;
wflags = FILE_MAP_COPY;
}
else {
/* MAP_PRIVATE + MAP_SHARED is not allowed, abort */
errno = EINVAL;
return MAP_FAILED;
}
}

int granularityOffset = (int)(offset % getregionsize());
offset -= granularityOffset; // align offset
len = (offset+len+granularityOffset > file_len) ? file_len-offset-
granularityOffset : len; //check to see if offset + len in bounds

/* create the windows map object */
hmap = CreateFileMapping(hfile, NULL, wprot, 0, offset+len
+granularityOffset, NULL);

if (hmap == NULL) {
/* the fd was checked before, so it must have bad access rights */
errno = EPERM;
return MAP_FAILED;
}

ret = MapViewOfFileEx(hmap, wflags, 0, offset, len +
granularityOffset,
(flags & MAP_FIXED) ? (start) : (NULL));

int err = GetLastError();

/* Drop the map, it will not be deleted until last 'view' is
closed */
CloseHandle(hmap);

if (ret == NULL || err!=0) {
/* if MAP_FIXED was set, the address was probably wrong */
errno = (flags & MAP_FIXED) ? (EINVAL) : (ENOMEM);
return MAP_FAILED;
}

if (granularityOffset) //map the return base address to viewoffile
base address
_mmap_map[(void *) ((char *)ret + granularityOffset)] = ret;

return ((void *) ((char *)ret + granularityOffset));
}

int munmap(void *start, size_t len)
{
if (start == NULL) {
errno = EINVAL;
return -1;
}

if (MAP_HAS1(_mmap_map, start)) // does it have a adjusted base for
granularity?
return UnmapViewOfFile(_mmap_map[start]) ? 0 : -1;
else
return UnmapViewOfFile(start) ? 0 : -1;
}


change: class MmapPointer to: class DLLEXP MmapPointer
change: class DLLEXP MmapFile to: class DLLEXP MmapFile

Then just define HAS_MMAP for the thelib and common projects.

Regards,

Simon

Simonr

unread,
Aug 18, 2010, 7:22:32 AM8/18/10
to C++ RTMP Server
Opps. forgot to mention to add:

static map<void *, void *> _mmap_map; //map addressses to cater for
granularity

after the following line in win32platform.cpp:
static map<uint32_t, SignalFnc> _signalHandlers;


Sorry!

Regards,

Simon

C++ RTMP Server

unread,
Aug 18, 2010, 7:59:42 PM8/18/10
to c-rtmp...@googlegroups.com
That is pretty cool :)

I will include your code. Just let me know your full name via a private email so I can do the proper licensing for it

Cheers,
Andrei

> You received this message because you are subscribed to "C++ RTMP Server" mailing list.
> To post to this group, send email to c-rtmp...@googlegroups.com
> To unsubscribe from this group, send email to
> c-rtmp-serve...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/c-rtmp-server?hl=en

------
Eugen-Andrei Gavriloaie
Web: http://www.rtmpd.com

Reply all
Reply to author
Forward
0 new messages