tech-userlevel archive

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

Re: mail(1) - string relaxation



Can you forward these patches to gnats?

On Mon, Dec 9, 2013 at 3:03 PM, Steffen Daode <sdaoden%gmail.com@localhost> 
wrote:
> Hello,
> i've implemented string relaxation in the S-nail(1) codebase and
> gained massive reduction of memory overhead.
> Since this thing is an exploded BSD Mail i thought doing the same
> for NetBSD mail(1) wouldn't be something bad, but it seems the
> wins are not comparable dramatic, most likely because of the
> completely different MIME approach.  Still there is a win,
> especially with large mailboxes (many messages that is) which need
> to be updated (after 'unre'ing a message, for example).
> This diff should work just fine, even if the signal handling of
> NetBSD mail(1) is far more improved in comparison; (note that,
> because of the sreset() that happens on each command loop tick,
> even the other case would likely survive (in fact i'm not quite
> sure if the recursion doesn't simply jump away, but if so,
> again..)).
> (And note my repo hasn't been updated for about two months, i'm
> behind GPRS most of the time, but i don't remember any mail
> change?  On interest and otherwise i'll update and resend.)
> Ciao,
>
> --steffen
>
> diff -Napru nmail/cmd1.c nmail.relax/cmd1.c
> --- nmail/cmd1.c        2013-12-09 13:16:52.000000000 +0100
> +++ nmail.relax/cmd1.c  2013-12-09 19:09:03.000000000 +0100
> @@ -124,13 +124,16 @@ headers(void *v)
>         flag = 0;
>         if (dot != get_message(n))
>                 dot = mp;
> +       srelax_on();
>         for (/*EMPTY*/; mp; mp = next_message(mp)) {
>                 if (mp->m_flag & MDELETED)
>                         continue;
>                 if (flag++ >= size)
>                         break;
>                 printhead(get_msgnum(mp));
> +               srelax();
>         }
> +       srelax_off();
>         if (flag == 0) {
>                 (void)printf("No more mail.\n");
>                 return 1;
> @@ -343,6 +346,7 @@ type1(int *msgvec, int doign, int mime_d
>          * exit code will never be seen.
>          */
>         sig_check();
> +       srelax_on();
>         oldsigpipe = sig_signal(SIGPIPE, cmd1_brokpipe);
>         if (setjmp(pipestop))
>                 goto close_pipe;
> @@ -365,8 +369,10 @@ type1(int *msgvec, int doign, int mime_d
>                 args.mip = NULL;
>  #endif
>                 (void)thread_recursion(mp, type1_core, &args);
> +               srelax();
>         }
>  close_pipe:
> +       srelax_off();
>  #ifdef MIME_SUPPORT
>         if (mip != NULL) {
>                 struct sigaction osa;
> @@ -549,6 +555,7 @@ top(void *v)
>         args.lineb = 1;
>         recursive = do_recursion();
>         msgCount = get_msgCount();
> +       srelax_on();
>         for (ip = msgvec; *ip && ip - msgvec < msgCount; ip++) {
>                 struct message *mp;
>
> @@ -556,7 +563,9 @@ top(void *v)
>                 dot = mp;
>                 args.parent = recursive ? mp : NULL;
>                 (void)thread_recursion(mp, top_core, &args);
> +               srelax();
>         }
> +       srelax_off();
>         return 0;
>  }
>
> diff -Napru nmail/cmd2.c nmail.relax/cmd2.c
> --- nmail/cmd2.c        2013-12-09 13:16:52.000000000 +0100
> +++ nmail.relax/cmd2.c  2013-12-09 19:02:25.000000000 +0100
> @@ -234,6 +234,7 @@ save1(char str[], int markmsg, const cha
>                 warn(NULL);
>                 return 1;
>         }
> +       srelax_on();
>         for (ip = msgvec; *ip && ip - msgvec < msgCount; ip++) {
>                 struct save1_core_args_s args;
>                 struct message *mp;
> @@ -245,9 +246,12 @@ save1(char str[], int markmsg, const cha
>                 if (thread_recursion(mp, save1_core, &args)) {
>                         warn("%s", fn);
>                         (void)Fclose(obuf);
> +                       srelax_off();
>                         return 1;
>                 }
> +               srelax();
>         }
> +       srelax_off();
>         (void)fflush(obuf);
>         if (ferror(obuf))
>                 warn("%s", fn);
> @@ -690,6 +694,7 @@ detach1(void *v, int do_unnamed)
>                 msgvec[1] = 0;
>         }
>         recursive = do_recursion();
> +       srelax_on();
>         for (ip = msgvec; *ip && ip - msgvec < msgCount; ip++) {
>                 struct detach1_core_args_s args;
>                 struct message *mp;
> @@ -700,7 +705,9 @@ detach1(void *v, int do_unnamed)
>                 args.igtab = do_unnamed ? detachall : ignoreall;
>                 args.dstdir = dstdir;
>                 (void)thread_recursion(mp, detach1_core, &args);
> +               srelax();
>         }
> +       srelax_off();
>         return 0;
>  }
>
> diff -Napru nmail/extern.h nmail.relax/extern.h
> --- nmail/extern.h      2013-12-09 13:16:52.000000000 +0100
> +++ nmail.relax/extern.h        2013-12-09 18:36:12.000000000 +0100
> @@ -278,6 +278,9 @@ int sendmail(void *);
>  void * csalloc(size_t, size_t);
>  void * salloc(size_t);
>  void   sreset(void);
> +void   srelax_on(void);
> +void   srelax_off(void);
> +void   srelax(void);
>  void   spreserve(void);
>
>  /*
> diff -Napru nmail/list.c nmail.relax/list.c
> --- nmail/list.c        2013-12-09 13:16:52.000000000 +0100
> +++ nmail.relax/list.c  2013-12-09 19:06:33.000000000 +0100
> @@ -845,6 +845,7 @@ match_string(int *markarray, char *str,
>                 return -1;
>
>         rval = 0;
> +       srelax_on();
>         for (i = 1; i <= msgCount; i++) {
>                 struct message *mp;
>                 mp = get_message(i);
> @@ -854,7 +855,9 @@ match_string(int *markarray, char *str,
>                 if (rval)
>                         markarray[i - 1] = 1;
>                 rval = 0;
> +               srelax();
>         }
> +       srelax_off();
>
>         free_cmparg(cmparg);    /* free any memory allocated by get_cmpfn() */
>
> @@ -1325,9 +1328,13 @@ show_headers_and_exit(int flags)
>                 (void)signal(SIGINT, SIG_IGN);
>
>         flags &= CMMASK;
> +       srelax_on();
>         for (mp = get_message(1); mp; mp = next_message(mp))
> -               if (flags == 0 || !ignore_message(mp->m_flag, flags))
> +               if (flags == 0 || !ignore_message(mp->m_flag, flags)) {
>                         printhead(get_msgnum(mp));
> +                       srelax();
> +               }
> +       srelax_off();
>
>         exit(0);
>         /* NOTREACHED */
> diff -Napru nmail/quit.c nmail.relax/quit.c
> --- nmail/quit.c        2013-12-09 13:16:52.000000000 +0100
> +++ nmail.relax/quit.c  2013-12-09 18:59:56.000000000 +0100
> @@ -95,15 +95,19 @@ writeback(FILE *res)
>                 }
>         }
>  #endif
> +       srelax_on();
>         for (mp = get_message(1); mp; mp = next_message(mp))
>                 if ((mp->m_flag & MPRESERVE) || (mp->m_flag & MTOUCH)==0) {
>                         p++;
>                         if (sendmessage(mp, obuf, NULL, NULL, NULL) < 0) {
>                                 warn("%s", mailname);
>                                 (void)Fclose(obuf);
> +                               srelax_off();
>                                 return -1;
>                         }
> +                       srelax();
>                 }
> +       srelax_off();
>  #ifdef APPEND
>         if (res != NULL)
>                 while ((c = getc(res)) != EOF)
> @@ -221,16 +225,20 @@ edstop(jmp_buf jmpbuf)
>         }
>         trunc(obuf);
>         c = 0;
> +       srelax_on();
>         for (mp = get_message(1); mp; mp = next_message(mp)) {
>                 if ((mp->m_flag & MDELETED) != 0)
>                         continue;
>                 c++;
>                 if (sendmessage(mp, obuf, NULL, NULL, NULL) < 0) {
>                         warn("%s", mailname);
> +                       srelax_off();
>                         sig_release();
>                         longjmp(jmpbuf, -1);
>                 }
> +               srelax();
>         }
> +       srelax_off();
>         gotcha = (c == 0 && ibuf == NULL);
>         if (ibuf != NULL) {
>                 while ((c = getc(ibuf)) != EOF)
> @@ -480,17 +488,22 @@ nolock:
>                 }
>                 (void)fchmod(fileno(obuf), 0600);
>         }
> +       srelax_on();
>         for (mp = get_message(1); mp; mp = next_message(mp))
> -               if (mp->m_flag & MBOX)
> +               if (mp->m_flag & MBOX) {
>                         if (sendmessage(mp, obuf, saveignore, NULL, NULL) < 
> 0) {
>                                 warn("%s", mbox);
>                                 if (!append)
>                                         (void)Fclose(ibuf);
>                                 (void)Fclose(obuf);
>                                 (void)Fclose(fbuf);
> +                               srelax_off();
>                                 dot_unlock(mailname);
>                                 return;
>                         }
> +                       srelax();
> +               }
> +       srelax_off();
>
>         /*
>          * Copy the user's old mbox contents back
> diff -Napru nmail/strings.c nmail.relax/strings.c
> --- nmail/strings.c     2013-12-09 13:16:52.000000000 +0100
> +++ nmail.relax/strings.c       2013-12-09 20:08:08.000000000 +0100
> @@ -38,6 +38,8 @@ __RCSID("$NetBSD: strings.c,v 1.18 2010/
>  #endif
>  #endif /* not lint */
>
> +#include <assert.h>
> +
>  /*
>   * Mail -- a mail program
>   *
> @@ -60,10 +62,13 @@ __RCSID("$NetBSD: strings.c,v 1.18 2010/
>  #define        NSPACE  25                      /* Total number of string 
> spaces */
>  static struct strings {
>         char    *s_topFree;             /* Beginning of this area */
> +       char    *s_relaxFree;           /* Begin of area during relaxation */
>         char    *s_nextFree;            /* Next alloctable place here */
>         size_t  s_nleft;                /* Number of bytes left here */
>  } stringdope[NSPACE];
>
> +static int     relaxation;
> +
>  /*
>   * Allocate size more bytes of space and return the address of the
>   * first byte to the caller.  An even number of bytes are always
> @@ -97,6 +102,7 @@ salloc(size_t size)
>                 sp->s_topFree = malloc(STRINGSIZE << idx);
>                 if (sp->s_topFree == NULL)
>                         errx(EXIT_FAILURE, "No room for space %d", idx);
> +               sp->s_relaxFree = NULL;
>                 sp->s_nextFree = sp->s_topFree;
>                 sp->s_nleft = STRINGSIZE << idx;
>         }
> @@ -131,13 +137,64 @@ sreset(void)
>
>         if (noreset)
>                 return;
> +
> +       relaxation = 0;
> +
>         idx = 0;
> -       for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) {
> +       for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; ++idx, ++sp) {
>                 if (sp->s_topFree == NULL)
>                         continue;
> +               sp->s_relaxFree = NULL;
>                 sp->s_nextFree = sp->s_topFree;
>                 sp->s_nleft = STRINGSIZE << idx;
> -               idx++;
> +       }
> +}
> +
> +PUBLIC void
> +srelax_on(void)
> +{
> +       struct strings *sp;
> +       int idx;
> +
> +       assert(relaxation == 0);
> +
> +       idx = 0;
> +       for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; ++idx, ++sp) {
> +               if (sp->s_topFree == NULL)
> +                       continue;
> +               sp->s_relaxFree = sp->s_nextFree;
> +       }
> +
> +       relaxation = 1;
> +}
> +
> +PUBLIC void
> +srelax_off(void)
> +{
> +       assert(relaxation == 1);
> +
> +       srelax();
> +       relaxation = 0;
> +}
> +
> +PUBLIC void
> +srelax(void)
> +{
> +       struct strings *sp;
> +       int idx;
> +
> +       assert(relaxation == 1);
> +
> +       idx = 0;
> +       for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; ++idx, ++sp) {
> +               if (sp->s_topFree == NULL)
> +                       continue;
> +               sp->s_nleft = STRINGSIZE << idx;
> +               if ((sp->s_nextFree = sp->s_relaxFree) == NULL)
> +                       sp->s_nextFree = sp->s_topFree;
> +               else
> +                       sp->s_nleft -= (size_t)(uintptr_t)(sp->s_relaxFree -
> +                           sp->s_topFree);
>         }
>  }
>


Home | Main Index | Thread Index | Old Index