* ath.c, ath.h, ath-pth.c, ath-pthread.c: New. Taken from GPGME.
authorWerner Koch <wk@gnupg.org>
Tue, 17 Sep 2002 12:41:14 +0000 (12:41 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 17 Sep 2002 12:41:14 +0000 (12:41 +0000)
* mutex.h: Removed.
* Makefile.am (ath_components): New.

src/ath-pth.c [new file with mode: 0644]
src/ath-pthread.c [new file with mode: 0644]
src/ath.c [new file with mode: 0644]
src/ath.h [new file with mode: 0644]
src/benchmark.c [new file with mode: 0644]

diff --git a/src/ath-pth.c b/src/ath-pth.c
new file mode 100644 (file)
index 0000000..8f236a7
--- /dev/null
@@ -0,0 +1,118 @@
+/* ath-pth.c - Pth module for self-adapting thread-safeness library
+ *      Copyright (C) 2002 g10 Code GmbH
+ *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <pth.h>
+
+#include "ath.h"
+
+#pragma weak pth_mutex_init
+#pragma weak pth_mutex_acquire
+#pragma weak pth_mutex_release
+#pragma weak pth_read
+#pragma weak pth_write
+#pragma weak pth_select
+#pragma weak pth_waitpid
+
+/* The lock we take while checking for lazy lock initialization.  */
+static pth_mutex_t check_init_lock = PTH_MUTEX_INIT;
+
+/* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
+   it is not already initialized.  */
+static int
+mutex_pth_init (void **priv, int just_check)
+{
+  int err = 0;
+
+  if (just_check)
+    pth_mutex_acquire (&check_init_lock, 0, NULL);
+  if (!*priv || !just_check)
+    {
+      pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));
+      if (!lock)
+       err = ENOMEM;
+      if (!err)
+       {
+         err = pth_mutex_init (lock);
+         if (err == FALSE)
+           err = errno;
+         else
+           err = 0;
+
+         if (err)
+           free (lock);
+         else
+           *priv = lock;
+       }
+    }
+  if (just_check)
+    pth_mutex_release (&check_init_lock);
+  return err;
+}
+
+
+static int
+mutex_pth_destroy (void *priv)
+{
+  free (priv);
+  return 0;
+}
+
+
+static int
+mutex_pth_lock (void *priv)
+{
+  int ret = pth_mutex_acquire ((pth_mutex_t *) priv, 0, NULL);
+  return ret == FALSE ? errno : 0;
+}
+
+
+static int
+mutex_pth_unlock (void *priv)
+{
+  int ret = pth_mutex_release ((pth_mutex_t *) priv);
+  return ret == FALSE ? errno : 0;
+}
+
+
+static struct ath_ops ath_pth_ops =
+  {
+    mutex_pth_init,
+    mutex_pth_destroy,
+    mutex_pth_lock,
+    mutex_pth_unlock,
+    pth_read,
+    pth_write,
+    pth_select,
+    pth_waitpid
+  };
+
+
+struct ath_ops *
+ath_pth_available (void)
+{
+  if (pth_mutex_init && pth_mutex_acquire && pth_mutex_release
+      && pth_read && pth_write && pth_select && pth_waitpid)
+    return &ath_pth_ops;
+  else
+    return 0;
+}
diff --git a/src/ath-pthread.c b/src/ath-pthread.c
new file mode 100644 (file)
index 0000000..6f62511
--- /dev/null
@@ -0,0 +1,101 @@
+/* ath-pthread.c - pthread module for self-adapting thread-safeness library
+ *      Copyright (C) 2002 g10 Code GmbH
+ *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include "ath.h"
+
+/* Need to include pthread_create in our check, as the GNU C library
+   has the pthread_mutex_* functions in their public interface.  */
+#pragma weak pthread_create
+#pragma weak pthread_mutex_init
+#pragma weak pthread_mutex_destroy
+#pragma weak pthread_mutex_lock
+#pragma weak pthread_mutex_unlock
+
+/* The lock we take while checking for lazy lock initialization.  */
+static pthread_mutex_t check_init_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
+   it is not already initialized.  */
+static int
+mutex_pthread_init (void **priv, int just_check)
+{
+  int err = 0;
+
+  if (just_check)
+    pthread_mutex_lock (&check_init_lock);
+  if (!*priv || !just_check)
+    {
+      pthread_mutex_t *lock = malloc (sizeof (pthread_mutex_t));
+      if (!lock)
+       err = ENOMEM;
+      if (!err)
+       {
+         err = pthread_mutex_init (lock, NULL);
+         if (err)
+           free (lock);
+         else
+           *priv = lock;
+       }
+    }
+  if (just_check)
+    pthread_mutex_unlock (&check_init_lock);
+  return err;
+}
+
+
+static int
+mutex_pthread_destroy (void *priv)
+{
+  int err = pthread_mutex_destroy ((pthread_mutex_t *) priv);
+  free (priv);
+  return err;
+}
+
+
+static struct ath_ops ath_pthread_ops =
+  {
+    mutex_pthread_init,
+    mutex_pthread_destroy,
+    (int (*) (void *)) pthread_mutex_lock,
+    (int (*) (void *)) pthread_mutex_unlock,
+    NULL,      /* read */
+    NULL,      /* write */
+    NULL,      /* select */
+    NULL       /* waitpid */
+  };
+
+
+struct ath_ops *
+ath_pthread_available (void)
+{
+  /* Need to include pthread_create in our check, as the GNU C library
+     has the pthread_mutex_* functions in their public interface.  */
+  if (pthread_create
+      && pthread_mutex_init && pthread_mutex_destroy
+      && pthread_mutex_lock && pthread_mutex_unlock)
+    return &ath_pthread_ops;
+  else
+    return 0;
+}
diff --git a/src/ath.c b/src/ath.c
new file mode 100644 (file)
index 0000000..834a3ac
--- /dev/null
+++ b/src/ath.c
@@ -0,0 +1,153 @@
+/* ath.c - self-adapting thread-safeness library
+ *      Copyright (C) 2002 g10 Code GmbH
+ *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "ath.h"
+
+static struct ath_ops *ath_ops;
+
+void
+ath_init (void)
+{
+#ifdef HAVE_PTHREAD
+  if (!ath_ops)
+    ath_ops = ath_pthread_available ();
+#endif
+#ifdef HAVE_PTH
+  if (!ath_ops)
+    ath_ops = ath_pth_available ();
+#endif
+#ifdef HAVE_ATH_DUMMY
+  if (!ath_ops)
+    ath_ops = ath_dummy_available ();
+#endif
+}
+
+
+/* This function is in general not very useful but due to some
+   backward compatibiltiy we need ot for gcry_control
+   (GCRYCTL_DISABLE_INTERNAL_LOCKING). */
+void
+ath_deinit (void)
+{
+  /* fixme: We should deallocate the resource. */
+  ath_ops = NULL;
+}
+
+
+int
+ath_mutex_init (ath_mutex_t *lock)
+{
+  if (!ath_ops)
+    return 0;
+
+  return ath_ops->mutex_init (lock, 0);
+}
+
+
+int
+ath_mutex_destroy (ath_mutex_t *lock)
+{
+  int err;
+  if (!ath_ops)
+    return 0;
+  err = ath_ops->mutex_init (lock, 1);
+  if (!err)
+    err = ath_ops->mutex_destroy (*lock);
+  return err;
+}
+
+
+int
+ath_mutex_lock (ath_mutex_t *lock)
+{
+  int err;
+
+  if (!ath_ops)
+    return 0;
+  err = ath_ops->mutex_init (lock, 1);
+  if (!err)
+    err = ath_ops->mutex_lock (*lock);
+  return err;
+}
+
+
+int
+ath_mutex_unlock (ath_mutex_t *lock)
+{
+  int err;
+
+  if (!ath_ops)
+    return 0;
+  err = ath_ops->mutex_init (lock, 1);
+  if (!err)
+    err = ath_ops->mutex_unlock (*lock);
+  return err;
+}
+
+
+ssize_t
+ath_read (int fd, void *buf, size_t nbytes)
+{
+  if (ath_ops && ath_ops->read)
+    return ath_ops->read (fd, buf, nbytes);
+  else
+    return read (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_write (int fd, const void *buf, size_t nbytes)
+{
+  if (ath_ops && ath_ops->write)
+    return ath_ops->write (fd, buf, nbytes);
+  else
+    return write (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+           struct timeval *timeout)
+{
+  if (ath_ops && ath_ops->select)
+    return ath_ops->select (nfd, rset, wset, eset, timeout);
+  else
+    return select (nfd, rset, wset, eset, timeout);
+}
+
+ssize_t
+ath_waitpid (pid_t pid, int *status, int options)
+{
+  if (ath_ops && ath_ops->waitpid)
+    return ath_ops->waitpid (pid, status, options);
+  else
+    return waitpid (pid, status, options);
+}
diff --git a/src/ath.h b/src/ath.h
new file mode 100644 (file)
index 0000000..96b31d3
--- /dev/null
+++ b/src/ath.h
@@ -0,0 +1,89 @@
+/* ath.h - interfaces for self-adapting thread-safeness library
+ *      Copyright (C) 2002 g10 Code GmbH
+ *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef ATH_H
+#define ATH_H
+
+#include <sys/types.h>
+
+/* Define ATH_EXT_SYM_PREFIX if you want to give all external symbols
+   a prefix.  */
+#define ATH_EXT_SYM_PREFIX _gcry_
+
+#ifdef ATH_EXT_SYM_PREFIX
+#define ATH_PREFIX1(x,y) x ## y
+#define ATH_PREFIX2(x,y) ATH_PREFIX1(x,y)
+#define ATH_PREFIX(x) ATH_PREFIX2(ATH_EXT_SYM_PREFIX,x)
+#define ath_init ATH_PREFIX(ath_init)
+#define ath_mutex_init ATH_PREFIX(ath_mutex_init)
+#define ath_mutex_destroy ATH_PREFIX(ath_mutex_destroy)
+#define ath_mutex_lock ATH_PREFIX(ath_mutex_lock)
+#define ath_mutex_unlock ATH_PREFIX(ath_mutex_unlock)
+#define ath_read ATH_PREFIX(ath_read)
+#define ath_write ATH_PREFIX(ath_write)
+#define ath_select ATH_PREFIX(ath_select)
+#define ath_waitpid ATH_PREFIX(ath_waitpid)
+#define ath_pthread_available ATH_PREFIX(ath_pthread_available)
+#define ath_pth_available ATH_PREFIX(ath_pth_available)
+#endif
+
+\f
+typedef void *ath_mutex_t;
+#define ATH_MUTEX_INITIALIZER 0;
+
+/* Functions for mutual exclusion.  */
+int ath_mutex_init (ath_mutex_t *mutex);
+int ath_mutex_destroy (ath_mutex_t *mutex);
+int ath_mutex_lock (ath_mutex_t *mutex);
+int ath_mutex_unlock (ath_mutex_t *mutex);
+
+/* Replacement for the POSIX functions, which can be used to allow
+   other (user-level) threads to run.  */
+ssize_t ath_read (int fd, void *buf, size_t nbytes);
+ssize_t ath_write (int fd, const void *buf, size_t nbytes);
+ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+                   struct timeval *timeout);
+ssize_t ath_waitpid (pid_t pid, int *status, int options);
+
+\f
+struct ath_ops
+{
+  int (*mutex_init) (void **priv, int just_check);
+  int (*mutex_destroy) (void *priv);
+  int (*mutex_lock) (void *priv);
+  int (*mutex_unlock) (void *priv);
+  ssize_t (*read) (int fd, void *buf, size_t nbytes);
+  ssize_t (*write) (int fd, const void *buf, size_t nbytes);
+  ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+                    struct timeval *timeout);
+  ssize_t (*waitpid) (pid_t pid, int *status, int options);
+};
+
+/* Initialize the any-thread package.  */
+void ath_init (void);
+void ath_deinit (void);
+
+/* Used by ath_pkg_init.  */
+struct ath_ops *ath_pthread_available (void);
+struct ath_ops *ath_pth_available (void);
+struct ath_ops *ath_dummy_available (void);
+
+#endif /* ATH_H */
diff --git a/src/benchmark.c b/src/benchmark.c
new file mode 100644 (file)
index 0000000..42aeebf
--- /dev/null
@@ -0,0 +1,173 @@
+/* benchmark.c - for libgcrypt
+ *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/times.h>
+#include <gcrypt.h>
+
+#define PGM "benchmark"
+#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
+                 exit(2);} while(0)
+
+
+/* Helper for the start and stop timer. */
+static clock_t started_at, stopped_at;
+
+
+static void
+start_timer (void)
+{
+  struct tms tmp;
+
+  times (&tmp);
+  started_at = stopped_at = tmp.tms_utime;
+}
+
+static void
+stop_timer (void)
+{
+  struct tms tmp;
+
+  times (&tmp);
+  stopped_at = tmp.tms_utime;
+}
+
+static const char *
+elapsed_time (void)
+{
+  static char buf[50];
+
+  sprintf (buf, "%5.0fms",
+           (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000);
+  return buf;
+}
+
+
+static void
+random_bench (void)
+{
+  char buf[128];
+  int i;
+
+  printf ("%-10s", "random");
+
+  start_timer ();
+  for (i=0; i < 100; i++)
+    gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
+  stop_timer ();
+  printf (" %s", elapsed_time ());
+
+  start_timer ();
+  for (i=0; i < 100; i++)
+    gcry_randomize (buf, 8, GCRY_STRONG_RANDOM);
+  stop_timer ();
+  printf (" %s", elapsed_time ());
+
+  putchar ('\n');
+}
+
+
+
+static void
+md_bench ( const char *algoname )
+{
+  int algo = gcry_md_map_name (algoname);
+  GcryMDHd hd;
+  int i;
+  char buf[1000];
+
+  if (!algo)
+    {
+      fprintf (stderr, PGM ": invalid hash algorithm `%s'/n", algoname);
+      exit (1);
+    }
+  
+  hd = gcry_md_open (algo, 0);
+  if (!hd)
+    {
+      fprintf (stderr, PGM ": error opeing hash algorithm `%s'/n", algoname);
+      exit (1);
+    }
+
+  for (i=0; i < sizeof buf; i++)
+    buf[i] = i;
+
+  printf ("%-10s", gcry_md_algo_name (algo));
+
+  start_timer ();
+  for (i=0; i < 1000; i++)
+    gcry_md_write (hd, buf, sizeof buf);
+  gcry_md_final (hd);
+  stop_timer ();
+  printf (" %s", elapsed_time ());
+
+  gcry_md_reset (hd);
+  start_timer ();
+  for (i=0; i < 10000; i++)
+    gcry_md_write (hd, buf, sizeof buf/10);
+  gcry_md_final (hd);
+  stop_timer ();
+  printf (" %s", elapsed_time ());
+
+  gcry_md_reset (hd);
+  start_timer ();
+  for (i=0; i < 1000000; i++)
+    gcry_md_write (hd, "", 1);
+  gcry_md_final (hd);
+  stop_timer ();
+  printf (" %s", elapsed_time ());
+
+  gcry_md_close (hd);
+  putchar ('\n');
+}
+
+int
+main( int argc, char **argv )
+{
+  if (argc < 2 )
+    {
+      fprintf (stderr, "usage: benchmark md [algonames]\n");
+      return 1;
+    }
+  argc--; argv++;
+  
+  gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
+
+  if ( !strcmp (*argv, "random"))
+    {
+      random_bench ();
+    }
+  else if ( !strcmp (*argv, "md"))
+    {
+      for (argc--, argv++; argc; argc--, argv++)
+        md_bench ( *argv );
+    }
+  else
+    {
+      fprintf (stderr, PGM ": bad arguments\n");
+      return 1;
+    }
+  
+  return 0;
+}
+