summaryrefslogtreecommitdiff
path: root/gprofng/testsuite/gprofng.display/synprog/callso.c
diff options
context:
space:
mode:
Diffstat (limited to 'gprofng/testsuite/gprofng.display/synprog/callso.c')
-rw-r--r--gprofng/testsuite/gprofng.display/synprog/callso.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/gprofng/testsuite/gprofng.display/synprog/callso.c b/gprofng/testsuite/gprofng.display/synprog/callso.c
new file mode 100644
index 00000000000..6ff5c99d753
--- /dev/null
+++ b/gprofng/testsuite/gprofng.display/synprog/callso.c
@@ -0,0 +1,152 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+ Contributed by Oracle.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <string.h>
+#include "stopwatch.h"
+
+
+#define DYNSOROUTINE "so_cputime"
+#define DYNSONAME "./so_syn.so"
+
+/* callso -- dynamically link a shared object, and call a routine in it */
+
+#ifndef NONSHARED
+
+static void *so_object = NULL;
+static void closeso (void);
+
+int
+callso (int k)
+{
+ int i;
+ char buf[1024];
+ char *p;
+ char *q = DYNSONAME;
+ int errnum;
+
+ hrtime_t start = gethrtime ();
+ hrtime_t vstart = gethrvtime ();
+
+ /* Log the event */
+ wlog ("start of callso", NULL);
+
+ /* see if already linked */
+ if (so_object != NULL)
+ {
+ fprintf (stderr, "Execution error -- callso: so_object already linked\n");
+ return 0;
+ }
+
+ /* open the dynamic shared object */
+ so_object = NULL;
+ while (so_object == NULL)
+ {
+ so_object = dlopen (DYNSONAME, RTLD_NOW);
+ if (so_object != NULL)
+ break;
+ p = dlerror ();
+ if (q == NULL)
+ q = "DYNSONAME";
+ if (p == NULL)
+ p = "dlerror() returns NULL";
+ errnum = errno;
+ if (errnum == EINTR)
+ continue; /* retry */
+ else
+ {
+ fprintf (stderr, "Execution error -- callso: dlopen of %s failed--%s, errno=%d (%s)\n",
+ q, p, errnum, strerror (errnum));
+ return (0);
+ }
+ }
+
+ /* look up the routine name in it */
+ int (*so_routine)() = (int (*)())dlsym (so_object, DYNSOROUTINE);
+ if (so_routine == NULL)
+ {
+ fprintf (stderr, "Execution error -- callso: dlsym %s not found\n",
+ DYNSOROUTINE);
+ return (0);
+ }
+
+ /* invoke the routine */
+ long long count = 0;
+ do
+ {
+ i = (*so_routine)();
+ count++;
+ }
+ while (start + testtime * 1e9 > gethrtime ());
+
+ closeso ();
+ sprintf (buf, "end of callso, %s returned %d", DYNSOROUTINE, i);
+ wlog (buf, NULL);
+ fprintf (stderr, " Performed %lld while-loop iterations\n", count);
+ whrvlog ((gethrtime () - start), (gethrvtime () - vstart), "callso", NULL);
+ return 0;
+}
+
+/* closeso -- close a DSO */
+void
+closeso (void)
+{
+ /* Log the event */
+ wlog ("start of closeso", NULL);
+
+ /* ensure already linked */
+ if (so_object == NULL)
+ {
+ fprintf (stderr, "Execution error -- closeso: so_object not linked\n");
+ return;
+ }
+
+ /* close the dynamic shared object */
+ int rc = dlclose (so_object);
+ if (rc != 0)
+ {
+ fprintf (stderr, "Execution error -- closeso: dlclose() failed--%s\n",
+ dlerror ());
+ return;
+ }
+
+ /* clear the pointer */
+ so_object = NULL;
+ wlog ("end of closeso", NULL);
+ return;
+}
+
+#else /* NONSHARED */
+
+int
+callso (int i)
+{
+ return 0;
+}
+
+void
+closeso (void)
+{
+ return;
+}
+#endif /* NONSHARED */