Imported Upstream version 16.04
[deb_dpdk.git] / examples / performance-thread / pthread_shim / pthread_shim.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2015 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <sys/types.h>
37 #include <errno.h>
38 #define __USE_GNU
39 #include <sched.h>
40 #include <dlfcn.h>
41
42 #include <rte_log.h>
43
44 #include "lthread_api.h"
45 #include "pthread_shim.h"
46
47 #define RTE_LOGTYPE_PTHREAD_SHIM RTE_LOGTYPE_USER3
48
49 #define POSIX_ERRNO(x)  (x)
50
51 /*
52  * this flag determines at run time if we override pthread
53  * calls and map then to equivalent lthread calls
54  * or of we call the standard pthread function
55  */
56 static __thread int override;
57
58
59 /*
60  * this structures contains function pointers that will be
61  * initialised to the loaded address of the real
62  * pthread library API functions
63  */
64 struct pthread_lib_funcs {
65 int (*f_pthread_barrier_destroy)
66         (pthread_barrier_t *);
67 int (*f_pthread_barrier_init)
68         (pthread_barrier_t *, const pthread_barrierattr_t *, unsigned);
69 int (*f_pthread_barrier_wait)
70         (pthread_barrier_t *);
71 int (*f_pthread_cond_broadcast)
72         (pthread_cond_t *);
73 int (*f_pthread_cond_destroy)
74         (pthread_cond_t *);
75 int (*f_pthread_cond_init)
76         (pthread_cond_t *, const pthread_condattr_t *);
77 int (*f_pthread_cond_signal)
78         (pthread_cond_t *);
79 int (*f_pthread_cond_timedwait)
80         (pthread_cond_t *, pthread_mutex_t *, const struct timespec *);
81 int (*f_pthread_cond_wait)
82         (pthread_cond_t *, pthread_mutex_t *);
83 int (*f_pthread_create)
84         (pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
85 int (*f_pthread_detach)
86         (pthread_t);
87 int (*f_pthread_equal)
88         (pthread_t, pthread_t);
89 void (*f_pthread_exit)
90         (void *);
91 void * (*f_pthread_getspecific)
92         (pthread_key_t);
93 int (*f_pthread_getcpuclockid)
94         (pthread_t, clockid_t *);
95 int (*f_pthread_join)
96         (pthread_t, void **);
97 int (*f_pthread_key_create)
98         (pthread_key_t *, void (*) (void *));
99 int (*f_pthread_key_delete)
100         (pthread_key_t);
101 int (*f_pthread_mutex_destroy)
102         (pthread_mutex_t *__mutex);
103 int (*f_pthread_mutex_init)
104         (pthread_mutex_t *__mutex, const pthread_mutexattr_t *);
105 int (*f_pthread_mutex_lock)
106         (pthread_mutex_t *__mutex);
107 int (*f_pthread_mutex_trylock)
108         (pthread_mutex_t *__mutex);
109 int (*f_pthread_mutex_timedlock)
110         (pthread_mutex_t *__mutex, const struct timespec *);
111 int (*f_pthread_mutex_unlock)
112         (pthread_mutex_t *__mutex);
113 int (*f_pthread_once)
114         (pthread_once_t *, void (*) (void));
115 int (*f_pthread_rwlock_destroy)
116         (pthread_rwlock_t *__rwlock);
117 int (*f_pthread_rwlock_init)
118         (pthread_rwlock_t *__rwlock, const pthread_rwlockattr_t *);
119 int (*f_pthread_rwlock_rdlock)
120         (pthread_rwlock_t *__rwlock);
121 int (*f_pthread_rwlock_timedrdlock)
122         (pthread_rwlock_t *__rwlock, const struct timespec *);
123 int (*f_pthread_rwlock_timedwrlock)
124         (pthread_rwlock_t *__rwlock, const struct timespec *);
125 int (*f_pthread_rwlock_tryrdlock)
126         (pthread_rwlock_t *__rwlock);
127 int (*f_pthread_rwlock_trywrlock)
128         (pthread_rwlock_t *__rwlock);
129 int (*f_pthread_rwlock_unlock)
130         (pthread_rwlock_t *__rwlock);
131 int (*f_pthread_rwlock_wrlock)
132         (pthread_rwlock_t *__rwlock);
133 pthread_t (*f_pthread_self)
134         (void);
135 int (*f_pthread_setspecific)
136         (pthread_key_t, const void *);
137 int (*f_pthread_spin_init)
138         (pthread_spinlock_t *__spin, int);
139 int (*f_pthread_spin_destroy)
140         (pthread_spinlock_t *__spin);
141 int (*f_pthread_spin_lock)
142         (pthread_spinlock_t *__spin);
143 int (*f_pthread_spin_trylock)
144         (pthread_spinlock_t *__spin);
145 int (*f_pthread_spin_unlock)
146         (pthread_spinlock_t *__spin);
147 int (*f_pthread_cancel)
148         (pthread_t);
149 int (*f_pthread_setcancelstate)
150         (int, int *);
151 int (*f_pthread_setcanceltype)
152         (int, int *);
153 void (*f_pthread_testcancel)
154         (void);
155 int (*f_pthread_getschedparam)
156         (pthread_t pthread, int *, struct sched_param *);
157 int (*f_pthread_setschedparam)
158         (pthread_t, int, const struct sched_param *);
159 int (*f_pthread_yield)
160         (void);
161 int (*f_pthread_setaffinity_np)
162         (pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
163 int (*f_nanosleep)
164         (const struct timespec *req, struct timespec *rem);
165 } _sys_pthread_funcs = {
166         .f_pthread_barrier_destroy = NULL,
167 };
168
169
170 /*
171  * this macro obtains the loaded address of a library function
172  * and saves it.
173  */
174 static void *__libc_dl_handle = RTLD_NEXT;
175
176 #define get_addr_of_loaded_symbol(name) do {                            \
177         char *error_str;                                                \
178         _sys_pthread_funcs.f_##name = dlsym(__libc_dl_handle, (#name)); \
179         error_str = dlerror();                                          \
180         if (error_str != NULL) {                                        \
181                 fprintf(stderr, "%s\n", error_str);                     \
182         }                                                               \
183 } while (0)
184
185
186 /*
187  * The constructor function initialises the
188  * function pointers for pthread library functions
189  */
190 void
191 pthread_intercept_ctor(void)__attribute__((constructor));
192 void
193 pthread_intercept_ctor(void)
194 {
195         override = 0;
196         /*
197          * Get the original functions
198          */
199         get_addr_of_loaded_symbol(pthread_barrier_destroy);
200         get_addr_of_loaded_symbol(pthread_barrier_init);
201         get_addr_of_loaded_symbol(pthread_barrier_wait);
202         get_addr_of_loaded_symbol(pthread_cond_broadcast);
203         get_addr_of_loaded_symbol(pthread_cond_destroy);
204         get_addr_of_loaded_symbol(pthread_cond_init);
205         get_addr_of_loaded_symbol(pthread_cond_signal);
206         get_addr_of_loaded_symbol(pthread_cond_timedwait);
207         get_addr_of_loaded_symbol(pthread_cond_wait);
208         get_addr_of_loaded_symbol(pthread_create);
209         get_addr_of_loaded_symbol(pthread_detach);
210         get_addr_of_loaded_symbol(pthread_equal);
211         get_addr_of_loaded_symbol(pthread_exit);
212         get_addr_of_loaded_symbol(pthread_getspecific);
213         get_addr_of_loaded_symbol(pthread_getcpuclockid);
214         get_addr_of_loaded_symbol(pthread_join);
215         get_addr_of_loaded_symbol(pthread_key_create);
216         get_addr_of_loaded_symbol(pthread_key_delete);
217         get_addr_of_loaded_symbol(pthread_mutex_destroy);
218         get_addr_of_loaded_symbol(pthread_mutex_init);
219         get_addr_of_loaded_symbol(pthread_mutex_lock);
220         get_addr_of_loaded_symbol(pthread_mutex_trylock);
221         get_addr_of_loaded_symbol(pthread_mutex_timedlock);
222         get_addr_of_loaded_symbol(pthread_mutex_unlock);
223         get_addr_of_loaded_symbol(pthread_once);
224         get_addr_of_loaded_symbol(pthread_rwlock_destroy);
225         get_addr_of_loaded_symbol(pthread_rwlock_init);
226         get_addr_of_loaded_symbol(pthread_rwlock_rdlock);
227         get_addr_of_loaded_symbol(pthread_rwlock_timedrdlock);
228         get_addr_of_loaded_symbol(pthread_rwlock_timedwrlock);
229         get_addr_of_loaded_symbol(pthread_rwlock_tryrdlock);
230         get_addr_of_loaded_symbol(pthread_rwlock_trywrlock);
231         get_addr_of_loaded_symbol(pthread_rwlock_unlock);
232         get_addr_of_loaded_symbol(pthread_rwlock_wrlock);
233         get_addr_of_loaded_symbol(pthread_self);
234         get_addr_of_loaded_symbol(pthread_setspecific);
235         get_addr_of_loaded_symbol(pthread_spin_init);
236         get_addr_of_loaded_symbol(pthread_spin_destroy);
237         get_addr_of_loaded_symbol(pthread_spin_lock);
238         get_addr_of_loaded_symbol(pthread_spin_trylock);
239         get_addr_of_loaded_symbol(pthread_spin_unlock);
240         get_addr_of_loaded_symbol(pthread_cancel);
241         get_addr_of_loaded_symbol(pthread_setcancelstate);
242         get_addr_of_loaded_symbol(pthread_setcanceltype);
243         get_addr_of_loaded_symbol(pthread_testcancel);
244         get_addr_of_loaded_symbol(pthread_getschedparam);
245         get_addr_of_loaded_symbol(pthread_setschedparam);
246         get_addr_of_loaded_symbol(pthread_yield);
247         get_addr_of_loaded_symbol(pthread_setaffinity_np);
248         get_addr_of_loaded_symbol(nanosleep);
249 }
250
251
252 /*
253  * Enable/Disable pthread override
254  * state
255  *  0 disable
256  *  1 enable
257  */
258 void pthread_override_set(int state)
259 {
260         override = state;
261 }
262
263
264 /*
265  * Return pthread override state
266  * return
267  *  0 disable
268  *  1 enable
269  */
270 int pthread_override_get(void)
271 {
272         return override;
273 }
274
275 /*
276  * This macro is used to catch and log
277  * invocation of stubs for unimplemented pthread
278  * API functions.
279  */
280 #define NOT_IMPLEMENTED do {                            \
281         if (override) {                                 \
282                 RTE_LOG(WARNING,                        \
283                         PTHREAD_SHIM,                   \
284                         "WARNING %s NOT IMPLEMENTED\n", \
285                         __func__);                      \
286         }                                               \
287 } while (0)
288
289 /*
290  * pthread API override functions follow
291  * Note in this example code only a subset of functions are
292  * implemented.
293  *
294  * The stub functions provided will issue a warning log
295  * message if an unimplemented function is invoked
296  *
297  */
298
299 int pthread_barrier_destroy(pthread_barrier_t *a)
300 {
301         NOT_IMPLEMENTED;
302         return _sys_pthread_funcs.f_pthread_barrier_destroy(a);
303 }
304
305 int
306 pthread_barrier_init(pthread_barrier_t *a,
307                      const pthread_barrierattr_t *b, unsigned c)
308 {
309         NOT_IMPLEMENTED;
310         return _sys_pthread_funcs.f_pthread_barrier_init(a, b, c);
311 }
312
313 int pthread_barrier_wait(pthread_barrier_t *a)
314 {
315         NOT_IMPLEMENTED;
316         return _sys_pthread_funcs.f_pthread_barrier_wait(a);
317 }
318
319 int pthread_cond_broadcast(pthread_cond_t *cond)
320 {
321         if (override) {
322
323                 lthread_cond_broadcast(*(struct lthread_cond **)cond);
324                 return 0;
325         }
326         return _sys_pthread_funcs.f_pthread_cond_broadcast(cond);
327 }
328
329 int pthread_mutex_destroy(pthread_mutex_t *mutex)
330 {
331         if (override)
332                 return lthread_mutex_destroy(*(struct lthread_mutex **)mutex);
333         return _sys_pthread_funcs.f_pthread_mutex_destroy(mutex);
334 }
335
336 int pthread_cond_destroy(pthread_cond_t *cond)
337 {
338         if (override)
339                 return lthread_cond_destroy(*(struct lthread_cond **)cond);
340         return _sys_pthread_funcs.f_pthread_cond_destroy(cond);
341 }
342
343 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
344 {
345         if (override)
346                 return lthread_cond_init(NULL,
347                                 (struct lthread_cond **)cond,
348                                 (const struct lthread_condattr *) attr);
349         return _sys_pthread_funcs.f_pthread_cond_init(cond, attr);
350 }
351
352 int pthread_cond_signal(pthread_cond_t *cond)
353 {
354         if (override) {
355                 lthread_cond_signal(*(struct lthread_cond **)cond);
356                 return 0;
357         }
358         return _sys_pthread_funcs.f_pthread_cond_signal(cond);
359 }
360
361 int
362 pthread_cond_timedwait(pthread_cond_t *__restrict cond,
363                        pthread_mutex_t *__restrict mutex,
364                        const struct timespec *__restrict time)
365 {
366         NOT_IMPLEMENTED;
367         return _sys_pthread_funcs.f_pthread_cond_timedwait(cond, mutex, time);
368 }
369
370 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
371 {
372         if (override) {
373                 pthread_mutex_unlock(mutex);
374                 int rv = lthread_cond_wait(*(struct lthread_cond **)cond, 0);
375
376                 pthread_mutex_lock(mutex);
377                 return rv;
378         }
379         return _sys_pthread_funcs.f_pthread_cond_wait(cond, mutex);
380 }
381
382 int
383 pthread_create(pthread_t *__restrict tid,
384                 const pthread_attr_t *__restrict attr,
385                 void *(func) (void *),
386                void *__restrict arg)
387 {
388         if (override) {
389                 int lcore = -1;
390
391                 if (attr != NULL) {
392                         /* determine CPU being requested */
393                         cpu_set_t cpuset;
394
395                         CPU_ZERO(&cpuset);
396                         pthread_attr_getaffinity_np(attr,
397                                                 sizeof(cpu_set_t),
398                                                 &cpuset);
399
400                         if (CPU_COUNT(&cpuset) != 1)
401                                 return POSIX_ERRNO(EINVAL);
402
403                         for (lcore = 0; lcore < LTHREAD_MAX_LCORES; lcore++) {
404                                 if (!CPU_ISSET(lcore, &cpuset))
405                                         continue;
406                                 break;
407                         }
408                 }
409                 return lthread_create((struct lthread **)tid, lcore,
410                                       (void (*)(void *))func, arg);
411         }
412         return _sys_pthread_funcs.f_pthread_create(tid, attr, func, arg);
413 }
414
415 int pthread_detach(pthread_t tid)
416 {
417         if (override) {
418                 struct lthread *lt = (struct lthread *)tid;
419
420                 if (lt == lthread_current())
421                         lthread_detach();
422                         return 0;
423                 NOT_IMPLEMENTED;
424         }
425         return _sys_pthread_funcs.f_pthread_detach(tid);
426 }
427
428 int pthread_equal(pthread_t a, pthread_t b)
429 {
430         NOT_IMPLEMENTED;
431         return _sys_pthread_funcs.f_pthread_equal(a, b);
432 }
433
434 void pthread_exit_override(void *v)
435 {
436         if (override) {
437                 lthread_exit(v);
438                 return;
439         }
440         _sys_pthread_funcs.f_pthread_exit(v);
441 }
442
443 void
444 *pthread_getspecific(pthread_key_t key)
445 {
446         if (override)
447                 return lthread_getspecific((unsigned int) key);
448         return _sys_pthread_funcs.f_pthread_getspecific(key);
449 }
450
451 int pthread_getcpuclockid(pthread_t a, clockid_t *b)
452 {
453         NOT_IMPLEMENTED;
454         return _sys_pthread_funcs.f_pthread_getcpuclockid(a, b);
455 }
456
457 int pthread_join(pthread_t tid, void **val)
458 {
459         if (override)
460                 return lthread_join((struct lthread *)tid, val);
461         return _sys_pthread_funcs.f_pthread_join(tid, val);
462 }
463
464 int pthread_key_create(pthread_key_t *keyptr, void (*dtor) (void *))
465 {
466         if (override)
467                 return lthread_key_create((unsigned int *)keyptr, dtor);
468         return _sys_pthread_funcs.f_pthread_key_create(keyptr, dtor);
469 }
470
471 int pthread_key_delete(pthread_key_t key)
472 {
473         if (override) {
474                 lthread_key_delete((unsigned int) key);
475                 return 0;
476         }
477         return _sys_pthread_funcs.f_pthread_key_delete(key);
478 }
479
480
481 int
482 pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
483 {
484         if (override)
485                 return lthread_mutex_init(NULL,
486                                 (struct lthread_mutex **)mutex,
487                                 (const struct lthread_mutexattr *)attr);
488         return _sys_pthread_funcs.f_pthread_mutex_init(mutex, attr);
489 }
490
491 int pthread_mutex_lock(pthread_mutex_t *mutex)
492 {
493         if (override)
494                 return lthread_mutex_lock(*(struct lthread_mutex **)mutex);
495         return _sys_pthread_funcs.f_pthread_mutex_lock(mutex);
496 }
497
498 int pthread_mutex_trylock(pthread_mutex_t *mutex)
499 {
500         if (override)
501                 return lthread_mutex_trylock(*(struct lthread_mutex **)mutex);
502         return _sys_pthread_funcs.f_pthread_mutex_trylock(mutex);
503 }
504
505 int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *b)
506 {
507         NOT_IMPLEMENTED;
508         return _sys_pthread_funcs.f_pthread_mutex_timedlock(mutex, b);
509 }
510
511 int pthread_mutex_unlock(pthread_mutex_t *mutex)
512 {
513         if (override)
514                 return lthread_mutex_unlock(*(struct lthread_mutex **)mutex);
515         return _sys_pthread_funcs.f_pthread_mutex_unlock(mutex);
516 }
517
518 int pthread_once(pthread_once_t *a, void (b) (void))
519 {
520         NOT_IMPLEMENTED;
521         return _sys_pthread_funcs.f_pthread_once(a, b);
522 }
523
524 int pthread_rwlock_destroy(pthread_rwlock_t *a)
525 {
526         NOT_IMPLEMENTED;
527         return _sys_pthread_funcs.f_pthread_rwlock_destroy(a);
528 }
529
530 int pthread_rwlock_init(pthread_rwlock_t *a, const pthread_rwlockattr_t *b)
531 {
532         NOT_IMPLEMENTED;
533         return _sys_pthread_funcs.f_pthread_rwlock_init(a, b);
534 }
535
536 int pthread_rwlock_rdlock(pthread_rwlock_t *a)
537 {
538         NOT_IMPLEMENTED;
539         return _sys_pthread_funcs.f_pthread_rwlock_rdlock(a);
540 }
541
542 int pthread_rwlock_timedrdlock(pthread_rwlock_t *a, const struct timespec *b)
543 {
544         NOT_IMPLEMENTED;
545         return _sys_pthread_funcs.f_pthread_rwlock_timedrdlock(a, b);
546 }
547
548 int pthread_rwlock_timedwrlock(pthread_rwlock_t *a, const struct timespec *b)
549 {
550         NOT_IMPLEMENTED;
551         return _sys_pthread_funcs.f_pthread_rwlock_timedwrlock(a, b);
552 }
553
554 int pthread_rwlock_tryrdlock(pthread_rwlock_t *a)
555 {
556         NOT_IMPLEMENTED;
557         return _sys_pthread_funcs.f_pthread_rwlock_tryrdlock(a);
558 }
559
560 int pthread_rwlock_trywrlock(pthread_rwlock_t *a)
561 {
562         NOT_IMPLEMENTED;
563         return _sys_pthread_funcs.f_pthread_rwlock_trywrlock(a);
564 }
565
566 int pthread_rwlock_unlock(pthread_rwlock_t *a)
567 {
568         NOT_IMPLEMENTED;
569         return _sys_pthread_funcs.f_pthread_rwlock_unlock(a);
570 }
571
572 int pthread_rwlock_wrlock(pthread_rwlock_t *a)
573 {
574         NOT_IMPLEMENTED;
575         return _sys_pthread_funcs.f_pthread_rwlock_wrlock(a);
576 }
577
578 int pthread_yield(void)
579 {
580         if (override) {
581                 lthread_yield();
582                 return 0;
583         }
584         return _sys_pthread_funcs.f_pthread_yield();
585
586 }
587
588 pthread_t pthread_self(void)
589 {
590         if (override)
591                 return (pthread_t) lthread_current();
592         return _sys_pthread_funcs.f_pthread_self();
593 }
594
595 int pthread_setspecific(pthread_key_t key, const void *data)
596 {
597         if (override) {
598                 int rv =  lthread_setspecific((unsigned int)key, data);
599                 return rv;
600         }
601         return _sys_pthread_funcs.f_pthread_setspecific(key, data);
602 }
603
604 int pthread_spin_init(pthread_spinlock_t *a, int b)
605 {
606         NOT_IMPLEMENTED;
607         return _sys_pthread_funcs.f_pthread_spin_init(a, b);
608 }
609
610 int pthread_spin_destroy(pthread_spinlock_t *a)
611 {
612         NOT_IMPLEMENTED;
613         return _sys_pthread_funcs.f_pthread_spin_destroy(a);
614 }
615
616 int pthread_spin_lock(pthread_spinlock_t *a)
617 {
618         NOT_IMPLEMENTED;
619         return _sys_pthread_funcs.f_pthread_spin_lock(a);
620 }
621
622 int pthread_spin_trylock(pthread_spinlock_t *a)
623 {
624         NOT_IMPLEMENTED;
625         return _sys_pthread_funcs.f_pthread_spin_trylock(a);
626 }
627
628 int pthread_spin_unlock(pthread_spinlock_t *a)
629 {
630         NOT_IMPLEMENTED;
631         return _sys_pthread_funcs.f_pthread_spin_unlock(a);
632 }
633
634 int pthread_cancel(pthread_t tid)
635 {
636         if (override) {
637                 lthread_cancel(*(struct lthread **)tid);
638                 return 0;
639         }
640         return _sys_pthread_funcs.f_pthread_cancel(tid);
641 }
642
643 int pthread_setcancelstate(int a, int *b)
644 {
645         NOT_IMPLEMENTED;
646         return _sys_pthread_funcs.f_pthread_setcancelstate(a, b);
647 }
648
649 int pthread_setcanceltype(int a, int *b)
650 {
651         NOT_IMPLEMENTED;
652         return _sys_pthread_funcs.f_pthread_setcanceltype(a, b);
653 }
654
655 void pthread_testcancel(void)
656 {
657         NOT_IMPLEMENTED;
658         return _sys_pthread_funcs.f_pthread_testcancel();
659 }
660
661
662 int pthread_getschedparam(pthread_t tid, int *a, struct sched_param *b)
663 {
664         NOT_IMPLEMENTED;
665         return _sys_pthread_funcs.f_pthread_getschedparam(tid, a, b);
666 }
667
668 int pthread_setschedparam(pthread_t a, int b, const struct sched_param *c)
669 {
670         NOT_IMPLEMENTED;
671         return _sys_pthread_funcs.f_pthread_setschedparam(a, b, c);
672 }
673
674
675 int nanosleep(const struct timespec *req, struct timespec *rem)
676 {
677         if (override) {
678                 uint64_t ns = req->tv_sec * 1000000000 + req->tv_nsec;
679
680                 lthread_sleep(ns);
681                 return 0;
682         }
683         return _sys_pthread_funcs.f_nanosleep(req, rem);
684 }
685
686 int
687 pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,
688                        const cpu_set_t *cpuset)
689 {
690         if (override) {
691                 /* we only allow affinity with a single CPU */
692                 if (CPU_COUNT(cpuset) != 1)
693                         return POSIX_ERRNO(EINVAL);
694
695                 /* we only allow the current thread to sets its own affinity */
696                 struct lthread *lt = (struct lthread *)thread;
697
698                 if (lthread_current() != lt)
699                         return POSIX_ERRNO(EINVAL);
700
701                 /* determine the CPU being requested */
702                 int i;
703
704                 for (i = 0; i < LTHREAD_MAX_LCORES; i++) {
705                         if (!CPU_ISSET(i, cpuset))
706                                 continue;
707                         break;
708                 }
709                 /* check requested core is allowed */
710                 if (i == LTHREAD_MAX_LCORES)
711                         return POSIX_ERRNO(EINVAL);
712
713                 /* finally we can set affinity to the requested lcore */
714                 lthread_set_affinity(i);
715                 return 0;
716         }
717         return _sys_pthread_funcs.f_pthread_setaffinity_np(thread, cpusetsize,
718                                                            cpuset);
719 }