This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] PowerPC - Add a faster way to get the thread id
- From: Edjunior Barbosa Machado <emachado at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Cc: rsa at us dot ibm dot com
- Date: Mon, 5 Nov 2012 16:44:32 -0200
- Subject: [PATCH] PowerPC - Add a faster way to get the thread id
This patch adds an alternative way to get the thread id without having to make a
costly syscall(), retrieving it from the TLS area.
Please consider this patch for GLIBC 2.17.
Thanks and regards,
--
Edjunior
ChangeLog
2012-11-05 David Flaherty <flaherty@linux.vnet.ibm.com>
Edjunior Machado <emachado@linux.vnet.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/Makefile: Add gettid and
tst-gettid.
* sysdeps/unix/sysv/linux/powerpc/bits/ppc.h (__ppc_gettid): New
prototype.
* sysdeps/unix/sysv/linux/powerpc/gettid.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions (GLIBC_2.17): Add
the new function.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
(GLIBC_2.17): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
(GLIBC_2.17): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
(GLIBC_2.17): Likewise.
* sysdeps/unix/sysv/linux/powerpc/tst-gettid.c: New file.
ports/ChangeLog.powerpc
2012-11-05 David Flaherty <flaherty@linux.vnet.ibm.com>
Edjunior Machado <emachado@linux.vnet.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
(GLIB_2.17): Add __ppc_gettid.
---
.../powerpc/powerpc32/nofpu/nptl/libc.abilist | 1 +
sysdeps/unix/sysv/linux/powerpc/Makefile | 4 +
sysdeps/unix/sysv/linux/powerpc/bits/ppc.h | 5 +
sysdeps/unix/sysv/linux/powerpc/gettid.c | 29 +++++++
sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions | 1 +
.../linux/powerpc/powerpc32/fpu/nptl/libc.abilist | 1 +
sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions | 1 +
.../sysv/linux/powerpc/powerpc64/nptl/libc.abilist | 1 +
sysdeps/unix/sysv/linux/powerpc/tst-gettid.c | 87 ++++++++++++++++++++
9 files changed, 130 insertions(+), 0 deletions(-)
create mode 100644 sysdeps/unix/sysv/linux/powerpc/gettid.c
create mode 100644 sysdeps/unix/sysv/linux/powerpc/tst-gettid.c
diff --git a/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
index 0efc6b5..f9a646b 100644
--- a/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
@@ -1775,6 +1775,7 @@ GLIBC_2.16
GLIBC_2.17
GLIBC_2.17 A
__ppc_get_timebase_freq F
+ __ppc_gettid F
clock_getcpuclockid F
clock_getres F
clock_gettime F
diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
index 4ff7e84..7a78336 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -22,3 +22,7 @@ sysdep_headers += bits/ppc.h
sysdep_routines += get_timebase_freq
tests += test-gettimebasefreq
endif
+
+sysdep_routines += gettid
+tests += tst-gettid
+$(objpfx)tst-gettid: $(shared-thread-library)
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h b/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h
index 76542d9..cbac71b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h
@@ -23,11 +23,16 @@
# error "Never include this file directly; use <sys/platform/ppc.h> instead."
#endif
+#include <sys/types.h>
+
__BEGIN_DECLS
/* Read the time base frequency. */
extern uint64_t __ppc_get_timebase_freq (void);
+/* Get the Thread id. */
+extern pid_t __ppc_gettid (void);
+
__END_DECLS
#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettid.c b/sysdeps/unix/sysv/linux/powerpc/gettid.c
new file mode 100644
index 0000000..0803658
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/gettid.c
@@ -0,0 +1,29 @@
+/* Non-syscall version of gettid.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library 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.
+
+ The GNU C Library 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 the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdint.h>
+#include <libc-internal.h>
+#include <sys/types.h>
+#include <tls.h>
+
+static inline pid_t
+__gettid(void)
+{
+ return THREAD_GETMEM (THREAD_SELF, tid);
+}
+weak_alias (__gettid, __ppc_gettid)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions b/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
index 8d1c3a5..47e72ea 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
@@ -32,5 +32,6 @@ libc {
}
GLIBC_2.17 {
__ppc_get_timebase_freq;
+ __ppc_gettid;
}
}
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
index 8e45958..a93223f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
@@ -1775,6 +1775,7 @@ GLIBC_2.16
GLIBC_2.17
GLIBC_2.17 A
__ppc_get_timebase_freq F
+ __ppc_gettid F
clock_getcpuclockid F
clock_getres F
clock_gettime F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions b/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
index 3ff01d1..6f44016 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
@@ -21,5 +21,6 @@ libc {
}
GLIBC_2.17 {
__ppc_get_timebase_freq;
+ __ppc_gettid;
}
}
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
index 8eaaccd..4e93772 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
@@ -81,6 +81,7 @@ GLIBC_2.16
GLIBC_2.17
GLIBC_2.17 A
__ppc_get_timebase_freq F
+ __ppc_gettid F
clock_getcpuclockid F
clock_getres F
clock_gettime F
diff --git a/sysdeps/unix/sysv/linux/powerpc/tst-gettid.c b/sysdeps/unix/sysv/linux/powerpc/tst-gettid.c
new file mode 100644
index 0000000..13467a2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/tst-gettid.c
@@ -0,0 +1,87 @@
+/* Test for __ppc_gettid ()
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library 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.
+
+ The GNU C Library 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 the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <syscall.h>
+
+#include <sys/platform/ppc.h>
+
+#define NUM_THREADS 100
+
+void * threadfunc (void *);
+
+void *
+threadfunc (void *arg)
+{
+ pid_t tid = __ppc_gettid ();
+ pid_t syscalltid = syscall (__NR_gettid);
+ printf ("\ttid is %d\n",tid);
+ printf ("\tsystid is %d\n",syscalltid);
+ if (tid != syscalltid)
+ {
+ printf ("ERROR: Thread id does not match the syscall value\n");
+ return (void *) 1l;
+ }
+ return NULL;
+}
+
+int
+main (void)
+{
+ void *res;
+ int i, retval = 0;
+ pthread_t *threads;
+ pid_t syscalltid = syscall (__NR_gettid);
+ pid_t tid = __ppc_gettid ();
+ pid_t id2 = getpid ();
+ printf ("pid is %d\n",id2);
+ printf ("\ttid is %d\n",tid);
+ printf ("\tsystid is %d\n",syscalltid);
+ printf ("*************************\n");
+
+ threads = (pthread_t *) malloc (NUM_THREADS * sizeof (*threads));
+
+ for (i = 0; i < NUM_THREADS; i++)
+ {
+ pthread_create (&threads[i],NULL,threadfunc,NULL);
+ }
+
+ /* Give the threads time to finish */
+ sleep(3);
+
+ /* Wait for all threads. */
+ res = malloc (sizeof (int));
+ for (i = 0; i < NUM_THREADS; i++)
+ {
+ pthread_join (threads[i], &res);
+ retval |= (res != NULL);
+ }
+
+ if (retval == 0)
+ printf ("tst-gettid passed\n");
+ else
+ printf ("tst-gettid FAILED\n");
+
+ exit (retval);
+}
--
1.7.1