[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: memory_object_lock_request and memory_object_data_return fnord

From: Neal H Walfield
Subject: Re: memory_object_lock_request and memory_object_data_return fnord
Date: 25 Mar 2002 01:29:54 -0500
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.1

> I am pretty dubious about modifying memcpy at this point.  There are a lot
> of different implementations in libc, and they are being further tweaked
> all the time.  There are both assembly implementations and inline-macro
> implementations, and many of each for all the tiny variants of chip that
> exist for each platform and are worth optimizing to differently.  Then
> there's the compiler, which is free to inline it however it likes (and gcc
> 3.x does often, I gather).  I am guessing that the cases that would be
> covering multipage ranges are ones that don't get inlined--but the compiler
> would be perfectly in its rights to partially inline them and insert calls
> to its own support functions in libgcc or whatever.  I think it will be an
> unrewarding uphill battle to put the onus on the libc and gcc maintainers
> to make sure that the page-copy hooks are always used in applicable
> cases.

I was thinking along the lines of changing the __memcpy's found in
libc/sysdep/i386/{,i[456]86}/memcpy.S et al. to __real_memcpy and then
having a libc/sysdep/mach/memcpy.c do:

  void *
  __mach_memcpy (void *dest, const void *src, size_t n)
    if (n >= __vm_page_size
        && (dest & (__vm_page_size - 1)) == (src & (__vm_page_size - 1)))
        void *start_page = (src + __vm_page_size - 1)
                           & ~(__vm_page_size - 1);
        size_t bytes_of_pages = (n - (start_page - src))
                                & ~(__vm_page_size - 1);

        if (bytes_of_pages == 0)
          /* No page aligned copies.  */
          __real_memcpy (src, dest, n)
            size_t jagged_start_count = start_page - src;
            size_t jagged_end_offset = bytes_of_pages
                                       + jagged_start_count;
            size_t jagged_end_count = n - bytes_of_pages
                                      - jagged_start_count;

            if (jagged_start > 0)
              __real_memcpy (dest, src, jagged_start);

            err = __vm_copy (__mach_task_self (), src + jagged_start,
                             start_page - end_page + 1,
                             dest + jagged_start);
            assert (! err);

            if (jagged_end > 0)
              __real_memcpy (dest + jagged_end_offset,
                             src + jagged_end_offset,
      return __real_memcpy (dest, src, n);

  alias (__mach_memcpy, __memcpy)
  weak_alias (__memcpy, memcpy)
  weak_alias (__mach_memcpy, mach_memcpy)

> It costs very little the have an explicit check in pager_memcpy.  In fact,
> in the all-whole-pages case checking up front can save the overhead of
> arranging to handle a possible fault in memcpy.

I called it __mach_memcpy so that we can be sure to get the vm_copy
version in particular cases such as this.

> But I just had to share the gruesome idea.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]