URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7386
[ Назад ]

Исходное сообщение
"mmap: Два файла в один массив"

Отправлено yurkao , 27-Май-08 04:37 
собственно что хочется?
хочется промапить два файла в один маассив. например файл А идёт и оффсета 0 до рамера SIZE1-1, а файл Б от оффеста SIZE1 до SIZE1+SIZE2-1.
как бы ничего продебы сложного но вот такой код сегфолтится сразу послее финального return-a рандомально. т.е. при разных значениях SIZE1 и SIZE2 иногда проходит нормально,а иногда сегфолтится.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>

#define MAIN_SIZE 40960

#define SWAP_SIZE MAIN_SIZE*2

int create_file(char *fname,off_t size){
    int fd;
    if((fd=open(fname,O_CREAT|O_RDWR,S_IRWXU))<0){
    perror("open(2)");
    return -1;
    }

    if(lseek(fd,size-1,SEEK_SET)==(off_t)-1){
    perror("lseek(2)");
    close(fd);
    return -1;
    }
    
    if(write(fd,(void*)"",1)<0){
    close(fd);
    return -1;
    }
    

    if(lseek(fd,0,SEEK_SET)==(off_t)-1){
    perror("lseek(2)");
    close(fd);
    return -1;
    }
    return fd;

}

int main(){

    void    *main_mem=NULL,*swap_mem=NULL;
    int      main_fd,swap_fd ;

    main_fd = create_file("main",MAIN_SIZE);
    if(main_fd<0) return -10;
    swap_fd = create_file("swap",SWAP_SIZE);
    if(swap_fd<0) return -20;
    
    if((main_mem = mmap(NULL,MAIN_SIZE,PROT_WRITE,MAP_SHARED,main_fd,0))==MAP_FAILED){
    perror("mmap(2)#1");
    _exit(2);
    }

    if((swap_mem = mmap(main_mem+MAIN_SIZE,SWAP_SIZE,PROT_WRITE,MAP_FIXED|MAP_SHARED,swap_fd,0))==MAP_FAILED){
    perror("mmap(2)#2");
    _exit(2);
    }
    
    memset(main_mem,'A',MAIN_SIZE);
    memset(swap_mem,'B',SWAP_SIZE);

    if(munmap(main_mem,MAIN_SIZE+SWAP_SIZE)<0){
    perror("munmap(2)");
    }

    close(main_fd);    
    close(swap_fd);    

    return 0;
}
      No tags yet, please


Содержание

Сообщения в этом обсуждении
"mmap: Два файла в один массив"
Отправлено vic , 27-Май-08 12:26 
читать man mmap на предмет getpagesize()

"mmap: Два файла в один массив"
Отправлено yurkao , 27-Май-08 13:46 
>читать man mmap на предмет getpagesize()

дык вот ведь какая штука: оффсет(0) и размеры памяти кратны размеру страницы (4096)...


"mmap: Два файла в один массив"
Отправлено vic , 27-Май-08 16:21 
>>читать man mmap на предмет getpagesize()
>
>дык вот ведь какая штука: оффсет(0) и размеры памяти кратны размеру страницы
>(4096)...

все равно используйте getpagesize()

в обоих mmap используйте флаг MAP_FIXED, а не в одном, а лучше не используйте вообще, а после выделения проверяйте совпадение main_mem + MAIN_SIZE == swap_mem

и это, не стоит удалять память одним munmap вызывайте два, т.е. на каждый выделенный кусок.


"mmap: Два файла в один массив"
Отправлено phpcoder , 27-Май-08 16:34 
>все равно используйте getpagesize()

       In  SUSv2  the  getpagesize()  call is labeled
       LEGACY, and in POSIX.1-2001 it has been dropped; HP-UX  does  not  have
       this  call.   Portable applications should employ sysconf(_SC_PAGESIZE)
       instead of this call.

(c) man getpagesize(2)


"mmap: Два файла в один массив"
Отправлено vic , 27-Май-08 16:42 
>[оверквотинг удален]
>
>       In  SUSv2  the
> getpagesize()  call is labeled
>       LEGACY, and in POSIX.1-2001 it
>has been dropped; HP-UX  does  not  have
>       this  call.  
>Portable applications should employ sysconf(_SC_PAGESIZE)
>       instead of this call.
>
>(c) man getpagesize(2)

упс =)


"mmap: Два файла в один массив"
Отправлено yurkao , 27-Май-08 18:16 
>все равно используйте getpagesize()
>
>в обоих mmap используйте флаг MAP_FIXED, а не в одном, а лучше
>не используйте вообще, а после выделения проверяйте совпадение main_mem + MAIN_SIZE
>== swap_mem
>
>и это, не стоит удалять память одним munmap вызывайте два, т.е. на
>каждый выделенный кусок.

какие то глюки... обновил глибсы на 2.7 и заработало. ненавижу такие пляски с глибсами:(
щас откачусь обратно и попробую с MAP_FIXED.
кстати я так и не понял куда мне его пихать этот getpagesize(2).
делать выравнивание до кратности размера страницы?


"mmap: Два файла в один массив"
Отправлено vic , 28-Май-08 13:07 
>[оверквотинг удален]
>>
>>и это, не стоит удалять память одним munmap вызывайте два, т.е. на
>>каждый выделенный кусок.
>
>какие то глюки... обновил глибсы на 2.7 и заработало. ненавижу такие пляски
>с глибсами:(
>щас откачусь обратно и попробую с MAP_FIXED.
>кстати я так и не понял куда мне его пихать этот getpagesize(2).
>
>делать выравнивание до кратности размера страницы?

как прально замечено надо юзать sysconf вместо getpagesize, ну и что-то типа:

main()
{

//#define MAIN_SIZE 40960
//#define SWAP_SIZE MAIN_SIZE*2

long sz = sysconf(_SC_PAGESIZE);
size_t MAIN_SIZE = sz * 10;
size_t SWAP_SIZE = MAIN_SIZE * 2;

[skiped]
}

зы: та не заработало с глибсами 2.7 просто падать стало горааааздо реже =)
MAP_FIXED просто принуждает выдавать ошибку вместо попытки использовать другой адрес вместо указанного, в мане предостерегают от использования этого флага, поэтому и написал выше вариант с пост-проверкой для swap_mem.