summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2002-09-17 12:41:14 +0000
committerWerner Koch <wk@gnupg.org>2002-09-17 12:41:14 +0000
commitc2fa23b3f0a1fcaa3fe511c97e17ff20f32b6689 (patch)
tree58f219eb66f3a4d5c289fde76bacc482d5dbab38 /src
parentd16c3b00274abf168053952354c85b60c1f448ac (diff)
downloadlibgcrypt-c2fa23b3f0a1fcaa3fe511c97e17ff20f32b6689.tar.gz
* ath.c, ath.h, ath-pth.c, ath-pthread.c: New. Taken from GPGME.
* mutex.h: Removed. * Makefile.am (ath_components): New.
Diffstat (limited to 'src')
-rw-r--r--src/ath-pth.c118
-rw-r--r--src/ath-pthread.c101
-rw-r--r--src/ath.c153
-rw-r--r--src/ath.h89
-rw-r--r--src/benchmark.c173
5 files changed, 634 insertions, 0 deletions
diff --git a/src/ath-pth.c b/src/ath-pth.c
new file mode 100644
index 00000000..8f236a7f
--- /dev/null
+++ b/src/ath-pth.c
@@ -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
index 00000000..6f62511b
--- /dev/null
+++ b/src/ath-pthread.c
@@ -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
index 00000000..834a3ac7
--- /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
index 00000000..96b31d3b
--- /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
+
+
+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);
+
+
+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
index 00000000..42aeebf3
--- /dev/null
+++ b/src/benchmark.c
@@ -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;
+}
+