Imported Upstream version 16.07-rc4
[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                 }
424                 NOT_IMPLEMENTED;
425         }
426         return _sys_pthread_funcs.f_pthread_detach(tid);
427 }
428
429 int pthread_equal(pthread_t a, pthread_t b)
430 {
431         NOT_IMPLEMENTED;
432         return _sys_pthread_funcs.f_pthread_equal(a, b);
433 }
434
435 void pthread_exit_override(void *v)
436 {
437         if (override) {
438                 lthread_exit(v);
439                 return;
440         }
441         _sys_pthread_funcs.f_pthread_exit(v);
442 }
443
444 void
445 *pthread_getspecific(pthread_key_t key)
446 {
447         if (override)
448                 return lthread_getspecific((unsigned int) key);
449         return _sys_pthread_funcs.f_pthread_getspecific(key);
450 }
451
452 int pthread_getcpuclockid(pthread_t a, clockid_t *b)
453 {
454         NOT_IMPLEMENTED;
455         return _sys_pthread_funcs.f_pthread_getcpuclockid(a, b);
456 }
457
458 int pthread_join(pthread_t tid, void **val)
459 {
460         if (override)
461                 return lthread_join((struct lthread *)tid, val);
462         return _sys_pthread_funcs.f_pthread_join(tid, val);
463 }
464
465 int pthread_key_create(pthread_key_t *keyptr, void (*dtor) (void *))
466 {
467         if (override)
468                 return lthread_key_create((unsigned int *)keyptr, dtor);
469         return _sys_pthread_funcs.f_pthread_key_create(keyptr, dtor);
470 }
471
472 int pthread_key_delete(pthread_key_t key)
473 {
474         if (override) {
475                 lthread_key_delete((unsigned int) key);
476                 return 0;
477         }
478         return _sys_pthread_funcs.f_pthread_key_delete(key);
479 }
480
481
482 int
483 pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
484 {
485         if (override)
486                 return lthread_mutex_init(NULL,
487                                 (struct lthread_mutex **)mutex,
488                                 (const struct lthread_mutexattr *)attr);
489         return _sys_pthread_funcs.f_pthread_mutex_init(mutex, attr);
490 }
491
492 int pthread_mutex_lock(pthread_mutex_t *mutex)
493 {
494         if (override)
495                 return lthread_mutex_lock(*(struct lthread_mutex **)mutex);
496         return _sys_pthread_funcs.f_pthread_mutex_lock(mutex);
497 }
498
499 int pthread_mutex_trylock(pthread_mutex_t *mutex)
500 {
501         if (override)
502                 return lthread_mutex_trylock(*(struct lthread_mutex **)mutex);
503         return _sys_pthread_funcs.f_pthread_mutex_trylock(mutex);
504 }
505
506 int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *b)
507 {
508         NOT_IMPLEMENTED;
509         return _sys_pthread_funcs.f_pthread_mutex_timedlock(mutex, b);
510 }
511
512 int pthread_mutex_unlock(pthread_mutex_t *mutex)
513 {
514         if (override)
515                 return lthread_mutex_unlock(*(struct lthread_mutex **)mutex);
516         return _sys_pthread_funcs.f_pthread_mutex_unlock(mutex);
517 }
518
519 int pthread_once(pthread_once_t *a, void (b) (void))
520 {
521         NOT_IMPLEMENTED;
522         return _sys_pthread_funcs.f_pthread_once(a, b);
523 }
524
525 int pthread_rwlock_destroy(pthread_rwlock_t *a)
526 {
527         NOT_IMPLEMENTED;
528         return _sys_pthread_funcs.f_pthread_rwlock_destroy(a);
529 }
530
531 int pthread_rwlock_init(pthread_rwlock_t *a, const pthread_rwlockattr_t *b)
532 {
533         NOT_IMPLEMENTED;
534         return _sys_pthread_funcs.f_pthread_rwlock_init(a, b);
535 }
536
537 int pthread_rwlock_rdlock(pthread_rwlock_t *a)
538 {
539         NOT_IMPLEMENTED;
540         return _sys_pthread_funcs.f_pthread_rwlock_rdlock(a);
541 }
542
543 int pthread_rwlock_timedrdlock(pthread_rwlock_t *a, const struct timespec *b)
544 {
545         NOT_IMPLEMENTED;
546         return _sys_pthread_funcs.f_pthread_rwlock_timedrdlock(a, b);
547 }
548
549 int pthread_rwlock_timedwrlock(pthread_rwlock_t *a, const struct timespec *b)
550 {
551         NOT_IMPLEMENTED;
552         return _sys_pthread_funcs.f_pthread_rwlock_timedwrlock(a, b);
553 }
554
555 int pthread_rwlock_tryrdlock(pthread_rwlock_t *a)
556 {
557         NOT_IMPLEMENTED;
558         return _sys_pthread_funcs.f_pthread_rwlock_tryrdlock(a);
559 }
560
561 int pthread_rwlock_trywrlock(pthread_rwlock_t *a)
562 {
563         NOT_IMPLEMENTED;
564         return _sys_pthread_funcs.f_pthread_rwlock_trywrlock(a);
565 }
566
567 int pthread_rwlock_unlock(pthread_rwlock_t *a)
568 {
569         NOT_IMPLEMENTED;
570         return _sys_pthread_funcs.f_pthread_rwlock_unlock(a);
571 }
572
573 int pthread_rwlock_wrlock(pthread_rwlock_t *a)
574 {
575         NOT_IMPLEMENTED;
576         return _sys_pthread_funcs.f_pthread_rwlock_wrlock(a);
577 }
578
579 int pthread_yield(void)
580 {
581         if (override) {
582                 lthread_yield();
583                 return 0;
584         }
585         return _sys_pthread_funcs.f_pthread_yield();
586
587 }
588
589 pthread_t pthread_self(void)
590 {
591         if (override)
592                 return (pthread_t) lthread_current();
593         return _sys_pthread_funcs.f_pthread_self();
594 }
595
596 int pthread_setspecific(pthread_key_t key, const void *data)
597 {
598         if (override) {
599                 int rv =  lthread_setspecific((unsigned int)key, data);
600                 return rv;
601         }
602         return _sys_pthread_funcs.f_pthread_setspecific(key, data);
603 }
604
605 int pthread_spin_init(pthread_spinlock_t *a, int b)
606 {
607         NOT_IMPLEMENTED;
608         return _sys_pthread_funcs.f_pthread_spin_init(a, b);
609 }
610
611 int pthread_spin_destroy(pthread_spinlock_t *a)
612 {
613         NOT_IMPLEMENTED;
614         return _sys_pthread_funcs.f_pthread_spin_destroy(a);
615 }
616
617 int pthread_spin_lock(pthread_spinlock_t *a)
618 {
619         NOT_IMPLEMENTED;
620         return _sys_pthread_funcs.f_pthread_spin_lock(a);
621 }
622
623 int pthread_spin_trylock(pthread_spinlock_t *a)
624 {
625         NOT_IMPLEMENTED;
626         return _sys_pthread_funcs.f_pthread_spin_trylock(a);
627 }
628
629 int pthread_spin_unlock(pthread_spinlock_t *a)
630 {
631         NOT_IMPLEMENTED;
632         return _sys_pthread_funcs.f_pthread_spin_unlock(a);
633 }
634
635 int pthread_cancel(pthread_t tid)
636 {
637         if (override) {
638                 lthread_cancel(*(struct lthread **)tid);
639                 return 0;
640         }
641         return _sys_pthread_funcs.f_pthread_cancel(tid);
642 }
643
644 int pthread_setcancelstate(int a, int *b)
645 {
646         NOT_IMPLEMENTED;
647         return _sys_pthread_funcs.f_pthread_setcancelstate(a, b);
648 }
649
650 int pthread_setcanceltype(int a, int *b)
651 {
652         NOT_IMPLEMENTED;
653         return _sys_pthread_funcs.f_pthread_setcanceltype(a, b);
654 }
655
656 void pthread_testcancel(void)
657 {
658         NOT_IMPLEMENTED;
659         return _sys_pthread_funcs.f_pthread_testcancel();
660 }
661
662
663 int pthread_getschedparam(pthread_t tid, int *a, struct sched_param *b)
664 {
665         NOT_IMPLEMENTED;
666         return _sys_pthread_funcs.f_pthread_getschedparam(tid, a, b);
667 }
668
669 int pthread_setschedparam(pthread_t a, int b, const struct sched_param *c)
670 {
671         NOT_IMPLEMENTED;
672         return _sys_pthread_funcs.f_pthread_setschedparam(a, b, c);
673 }
674
675
676 int nanosleep(const struct timespec *req, struct timespec *rem)
677 {
678         if (override) {
679                 uint64_t ns = req->tv_sec * 1000000000 + req->tv_nsec;
680
681                 lthread_sleep(ns);
682                 return 0;
683         }
684         return _sys_pthread_funcs.f_nanosleep(req, rem);
685 }
686
687 int
688 pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,
689                        const cpu_set_t *cpuset)
690 {
691         if (override) {
692                 /* we only allow affinity with a single CPU */
693                 if (CPU_COUNT(cpuset) != 1)
694                         return POSIX_ERRNO(EINVAL);
695
696                 /* we only allow the current thread to sets its own affinity */
697                 struct lthread *lt = (struct lthread *)thread;
698
699                 if (lthread_current() != lt)
700                         return POSIX_ERRNO(EINVAL);
701
702                 /* determine the CPU being requested */
703                 int i;
704
705                 for (i = 0; i < LTHREAD_MAX_LCORES; i++) {
706                         if (!CPU_ISSET(i, cpuset))
707                                 continue;
708                         break;
709                 }
710                 /* check requested core is allowed */
711                 if (i == LTHREAD_MAX_LCORES)
712                         return POSIX_ERRNO(EINVAL);
713
714                 /* finally we can set affinity to the requested lcore */
715                 lthread_set_affinity(i);
716                 return 0;
717         }
718         return _sys_pthread_funcs.f_pthread_setaffinity_np(thread, cpusetsize,
719                                                            cpuset);
720 }