Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 May 2000 01:19:18 -0700
From:      Alfred Perlstein <bright@wintelcom.net>
To:        nathan@khmere.com
Cc:        "hackers@FreeBSD.ORG" <hackers@FreeBSD.ORG>
Subject:   Re: mremap help ? or no support for FreeBSD ? so do what ?
Message-ID:  <20000513011918.C28383@fw.wintelcom.net>
In-Reply-To: <391D61DA.C9793AAC@khmere.com>; from nathan@khmere.com on Sat, May 13, 2000 at 07:08:27AM -0700
References:  <391D39E0.934224E4@khmere.com> <20000512235721.A28383@fw.wintelcom.net> <391D61DA.C9793AAC@khmere.com>

next in thread | previous in thread | raw e-mail | index | archive | help
* nathan@khmere.com <nathan@khmere.com> [000513 00:41] wrote:
> Alfred Perlstein wrote:
> 
> > * nathan@khmere.com <nathan@khmere.com> [000512 21:54] wrote:
> > > I know that this was discussed in the past but I can't find out what to
> > > do ?
> > >
> > > In Linux if I have to resize a mmap 'ed object I can just use mremap....
> > > but in FreeBSD if,  I want to resize it what do I do ?
> > >
> > > I have tried writing past where I know the end is and it kinda works ?
> > > but why ?
> > >
> > > Is their a better solution besides just writing to the file and then
> > > calling msync ?
> > >
> > > Is their new plans to make a mremap call for FreeBSD 4.x ?
> >
> > no.
> >
> > >
> > > Or am I just  sh%t  out of luck ?
> >
> > Possibly, but if you describe what you are trying to accomplish
> > there may be some advice available.  Your misuse of msync makes me
> > think that a rethinking of what you are trying to accomplish may
> > be a good idea.  Please explain what makes you need mremap which
> > is not portable to any version of unix.  I'm assuming you want your
> > app to work on Solaris and other commercial systems.
> >
> > --
> > -Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org]
> > "I have the heart of a child; I keep it in a jar on my desk."
> >
> > To Unsubscribe: send mail to majordomo@FreeBSD.org
> > with "unsubscribe freebsd-hackers" in the body of the message
> 
> Sorry !
> 
> Ok here is a snipit of what I am trying to do....
> 
> fstat(fd, &st);
> if( (base = (caddr_t *) mmap(0, st.st_size, ( PROT_READ | PROT_WRITE ) ,
> MAP_SHARED, fd, 0)) == MAP_FAILED)
>  {
>    MSG_ERR("cannot mmap file, exiting ! ");
>    _exit(1);
>  }
> 
> /* say st.st_size = 200, and I want to add to the end of the file more data
> */
> base += 200; /* we are now at the end */
> 
> rec = (stuct rec_t *) base;
> rec->len = 200;
> /* we are writing to the buff, but we are past.... */
> memmove(rec->data, data, 100);
> msync(base, 0, (st.st_len + rec->len),  MS_ASYNC);
> 
> the struct rec_t is an example of a stuct that I want to append to the buf
> and make another reccord.
> If base was a regular pointer we would segfault.... cause we are past the
> pointers buf....
> but  it kinda works.. meaning it will write and add and sometimes and not
> segfault... sometimes...
> 
> or I can do this:
> 
> rec = (stuct rec_t *) base;
> rec->len = 200;
> memmove(rec->data, data, 100);
> write(fd, (char *) rec, rec->len);
> msync(base, 0, (st.st_len + rec->len),  MS_ASYNC);
> 
> After I append to the file and then msync.  I should be able to read the
> reccord that I just added from base.
> base  should reflect the file.... right ?
> 
> I want to make things simple and only append to the buffer "base" and not
> have to re-open the file and write to it then msync it back to mem. I know
> that some of this under FreeBSD "automatic" meaning that the changes made to
> the file  are seen by "base" even though I do not call msync..... but in
> order to keep things clear, I will msync.
> 
> I hope that this wasn't too confusing... I am not good at explanations.... or
> spelling....

The first code snippet is completely incorrect, this is _not_ how
you use the mmap() interface and I'm suprised it works at all.
Writing after the mmap'd area should cause a SEGV of BUS signal to
be sent to your process.

You really haven't provided the code you're using on Linux to use mremap()
which I'm assuming looks something like:

> rec = (stuct rec_t *) base;
> rec->len = 200;
> memmove(rec->data, data, 100);
> write(fd, (char *) rec, rec->len);
->>> mremap(arguments to extend the map);
> msync(base, 0, (st.st_len + rec->len),  MS_ASYNC);

(derived from the second snippet)

Now i'm confused, why are you mmap()'ing like this?  I know mremap()
offers a slightly easier interface, but you could simulate with some
code like so:

(you've already mmap()'d a page aligned and multiple of page sized
region)
if (!mmap(base + offset, additional length,
    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, offset)) {

    unmap file and remap it.
};

which would tell the OS to map in the end of the file at the end
of the map you already have.

problems which can then happen is that if you mmap() multiple files
without specifying a fixed address then they may be mmap'd into
your address space right next to each other so that the fixed
mapping will fail.

A more flexible way would be to maintain a structure for each file
that keeps track of all the base and length addresses that you've
mmap'd in the file.  Then before writing to the memory address you
can do a quick lookup to figure out where the OS has mapped in that
particular offset into your address space.  You could use a hash
on the fd and a binary tree to store that infomation pretty easily.

Basically implement a simple mmap() manager and you should be set.

best of luck,
-- 
-Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org]
"I have the heart of a child; I keep it in a jar on my desk."


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000513011918.C28383>