diff options
author | Werner Koch <wk@gnupg.org> | 2002-09-17 12:41:14 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2002-09-17 12:41:14 +0000 |
commit | c2fa23b3f0a1fcaa3fe511c97e17ff20f32b6689 (patch) | |
tree | 58f219eb66f3a4d5c289fde76bacc482d5dbab38 /src | |
parent | d16c3b00274abf168053952354c85b60c1f448ac (diff) | |
download | libgcrypt-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.c | 118 | ||||
-rw-r--r-- | src/ath-pthread.c | 101 | ||||
-rw-r--r-- | src/ath.c | 153 | ||||
-rw-r--r-- | src/ath.h | 89 | ||||
-rw-r--r-- | src/benchmark.c | 173 |
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; +} + |