Messages in this thread |  | | Date | Thu, 13 Feb 1997 12:41:14 +0200 (SAT) | From | John Carter <> | Subject | RE: B*gg*r mallocs, mmap JOY! |
| |
Ha! I just _luv_ Linux.
Thanks to Ingo Molnar and many others on the list who gave me clues along they way...
Here is an example program for anyone else who wishes to use mmap. (Note you _can_ use mmap to write to files, the trick is ftruncate())
It does what 'cp' does, but a little bit slower. A cute thing to note is the load graph soars to 3, maybe it would be civilized to 'nice' any programs you run that do this.
The joy of it is that if you are actually doing real work like neighbourhood operations on a satellite image, you can forget all those nasty horrid boundary conditions on the buffers, as there are no buffers (visible).
50% of the code and 90% of the bugs of such a program is typically handling boundary conditions on the buffering.
I LOVE LINUX. I tested this creating 150Mb of VM on a 24Mb real mem system and used 0 swap space.
By gorrah, what a mess programming in DOS and Vax/VMS was in comparison.
John Carter EMail: ece@dwaf-hri.pwv.gov.za Telephone : 27-12-808-0374x194 Fax:- 27-12-808-0338
Founder of the Council for Unnatural Scientists.
====================================================================== #include <sys/mman.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #include <stdio.h> #include <iostream.h>
main() { int ifd, ofd; struct stat st; char * icp, * ocp;
ifd = open( "/home/john/pgm/tryout/temp", O_RDONLY); if( ifd < 0) { perror( "input file"); return 1; }
fstat( ifd, &st); cout << "Open " << st.st_size << " byte input file.\n"; ofd = open( "/home/john/pgm/tryout/temp1", O_CREAT | O_RDWR, S_IRWXU); if( ofd < 0) { perror( "output file"); return 1; }
cout << "Opened output file, now truncating file at " << st.st_size / 1024 / 1024 << " Mb's.\n"; ftruncate( ofd, st.st_size); // Note this cuty... // ftruncate is not in glibc, its a system call, and works instantaneously.
cout << "Truncated file.\n";
icp = (char *)mmap( 0, st.st_size, PROT_READ, MAP_FILE | MAP_SHARED, ifd, 0);
if( icp == (char *)-1) { perror( "input memory map"); return 1; }
cout << "Mapped input file.\n";
ocp = (char *)mmap( 0, st.st_size, PROT_WRITE, MAP_FILE | MAP_SHARED, ofd, 0);
if( ocp == (char *)-1) { perror( "output memory map"); return 1; }
cout << "Mapped output file.\n";
memcpy( ocp, icp, st.st_size); // Shove data across, this is where // the real work would go. cout << "Done the mem copy.\n";
munmap( icp, st.st_size);
cout << "Unmapped input array.\n";
munmap( ocp, st.st_size);
cout << "Unmapped output array.\n";
if( close( ifd) < 0) { perror( "close input file"); return 1; }
cout << "Closed input file.\n";
if( close( ofd) < 0) { perror( "close output file"); return 1; }
cout << "Closed output file.\n"; }
|  |