Operating Systems 2 EN -- Laboratory 5 -- 2006-2007 -- info.uvt.ro
Appearance
Operating Systems 2 EN -- 2006-2007 -- info.uvt.ro
- Operating Systems 2 EN -- Assignment -- 2006-2007 -- info.uvt.ro
- Operating Systems 2 EN -- Laboratory 1 -- 2006-2007 -- info.uvt.ro
- Operating Systems 2 EN -- Laboratory 5 -- 2006-2007 -- info.uvt.ro
- Operating Systems 2 EN -- Laboratory 6 -- 2006-2007 -- info.uvt.ro
- Operating Systems 2 EN -- OSDI -- 2006-2007 -- info.uvt.ro
Memory mapped file
[edit | edit source]Links
[edit | edit source]Memory Mapped Files Memory mapped file -- Wikipedia article
Advantages
[edit | edit source]- Increased input / output performance
- Cached data
- Small data is read at once
- Minimizes the system calls
- Avoids memory copying
- Memory sharing
Disadvantages
[edit | edit source]- Increases the page faults ration
Suitable for
[edit | edit source]- Small but often input / output operations
- Random access
- Sharing data between processes
- Executable / library loading
Unsuitable for
[edit | edit source]- Sequential reading (streaming)
System call
[edit | edit source]#include <sys/mman.h>
void * mmap (
void * address,
size_t size,
int protection,
int flags,
int file_descriptor,
off_t file_offset);
int munmap (
void * address,
size_t size);
- address is a desired starting address for the mapped data. Usually it takes the value 0 and the operating system decides the actual address. It should be a multiple of the page size system parameter, obtained by getpagesize.
- size is the number of bytes to map from the file in memory. It should be a multiple of the page size system parameter.
- file_description is used to specify the backing file.
- file_offset the starting position inside the file. It should be a multiple of the page size system parameter.
- protection is a set of flags that mark the memory protection:
- PROT_NONE -- page can not be accessed;
- PROT_READ -- page can be read;
- PROT_WRITE -- page can be written;
- PROT_EXEC -- page can be executed.
- flags is a set of miscellaneous flags:
- MAP_FIXED -- makes the file system use only the desired address, or give an error;
- MAP_SHARED -- if a process modifies the mapped memory, all processes could see the modification;
- MAP_PRIVATE -- if a process modifies the mapped memory, the modification is only visible to the process;
- MAP_LOCKED -- the mapped pages are locked by using mlock;
- MAP_ANONYMOUS -- the mapped memory is not backed by a file, thus file descriptor and file offset are ignored;
- return value for mmap
- MAP_FAILED -- in case of error;
- a valid address -- in case of success.
- return value for munmap
- 0 -- in case of success;
- -1 -- in case of error;
Example
[edit | edit source]#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
void terminate (char * message)
{
printf ("[EE] %s\n", message);
exit (1);
}
void terminate_if (int condition, char * message)
{
if (condition)
terminate (message);
}
int main (int argc, char * * args)
{
char * file_name;
int file_descriptor;
void * file_address;
size_t file_size;
struct stat file_stat;
int outcome;
int page_size;
int page_count;
int page_index;
char * page;
terminate_if (argc != 2, "Invalid number of arguments");
file_name = args[1];
file_descriptor = open (file_name, O_RDONLY);
terminate_if (file_descriptor == -1, "Can not open the file.");
outcome = fstat (file_descriptor, &file_stat);
terminate_if (outcome == -1, "Can not stat the file.");
file_size = file_stat.st_size;
file_address = mmap (0, file_size, PROT_READ, MAP_PRIVATE, file_descriptor, 0);
terminate_if (file_address == MAP_FAILED, "Can not map the file.");
page_size = 16;
page_count = file_size / page_size;
for (page_index = 0; page_index < page_count; page_index++) {
page = ((char *) file_address) + (page_index * page_size);
int i;
printf ("%8x |", page_index * page_size);
for (i = 0; i < page_size; i++)
printf (" %02x", (unsigned char) page[i]);
printf (" | |");
for (i = 0; i < page_size; i++)
printf ("%c", ((page[i] >= 32) && (page[i] < 127) ? page[i] : ' '));
printf ("|\n");
}
outcome = munmap (file_address, file_size);
terminate_if (outcome != 0, "Can not unmap the file.");
outcome = close (file_descriptor);
terminate_if (outcome != 0, "Can not close the file.");
}
Non blocking streams
[edit | edit source]When using non blocking operations, a read or write operation immediately returns when there is no data to be read / written.
For more information consult the man pages for:
- open
- read
Example
[edit | edit source]#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
void terminate (char * message)
{
printf ("[EE] %s\n", message);
exit (1);
}
void terminate_if (int condition, char * message)
{
if (condition)
terminate (message);
}
int main (int argc, char * * args)
{
char * file_name;
int file_descriptor;
struct stat file_stat;
int loop;
int outcome;
char buffer[1024];
terminate_if (argc != 2, "Invalid number of arguments");
file_name = args[1];
file_descriptor = open (file_name, O_RDONLY | O_NONBLOCK);
terminate_if (file_descriptor == -1, "Can not open the file.");
loop = 1;
while (loop) {
printf ("[II] Reading...\n");
outcome = read (file_descriptor, buffer, sizeof (buffer));
if (outcome > 0) {
int i;
printf ("[>>] ");
for (i = 0; i < outcome; i++)
printf ("%c", buffer[i]);
printf ("\n");
} else {
if ((outcome == 0) || (errno == EAGAIN)) {
printf ("[II] Sleeping...\n");
sleep (1);
} else
terminate ("Can not read from file.");
}
}
outcome = close (file_descriptor);
terminate_if (outcome != 0, "Can not close the file.");
}