diff mbox

[RFC] Add C11 threads.h support.

Message ID CAD82F-pXPRnsxLtT2pTADWkjsV=m6xA7cDuMX6J_bXW+c=HsVA@mail.gmail.com
State New
Headers show

Commit Message

Juan Manuel Torres Palma June 26, 2015, 5:26 p.m. UTC
Dear glibc developers,

As I am preparing what I think that could be my last patch to have C11
threads.h working, I still have a couple doubts to be solved.

First, I would like any of you to review this patch and let me know if
my approach is correct, by separating types in bits/threadstypes.h
from functions in include/threads.h.

Second, I have noticed that there are files that I haven't updated,
that I think that I should. Those files are libpthread.abilist, and I
don't know how should I do it. Should I do it manually? Or is there a
script to get the symbols from the library once it's compiled.

Thanks for your time.
Cheers.

Comments

Joseph Myers June 26, 2015, 9:22 p.m. UTC | #1
On Fri, 26 Jun 2015, Juan Manuel Torres Palma wrote:

> Dear glibc developers,
> 
> As I am preparing what I think that could be my last patch to have C11
> threads.h working, I still have a couple doubts to be solved.
> 
> First, I would like any of you to review this patch and let me know if
> my approach is correct, by separating types in bits/threadstypes.h
> from functions in include/threads.h.

I'm not sure it's useful without any targets that would define the types 
differently; I think bits/ headers are only needed where there are such 
target-dependencies (so bits/thread-shared-types.h is needed, but maybe 
not bits/threadstypes.h).

> Second, I have noticed that there are files that I haven't updated,
> that I think that I should. Those files are libpthread.abilist, and I
> don't know how should I do it. Should I do it manually? Or is there a
> script to get the symbols from the library once it's compiled.

You should update libpthread.abilist (all copies).  If you examine the 
diffs from "make check-abi" and confirm they are as expected, you can 
apply them to the copy of libpthread.abilist used in your configuration, 
and then copy the same entries to all other copies.

The patch should also add documentation and testcases for all the 
functions, as well as updating the conform/ tests to cover the new header.

> +/* Declaration of C11 threads.h types. All of the types are based
> +   on pthread types to ease implementation and compatibility. 
> +   Most of these types can be consulted in Linux Standard Base
> +   Specifications. */

I don't think LSB should be referred to in glibc headers.  Also note ".  "
(dot, two spaces) at the end of comments.

> +#ifndef __STDC_NO_THREADS__

No such conditional needed.  __STDC_NO_THREADS__ should never be defined 
once this support is in.

> +//#if ( defined __STDC_VERSION__ && __STDC_VERSION__ < 201112L )
> +//# error "<threads.h> requires ISO C11 mode"
> +//#else

Don't include such commented-out code.

> +# ifdef __cplusplus
> +__BEGIN_DECLS
> +# endif

No __cplusplus here, since __BEGIN_DECLS / __END_DECLS are defined to 
empty for non-C++.

> +/* Threads functions */
> +extern int thrd_create (thrd_t *thr, thrd_start_t func, void *arg );

Each function should have a comment explaining its semantics in the 
header.  Argument names need to be in the implementation namespace (the 
conform/ tests will tell you if you get this wrong, once you've added 
threads.h data to them).  Stray space before ')'.

> +void call_once (once_flag *flag, void (*func)(void))

Bad formatting for function definition.  The return type goes on the line 
before the name, and there should be a comment explaining the semantics of 
the function and its arguments.

> +{
> +  pthread_once (flag, func);

You need to call the implementation-namespace names such as 
__pthread_once.  It's not enough that they exist if you then use the other 
names for those functions; you must avoid any strong references (defined 
or undefined) to names outside the C11 and implementation namespaces (and 
any uses of weak undefined symbols outside those namespaces that might get 
executed for conforming code).
Juan Manuel Torres Palma June 27, 2015, 3:04 p.m. UTC | #2
> I'm not sure it's useful without any targets that would define the types
> differently; I think bits/ headers are only needed where there are such
> target-dependencies (so bits/thread-shared-types.h is needed, but maybe
> not bits/threadstypes.h).

I have moved it to nptl/threadstypes.h now.

> You should update libpthread.abilist (all copies).  If you examine the
> diffs from "make check-abi" and confirm they are as expected, you can
> apply them to the copy of libpthread.abilist used in your configuration,
> and then copy the same entries to all other copies.
>
> The patch should also add documentation and testcases for all the
> functions, as well as updating the conform/ tests to cover the new header.

Works well, but it fails. I guess this is what I should expect because
the generated ABI with new symbols doesn't match with the ABI defined
in libpthread.abilist. However I get a symbol that I'm not really sure
of. It's _nl_default_dirname, that was originally defined to 0x12 and
after building it's defined to 0x43. Reading ChangeLog I couldn't
really get an idea of what this symbol is for.

> Each function should have a comment explaining its semantics in the
> header.  Argument names need to be in the implementation namespace (the
> conform/ tests will tell you if you get this wrong, once you've added
> threads.h data to them).  Stray space before ')'.

I have done this too, but I don't understand why argument names need
to be preceded of "__" in this case. I have seen it in other header
files, but why? I thought the assembler only cares about the types
defined in the function prototype.

> You need to call the implementation-namespace names such as
> __pthread_once.  It's not enough that they exist if you then use the other
> names for those functions; you must avoid any strong references (defined
> or undefined) to names outside the C11 and implementation namespaces (and
> any uses of weak undefined symbols outside those namespaces that might get
> executed for conforming code).

I don't get this point either. I thought this code will be executing
inside the library, where __pthread_* symbols are exactly the same
than pthread_* symbols. So, if the user redefines pthread_* symbols
(He's a llowed to do that), won't affect symbols inside library. Am I
wrong?

Thanks for your help.
Cheers.
Rich Felker June 27, 2015, 6:51 p.m. UTC | #3
On Sat, Jun 27, 2015 at 05:04:26PM +0200, Juan Manuel Torres Palma wrote:
> > You need to call the implementation-namespace names such as
> > __pthread_once.  It's not enough that they exist if you then use the other
> > names for those functions; you must avoid any strong references (defined
> > or undefined) to names outside the C11 and implementation namespaces (and
> > any uses of weak undefined symbols outside those namespaces that might get
> > executed for conforming code).
> 
> I don't get this point either. I thought this code will be executing
> inside the library, where __pthread_* symbols are exactly the same
> than pthread_* symbols. So, if the user redefines pthread_* symbols
> (He's a llowed to do that), won't affect symbols inside library. Am I
> wrong?

Yes, you're wrong about this. pthread_* are not reserved in a plain C
program that does not use POSIX; an application can define them (or
any other POSIX symbols that aren't in plain C) for any purpose it
wants.

There is no such thing as "inside the library" except possibly as a
linking optimization for shared libraries. With an archive (static)
library, object files from the library have no special status distinct
from object files provided by the program or third-party libraries.

Rich
Joseph Myers June 29, 2015, 2:30 p.m. UTC | #4
On Sat, 27 Jun 2015, Juan Manuel Torres Palma wrote:

> > I'm not sure it's useful without any targets that would define the types
> > differently; I think bits/ headers are only needed where there are such
> > target-dependencies (so bits/thread-shared-types.h is needed, but maybe
> > not bits/threadstypes.h).
> 
> I have moved it to nptl/threadstypes.h now.

I don't think a separate header is needed at all.  Just define the types 
directly in threads.h unless either (a) different definitions are needed 
on different systems or (b) the same type definitions need sharing between 
more than one public header.  If either of those becomes true, put the 
relevant definitions in a bits/ header (any non-public headers - headers 
users should not include directly - should be in bits/).

> Works well, but it fails. I guess this is what I should expect because
> the generated ABI with new symbols doesn't match with the ABI defined
> in libpthread.abilist. However I get a symbol that I'm not really sure
> of. It's _nl_default_dirname, that was originally defined to 0x12 and
> after building it's defined to 0x43. Reading ChangeLog I couldn't
> really get an idea of what this symbol is for.

This indicates you didn't configure with --prefix=/usr.  Configuring with 
a different prefix breaks the ABI (see bug 14664).  So always configure 
--prefix=/usr (and then set install_root=/some/where to install under 
/some/where when installing).

> > Each function should have a comment explaining its semantics in the
> > header.  Argument names need to be in the implementation namespace (the
> > conform/ tests will tell you if you get this wrong, once you've added
> > threads.h data to them).  Stray space before ')'.
> 
> I have done this too, but I don't understand why argument names need
> to be preceded of "__" in this case. I have seen it in other header
> files, but why? I thought the assembler only cares about the types
> defined in the function prototype.

Because "thr", for example, is in the user's namespace, the user can 
legitimately do

#define thr ** break this **
#include <threads.h>

which would break if "thr" is used as an argument name in threads.h.  So 
installed headers need to be namespace-clean in terms of the set of 
identifiers appearing as preprocessing tokens in the header - regardless 
of the syntactic position in which those preprocessing tokens appear.

> > You need to call the implementation-namespace names such as
> > __pthread_once.  It's not enough that they exist if you then use the other
> > names for those functions; you must avoid any strong references (defined
> > or undefined) to names outside the C11 and implementation namespaces (and
> > any uses of weak undefined symbols outside those namespaces that might get
> > executed for conforming code).
> 
> I don't get this point either. I thought this code will be executing
> inside the library, where __pthread_* symbols are exactly the same
> than pthread_* symbols. So, if the user redefines pthread_* symbols
> (He's a llowed to do that), won't affect symbols inside library. Am I
> wrong?

If you call a function in the user's namespace, it's a problem (a) for 
static linking, (b) for calls from one shared library to another and (c) 
for calls within a shared library if they go via the PLT.  (In the last 
case, for most functions you'd also get a failure from elf/check-localplt 
if you accidentally introduce new PLT references, but the hidden_proto / 
hidden_def mechanism can be used to avoid PLT references, if the call 
would otherwise be OK for static linking.  I take it you ran the full 
glibc testsuite before and after your patch and made sure there were no 
new failures?  In the case of (a), adding threads.h to the conform/ tests 
will ensure the testsuite checks the namespace for you.)
Juan Manuel Torres Palma June 30, 2015, 4:53 p.m. UTC | #5
I get all of your points now, it's unbelievable how much I'm learning
during the process, thanks for your guidance.

After running the testsuite I'm getting error regarding the
linknamespace test and conform test. Conform tests errors don't make
me worry that much because they seem to appear on other headers too
and are being ignored. However, in linknamespace test appear a lot of
new functions that I didn't even think about that seem to be in user's
namespace.

I attach my threads.h-data, linknamespace.out and conform.out for some feedback.

Cheers.

2015-06-29 16:30 GMT+02:00 Joseph Myers <joseph@codesourcery.com>:
> On Sat, 27 Jun 2015, Juan Manuel Torres Palma wrote:
>
>> > I'm not sure it's useful without any targets that would define the types
>> > differently; I think bits/ headers are only needed where there are such
>> > target-dependencies (so bits/thread-shared-types.h is needed, but maybe
>> > not bits/threadstypes.h).
>>
>> I have moved it to nptl/threadstypes.h now.
>
> I don't think a separate header is needed at all.  Just define the types
> directly in threads.h unless either (a) different definitions are needed
> on different systems or (b) the same type definitions need sharing between
> more than one public header.  If either of those becomes true, put the
> relevant definitions in a bits/ header (any non-public headers - headers
> users should not include directly - should be in bits/).
>
>> Works well, but it fails. I guess this is what I should expect because
>> the generated ABI with new symbols doesn't match with the ABI defined
>> in libpthread.abilist. However I get a symbol that I'm not really sure
>> of. It's _nl_default_dirname, that was originally defined to 0x12 and
>> after building it's defined to 0x43. Reading ChangeLog I couldn't
>> really get an idea of what this symbol is for.
>
> This indicates you didn't configure with --prefix=/usr.  Configuring with
> a different prefix breaks the ABI (see bug 14664).  So always configure
> --prefix=/usr (and then set install_root=/some/where to install under
> /some/where when installing).
>
>> > Each function should have a comment explaining its semantics in the
>> > header.  Argument names need to be in the implementation namespace (the
>> > conform/ tests will tell you if you get this wrong, once you've added
>> > threads.h data to them).  Stray space before ')'.
>>
>> I have done this too, but I don't understand why argument names need
>> to be preceded of "__" in this case. I have seen it in other header
>> files, but why? I thought the assembler only cares about the types
>> defined in the function prototype.
>
> Because "thr", for example, is in the user's namespace, the user can
> legitimately do
>
> #define thr ** break this **
> #include <threads.h>
>
> which would break if "thr" is used as an argument name in threads.h.  So
> installed headers need to be namespace-clean in terms of the set of
> identifiers appearing as preprocessing tokens in the header - regardless
> of the syntactic position in which those preprocessing tokens appear.
>
>> > You need to call the implementation-namespace names such as
>> > __pthread_once.  It's not enough that they exist if you then use the other
>> > names for those functions; you must avoid any strong references (defined
>> > or undefined) to names outside the C11 and implementation namespaces (and
>> > any uses of weak undefined symbols outside those namespaces that might get
>> > executed for conforming code).
>>
>> I don't get this point either. I thought this code will be executing
>> inside the library, where __pthread_* symbols are exactly the same
>> than pthread_* symbols. So, if the user redefines pthread_* symbols
>> (He's a llowed to do that), won't affect symbols inside library. Am I
>> wrong?
>
> If you call a function in the user's namespace, it's a problem (a) for
> static linking, (b) for calls from one shared library to another and (c)
> for calls within a shared library if they go via the PLT.  (In the last
> case, for most functions you'd also get a failure from elf/check-localplt
> if you accidentally introduce new PLT references, but the hidden_proto /
> hidden_def mechanism can be used to avoid PLT references, if the call
> would otherwise be OK for static linking.  I take it you ran the full
> glibc testsuite before and after your patch and made sure there were no
> new failures?  In the case of (a), adding threads.h to the conform/ tests
> will ensure the testsuite checks the namespace for you.)
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
Joseph Myers June 30, 2015, 5:22 p.m. UTC | #6
On Tue, 30 Jun 2015, Juan Manuel Torres Palma wrote:

> I get all of your points now, it's unbelievable how much I'm learning
> during the process, thanks for your guidance.
> 
> After running the testsuite I'm getting error regarding the
> linknamespace test and conform test. Conform tests errors don't make
> me worry that much because they seem to appear on other headers too
> and are being ignored. However, in linknamespace test appear a lot of
> new functions that I didn't even think about that seem to be in user's
> namespace.
> 
> I attach my threads.h-data, linknamespace.out and conform.out for some 
> feedback.

Most conform tests failures should be straightforward to fix.  Note that 
the results are currently clear for all ISO C versions; it's only other 
standards for which they haven't been fully cleaned up yet.  You have 
errors for the types of thrd_create and thrd_exit.  So check the types in 
both the header and the expectations.

In the case of thrd_create, it seems you have the wrong type for the first 
argument in threads.h-data.  In the case of thrd_exit, there may be a 
trickier issue involved - try declaring it in the header using 
__attribute__ ((__noreturn__)) as done for other non-returning functions 
in standard headers, instead of _Noreturn - this is compatible with C11 
_Noreturn but the conform tests avoid it causing problems with typeof (for 
GNU C typeof, non-returning counts as part of the function's type, which 
affects how the tests for types of functions work).

For the linknamespace tests, you'll need to investigate why all the lines 
such as

[initial] thrd_create

appear - this indicates something odd going on with the testsuite.  
Functions such as thrd_create should, given the makefile changes to add 
threads.h to the headers for C11, appear in the generated symlist-ISO11 as 
being in the implementation namespace for C11.  So you'll need to look at 
why list-header-symbols.pl, passed a list of headers including threads.h, 
failed to generate output indicating that those symbols are allowed (or 
why, if listed as allowed, they still show up as failing).

Then, having resolved that issue so that linknamespace.out only lists 
symbols (the last symbol listed on each line is the one that the testsuite 
thinks is problematic) that reflect genuine bugs, each of those will need 
resolving, by making the relevant code call implementation-namespace 
versions.  For example, pthread_create will need to call various 
__pthread_* functions instead of plain pthread_*.
diff mbox

Patch

commit f3b281bfa2b5d3ec80b8a1ba9988fc1dbf45c3a1
Author: Juan Manuel Torres Palma <jmtorrespalma@gmail.com>
Date:   Fri Jun 26 18:43:32 2015 +0200

    Add C11 threads.h support.
    
    This patch adds complete support for header threads.h including all
    functions and types as specified in C11 standard (ISO/IEC 9899:2011).
    All functions and types are based on POSIX threads to simplify
    implementation and design.

diff --git a/bits/threadstypes.h b/bits/threadstypes.h
new file mode 100644
index 0000000..cd9f647
--- /dev/null
+++ b/bits/threadstypes.h
@@ -0,0 +1,69 @@ 
+/* Copyright (C) 2002-2015 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/>.  */
+
+
+/* Declaration of C11 threads.h types. All of the types are based
+   on pthread types to ease implementation and compatibility. 
+   Most of these types can be consulted in Linux Standard Base
+   Specifications. */
+
+#ifndef _BITS_THREADSTYPES_H
+# define _BITS_THREADSTYPES_H	1
+
+# include <bits/thread-shared-types.h>
+
+# define ONCE_FLAG_INIT 0 
+# define thread_local _Thread_local 
+# define TSS_DTOR_ITERATIONS 4 
+
+typedef unsigned long int thrd_t;      /* Based on pthread_t */
+typedef int once_flag;                 /* Based on pthread_once_t */
+typedef unsigned int tss_t;            /* Based on pthread_key_t */
+typedef int (*thrd_start_t) (void*);
+typedef void (*tss_dtor_t) (void*); 
+
+/* Exit and error codes */
+enum
+{
+  thrd_success  = 0,
+  thrd_busy     = 1,
+  thrd_error    = 2,
+  thrd_nomem    = 3,
+  thrd_timedout = 4
+};
+
+/* Kinds of mutexes */
+enum
+{
+  mtx_plain     = 0,
+  mtx_recursive = 1,
+  mtx_timed     = 2
+};
+
+/* Definition of mtx_t based on pthread_mutex_t. */
+typedef union
+{
+  __PTHREAD_MUTEX_T_CONTENT
+} mtx_t;
+
+/* Definition of cnd_t based on pthread_cond_t. */
+typedef union
+{
+  __PTHREAD_COND_T_CONTENT
+} cnd_t;
+
+#endif /* bits/threadstypes.h */
diff --git a/include/stdc-predef.h b/include/stdc-predef.h
index e5f1139..1a5d899 100644
--- a/include/stdc-predef.h
+++ b/include/stdc-predef.h
@@ -58,7 +58,5 @@ 
    published.  */
 #define __STDC_ISO_10646__		201304L
 
-/* We do not support C11 <threads.h>.  */
-#define __STDC_NO_THREADS__		1
 
 #endif
diff --git a/include/threads.h b/include/threads.h
new file mode 100644
index 0000000..465ab08
--- /dev/null
+++ b/include/threads.h
@@ -0,0 +1,85 @@ 
+/* Copyright (C) 2015 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/>.  */
+
+/*
+ *  ISO C11 Standard: 7.26
+ *  Thread support library   <threads.h>
+ */
+
+
+#ifndef _THREADS_H
+#define _THREADS_H	1
+
+#include <features.h>
+
+#ifndef __STDC_NO_THREADS__
+
+# include <time.h>
+# include <bits/threadstypes.h>
+
+//#if ( defined __STDC_VERSION__ && __STDC_VERSION__ < 201112L )
+//# error "<threads.h> requires ISO C11 mode"
+//#else
+
+# ifdef __cplusplus
+__BEGIN_DECLS
+# endif
+
+/* Threads functions */
+extern int thrd_create (thrd_t *thr, thrd_start_t func, void *arg );
+extern int thrd_equal (thrd_t lhs, thrd_t rhs);
+extern thrd_t thrd_current (void);
+extern int thrd_sleep (const struct timespec *time_point,
+               struct timespec *remaining);
+extern _Noreturn void thrd_exit (int res);
+extern int thrd_detach (thrd_t thr);
+extern int thrd_join (thrd_t thr, int *res);
+extern void thrd_yield (void);
+
+/* Mutex functions */
+extern int mtx_init (mtx_t *mutex, int type);
+extern int mtx_lock (mtx_t *mutex);
+extern int mtx_timedlock (mtx_t *__restrict mutex,
+              const struct timespec *__restrict time_point);
+extern int mtx_trylock (mtx_t *mutex);
+extern int mtx_unlock (mtx_t *mutex);
+extern void mtx_destroy (mtx_t *mutex);
+extern void call_once (once_flag *flag, void (*func)(void));
+
+/* Condition variable functions */
+extern int cnd_init (cnd_t *cond);
+extern int cnd_signal (cnd_t *cond);
+extern int cnd_broadcast (cnd_t *cond);
+extern int cnd_wait (cnd_t *cond, mtx_t *mutex);
+extern int cnd_timedwait (cnd_t *__restrict cond,
+    mtx_t *__restrict mutex,
+    const struct timespec *__restrict time_point);
+extern void cnd_destroy (cnd_t *cond);
+
+/* Thread specific storage functions */
+extern int tss_create (tss_t *tss_id, tss_dtor_t destructor);
+extern void *tss_get (tss_t tss_id);
+extern int tss_set (tss_t tss_id, void *val);
+extern void tss_delete (tss_t tss_id);
+
+# ifdef __cplusplus
+__END_DECLS
+# endif
+
+//#endif /* Version check */
+#endif /* __STDC_NO_THREADS__ */
+#endif /* _THREADS_H */
diff --git a/nptl/Makefile b/nptl/Makefile
index 530d14b..ea67f6f 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -22,7 +22,8 @@  subdir	:= nptl
 
 include ../Makeconfig
 
-headers := pthread.h semaphore.h bits/semaphore.h
+headers := pthread.h semaphore.h bits/semaphore.h \
+	   threads.h bits/threadstypes.h
 
 extra-libs := libpthread
 extra-libs-others := $(extra-libs)
@@ -132,7 +133,15 @@  libpthread-routines = nptl-init vars events version pt-interp \
 		      pthread_mutex_getprioceiling \
 		      pthread_mutex_setprioceiling \
 		      pthread_setname pthread_getname \
-		      pthread_setattr_default_np pthread_getattr_default_np
+		      pthread_setattr_default_np pthread_getattr_default_np \
+			  thrd_create thrd_current thrd_detach thrd_equal \
+			  thrd_exit thrd_join thrd_sleep thrd_yield \
+			  call_once cnd_broadcast cnd_destroy cnd_init \
+			  cnd_signal cnd_timedwait cnd_wait \
+			  mtx_destroy mtx_init mtx_lock mtx_timedlock \
+			  mtx_trylock mtx_unlock \
+			  tss_create tss_delete tss_get tss_set
+
 #		      pthread_setuid pthread_seteuid pthread_setreuid \
 #		      pthread_setresuid \
 #		      pthread_setgid pthread_setegid pthread_setregid \
diff --git a/nptl/Versions b/nptl/Versions
index 34e4b46..0f59855 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -267,7 +267,19 @@  libpthread {
   }
 
   GLIBC_2.22 {
-  }
+    thrd_create; thrd_current;
+    thrd_detach; thrd_equal;
+    thrd_exit; thrd_join;
+    thrd_sleep; thrd_yield;
+    call_once; cnd_broadcast;
+    cnd_destroy; cnd_init;
+    cnd_signal; cnd_timedwait;
+    cnd_wait; mtx_destroy;
+    mtx_init; mtx_lock;
+    mtx_timedlock; mtx_trylock;
+    mtx_unlock; tss_create;
+    tss_delete; tss_get; tss_set;
+  };
 
   GLIBC_PRIVATE {
     __pthread_initialize_minimal;
diff --git a/nptl/__thrd_err_map.h b/nptl/__thrd_err_map.h
new file mode 100644
index 0000000..4a5496b
--- /dev/null
+++ b/nptl/__thrd_err_map.h
@@ -0,0 +1,43 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include <errno.h>
+
+/* Maps pthread error codes with thrd error codes.
+   Defined as inline because it's a common function used
+   by most of threads.h functions, so we avoid code duplication
+   with a small inline function. */
+
+static __always_inline int
+__thrd_err_map (int err_code)
+{
+
+  switch (err_code)
+  {
+    case 0:
+      return thrd_success;
+    case ENOMEM:
+      return thrd_nomem;
+    case ETIMEDOUT:
+      return thrd_timedout;
+    case EBUSY:
+      return thrd_busy;
+    default:
+      return thrd_error;
+  }
+}
diff --git a/nptl/call_once.c b/nptl/call_once.c
new file mode 100644
index 0000000..03d483a
--- /dev/null
+++ b/nptl/call_once.c
@@ -0,0 +1,24 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+void call_once (once_flag *flag, void (*func)(void))
+{
+  pthread_once (flag, func);
+}
diff --git a/nptl/cnd_broadcast.c b/nptl/cnd_broadcast.c
new file mode 100644
index 0000000..9aa3e6c
--- /dev/null
+++ b/nptl/cnd_broadcast.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int cnd_broadcast (cnd_t *cond)
+{
+  int err_code = pthread_cond_broadcast ((pthread_cond_t*) cond);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/cnd_destroy.c b/nptl/cnd_destroy.c
new file mode 100644
index 0000000..3b2bb81
--- /dev/null
+++ b/nptl/cnd_destroy.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+void cnd_destroy (cnd_t *cond)
+{
+  pthread_cond_destroy ((pthread_cond_t *) cond);
+}
diff --git a/nptl/cnd_init.c b/nptl/cnd_init.c
new file mode 100644
index 0000000..1ae5af8
--- /dev/null
+++ b/nptl/cnd_init.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int cnd_init (cnd_t *cond)
+{
+  int err_code = pthread_cond_init ((pthread_cond_t *)cond, NULL);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/cnd_signal.c b/nptl/cnd_signal.c
new file mode 100644
index 0000000..16e154f
--- /dev/null
+++ b/nptl/cnd_signal.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int cnd_signal (cnd_t *cond)
+{
+  int err_code = pthread_cond_signal ((pthread_cond_t *) cond);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/cnd_timedwait.c b/nptl/cnd_timedwait.c
new file mode 100644
index 0000000..db8c030
--- /dev/null
+++ b/nptl/cnd_timedwait.c
@@ -0,0 +1,28 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int cnd_timedwait (cnd_t *restrict cond, mtx_t *restrict mutex,
+		const struct timespec* restrict time_point)
+{
+  int err_code = pthread_cond_timedwait ((pthread_cond_t *) cond,
+                    (pthread_mutex_t *) mutex, time_point);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/cnd_wait.c b/nptl/cnd_wait.c
new file mode 100644
index 0000000..f13b31d
--- /dev/null
+++ b/nptl/cnd_wait.c
@@ -0,0 +1,26 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int cnd_wait (cnd_t *cond, mtx_t *mutex)
+{
+  int err_code = pthread_cond_wait ((pthread_cond_t *) cond,
+                    (pthread_mutex_t *) mutex);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/mtx_destroy.c b/nptl/mtx_destroy.c
new file mode 100644
index 0000000..cc827dd
--- /dev/null
+++ b/nptl/mtx_destroy.c
@@ -0,0 +1,24 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+void mtx_destroy (mtx_t *mutex)
+{
+  pthread_mutex_destroy ((pthread_mutex_t *) mutex);
+}
diff --git a/nptl/mtx_init.c b/nptl/mtx_init.c
new file mode 100644
index 0000000..3d0d54d
--- /dev/null
+++ b/nptl/mtx_init.c
@@ -0,0 +1,51 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+
+int mtx_init (mtx_t *mutex, int type)
+{
+  pthread_mutexattr_t config;
+  int pthd_type;
+  int err_code;
+
+  /* Initialize config */
+  pthread_mutexattr_init (&config);
+
+  /* Match types for mutex creation */
+  switch (type)
+  {
+    case mtx_plain | mtx_recursive:
+    case mtx_timed | mtx_recursive:
+      pthd_type = PTHREAD_MUTEX_RECURSIVE;
+      break;
+    case mtx_plain:
+    case mtx_timed: /* No difference between both in standard */
+    default:
+      pthd_type = PTHREAD_MUTEX_DEFAULT;
+      break;
+  }
+
+  /* Set type of mutex */
+  pthread_mutexattr_settype (&config, pthd_type);
+  /* Initialize mutex with config */
+  err_code = pthread_mutex_init ((pthread_mutex_t *) mutex, &config);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/mtx_lock.c b/nptl/mtx_lock.c
new file mode 100644
index 0000000..d63045a
--- /dev/null
+++ b/nptl/mtx_lock.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int mtx_lock (mtx_t *mutex)
+{
+  int err_code = pthread_mutex_lock ((pthread_mutex_t *) mutex);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/mtx_timedlock.c b/nptl/mtx_timedlock.c
new file mode 100644
index 0000000..6e1c8cc
--- /dev/null
+++ b/nptl/mtx_timedlock.c
@@ -0,0 +1,28 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include <time.h>
+#include "__thrd_err_map.h"
+
+int mtx_timedlock (mtx_t *restrict mutex,
+      const struct timespec *restrict time_point)
+{
+  int err_code = pthread_mutex_timedlock ((pthread_mutex_t *)mutex,
+                   time_point);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/mtx_trylock.c b/nptl/mtx_trylock.c
new file mode 100644
index 0000000..2ab12e5
--- /dev/null
+++ b/nptl/mtx_trylock.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int mtx_trylock (mtx_t *mutex)
+{
+  int err_code = pthread_mutex_trylock ((pthread_mutex_t *) mutex);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/mtx_unlock.c b/nptl/mtx_unlock.c
new file mode 100644
index 0000000..f9cd504
--- /dev/null
+++ b/nptl/mtx_unlock.c
@@ -0,0 +1,26 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int mtx_unlock (mtx_t *mutex)
+{
+	int err_code = pthread_mutex_unlock ((pthread_mutex_t *) mutex);
+	return __thrd_err_map (err_code);
+}
+
diff --git a/nptl/thrd_create.c b/nptl/thrd_create.c
new file mode 100644
index 0000000..88c8a65
--- /dev/null
+++ b/nptl/thrd_create.c
@@ -0,0 +1,27 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int thrd_create (thrd_t *thr, thrd_start_t func, void *arg)
+{
+  int err_code = pthread_create (thr, NULL, (void* (*) (void*))func, arg);
+  return __thrd_err_map (err_code);
+}
+
diff --git a/nptl/thrd_current.c b/nptl/thrd_current.c
new file mode 100644
index 0000000..7cdb39a
--- /dev/null
+++ b/nptl/thrd_current.c
@@ -0,0 +1,24 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+thrd_t thrd_current ()
+{
+  return pthread_self ();
+}
diff --git a/nptl/thrd_detach.c b/nptl/thrd_detach.c
new file mode 100644
index 0000000..3563908
--- /dev/null
+++ b/nptl/thrd_detach.c
@@ -0,0 +1,27 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int thrd_detach (thrd_t thr)
+{
+  int err_code;
+
+  err_code = pthread_detach (thr);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/thrd_equal.c b/nptl/thrd_equal.c
new file mode 100644
index 0000000..26587c4
--- /dev/null
+++ b/nptl/thrd_equal.c
@@ -0,0 +1,24 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int thrd_equal (thrd_t lhs, thrd_t rhs)
+{
+  return pthread_equal (lhs, rhs);
+}
diff --git a/nptl/thrd_exit.c b/nptl/thrd_exit.c
new file mode 100644
index 0000000..5c6fa5a
--- /dev/null
+++ b/nptl/thrd_exit.c
@@ -0,0 +1,29 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include <stdint.h>
+#include "__thrd_err_map.h"
+
+_Noreturn void thrd_exit (int res)
+{
+  /* We need to cast an int to void pointer */
+  uintptr_t aux_pointer;
+
+  aux_pointer = res;
+  pthread_exit ((void*) aux_pointer);
+}
diff --git a/nptl/thrd_join.c b/nptl/thrd_join.c
new file mode 100644
index 0000000..3fe034a
--- /dev/null
+++ b/nptl/thrd_join.c
@@ -0,0 +1,43 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int thrd_join (thrd_t thr, int *res)
+{
+  int err_code;
+  uintptr_t aux_p;
+
+  /** We have to cast the pointer res to a void** so the
+   *  pthread function can modify it. In case we don't want
+   *  to store the value returned, we have to send a NULL
+   *  pointer to pthread_join, instead of the stack value
+   *  where the pointer is currently stored
+   */
+
+  if (res != NULL)
+  {
+    err_code = pthread_join (thr,(void*) &aux_p);
+    *res = (int)aux_p;
+
+  }else{
+    err_code = pthread_join (thr, NULL);
+  }
+ 
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c
new file mode 100644
index 0000000..460c3ad
--- /dev/null
+++ b/nptl/thrd_sleep.c
@@ -0,0 +1,27 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include <time.h>
+
+int thrd_sleep (const struct timespec* time_point,
+        struct timespec* remaining)
+{
+
+  /* Returns 0 if success, -1 if interrupted and other if error */
+  return __nanosleep (time_point, remaining);
+}
diff --git a/nptl/thrd_yield.c b/nptl/thrd_yield.c
new file mode 100644
index 0000000..30d3852
--- /dev/null
+++ b/nptl/thrd_yield.c
@@ -0,0 +1,24 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+void thrd_yield ()
+{
+  sched_yield ();
+}
diff --git a/nptl/tss_create.c b/nptl/tss_create.c
new file mode 100644
index 0000000..ad85348
--- /dev/null
+++ b/nptl/tss_create.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int tss_create (tss_t *tss_id, tss_dtor_t destructor)
+{
+  int err_code = pthread_key_create (tss_id, destructor);
+  return __thrd_err_map (err_code);
+}
diff --git a/nptl/tss_delete.c b/nptl/tss_delete.c
new file mode 100644
index 0000000..9b912c1
--- /dev/null
+++ b/nptl/tss_delete.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+void tss_delete (tss_t tss_id)
+{
+  pthread_key_delete (tss_id);
+}
diff --git a/nptl/tss_get.c b/nptl/tss_get.c
new file mode 100644
index 0000000..e4fa7b1
--- /dev/null
+++ b/nptl/tss_get.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+void *tss_get (tss_t tss_id)
+{
+  /* Returns NULL if not successful or the pointer if success */
+  return pthread_getspecific (tss_id);
+}
diff --git a/nptl/tss_set.c b/nptl/tss_set.c
new file mode 100644
index 0000000..892cbb8
--- /dev/null
+++ b/nptl/tss_set.c
@@ -0,0 +1,25 @@ 
+/* Copyright (C) 2015 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 <threads.h>
+#include "__thrd_err_map.h"
+
+int tss_set (tss_t tss_id, void *val)
+{
+  int err_code = pthread_setspecific (tss_id, val);
+  return __thrd_err_map (err_code);
+}