[Python-Dev] New branch for r23c2 work (original) (raw)

Skip Montanaro skip@pobox.com
Mon, 21 Jul 2003 10:34:40 -0500


Anthony> Could someone have a quick look at 774751 and decide if it's
Anthony> worth spending time on before rc2? (synopsis: sometime between
Anthony> 2.1 and 2.2, binding to a socket on MacOS X started taking a
Anthony> long long long time.)

I took the proverbial quick look. It appears the call to getsockaddrarg is taking all the time. I added some calls to gettimeofday surrounding the bits of functionality in sock_bind:

    struct timeval t;
    long usec;

    gettimeofday(&t, NULL); usec = t.tv_usec;
    if (!getsockaddrarg(s, addro, &addr, &addrlen))
            return NULL;
    gettimeofday(&t, NULL);
    fprintf(stderr, "getsockaddrarg: %d\n", (t.tv_usec-usec));
    gettimeofday(&t, NULL); usec = t.tv_usec;
    Py_BEGIN_ALLOW_THREADS
    res = bind(s->sock_fd, addr, addrlen);
    Py_END_ALLOW_THREADS
    gettimeofday(&t, NULL);
    fprintf(stderr, "bind+threads: %d\n", (t.tv_usec-usec));

and get this sort of output running on my Powerbook:

getsockaddrarg: 139824
bind+threads: 30
getsockaddrarg: 139884
bind+threads: 17
getsockaddrarg: 138592
bind+threads: 17
getsockaddrarg: 139504
bind+threads: 19

Instrumenting Python 2.2.3 sock_bind on a Linux machine generates this sort of output:

getsockaddrarg: 13
bind+threads: 7
getsockaddrarg: 14
bind+threads: 8
getsockaddrarg: 14
bind+threads: 8
getsockaddrarg: 15
bind+threads: 7
getsockaddrarg: 14
bind+threads: 7

Moving the time checks into getsockaddrarg generates this output on my Powerbook:

tuple check: 4
parse tuple: 26
setipaddr: 141153
htons: 3

Looking at setipaddr I see that Just added some lock acquisition code in May:

1.265        (jvr      09-May-03):          Py_BEGIN_ALLOW_THREADS
1.265        (jvr      09-May-03):          ACQUIRE_GETADDRINFO_LOCK
1.153        (loewis   21-Jul-01):          error = getaddrinfo(NULL, "0", &hints, &res);
1.265        (jvr      09-May-03):          Py_END_ALLOW_THREADS
1.265        (jvr      09-May-03):          /* We assume that those thread-unsafe getaddrinfo() versions
1.265        (jvr      09-May-03):             *are* safe regarding their return value, ie. that a
1.265        (jvr      09-May-03):             subsequent call to getaddrinfo() does not destroy the
1.265        (jvr      09-May-03):             outcome of the first call. */
1.265        (jvr      09-May-03):          RELEASE_GETADDRINFO_LOCK

revision 1.265
date: 2003/05/09 07:53:18;  author: jvr;  state: Exp;  lines: +45 -10
[ 731644] & [ 604210 ] Release the GIL around getaddrinfo(), yet protect
access with lock on those platforms that getaddrinfo() isn't (known to be)
thread-safe. Thanks to MvL for mentoring this patch.

Without digging deeper, I'm going to suggest that's the culprit. I'll leave it to others to figure out what can be done.

Skip