examples/performance-thread: fix return sign
[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_config.h>
43 #include <rte_log.h>
44
45 #include "lthread_api.h"
46 #include "pthread_shim.h"
47
48 #define RTE_LOGTYPE_PTHREAD_SHIM RTE_LOGTYPE_USER3
49
50 #define POSIX_ERRNO(x)  (x)
51
52 /*
53  * this flag determines at run time if we override pthread
54  * calls and map then to equivalent lthread calls
55  * or of we call the standard pthread function
56  */
57 static __thread int override;
58
59
60 /*
61  * this structures contains function pointers that will be
62  * initialised to the loaded address of the real
63  * pthread library API functions
64  */
65 struct pthread_lib_funcs {
66 int (*f_pthread_barrier_destroy)
67         (pthread_barrier_t *);
68 int (*f_pthread_barrier_init)
69         (pthread_barrier_t *, const pthread_barrierattr_t *, unsigned);
70 int (*f_pthread_barrier_wait)
71         (pthread_barrier_t *);
72 int (*f_pthread_cond_broadcast)
73         (pthread_cond_t *);
74 int (*f_pthread_cond_destroy)
75         (pthread_cond_t *);
76 int (*f_pthread_cond_init)
77         (pthread_cond_t *, const pthread_condattr_t *);
78 int (*f_pthread_cond_signal)
79         (pthread_cond_t *);
80 int (*f_pthread_cond_timedwait)
81         (pthread_cond_t *, pthread_mutex_t *, const struct timespec *);
82 int (*f_pthread_cond_wait)
83         (pthread_cond_t *, pthread_mutex_t *);
84 int (*f_pthread_create)
85         (pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
86 int (*f_pthread_detach)
87         (pthread_t);
88 int (*f_pthread_equal)
89         (pthread_t, pthread_t);
90 void (*f_pthread_exit)
91         (void *);
92 void * (*f_pthread_getspecific)
93         (pthread_key_t);
94 int (*f_pthread_getcpuclockid)
95         (pthread_t, clockid_t *);
96 int (*f_pthread_join)
97         (pthread_t, void **);
98 int (*f_pthread_key_create)
99         (pthread_key_t *, void (*) (void *));
100 int (*f_pthread_key_delete)
101         (pthread_key_t);
102 int (*f_pthread_mutex_destroy)
103         (pthread_mutex_t *__mutex);
104 int (*f_pthread_mutex_init)
105         (pthread_mutex_t *__mutex, const pthread_mutexattr_t *);
106 int (*f_pthread_mutex_lock)
107         (pthread_mutex_t *__mutex);
108 int (*f_pthread_mutex_trylock)
109         (pthread_mutex_t *__mutex);
110 int (*f_pthread_mutex_timedlock)
111         (pthread_mutex_t *__mutex, const struct timespec *);
112 int (*f_pthread_mutex_unlock)
113         (pthread_mutex_t *__mutex);
114 int (*f_pthread_once)
115         (pthread_once_t *, void (*) (void));
116 int (*f_pthread_rwlock_destroy)
117         (pthread_rwlock_t *__rwlock);
118 int (*f_pthread_rwlock_init)
119         (pthread_rwlock_t *__rwlock, const pthread_rwlockattr_t *);
120 int (*f_pthread_rwlock_rdlock)
121         (pthread_rwlock_t *__rwlock);
122 int (*f_pthread_rwlock_timedrdlock)
123         (pthread_rwlock_t *__rwlock, const struct timespec *);
124 int (*f_pthread_rwlock_timedwrlock)
125         (pthread_rwlock_t *__rwlock, const struct timespec *);
126 int (*f_pthread_rwlock_tryrdlock)
127         (pthread_rwlock_t *__rwlock);
128 int (*f_pthread_rwlock_trywrlock)
129         (pthread_rwlock_t *__rwlock);
130 int (*f_pthread_rwlock_unlock)
131         (pthread_rwlock_t *__rwlock);
132 int (*f_pthread_rwlock_wrlock)
133         (pthread_rwlock_t *__rwlock);
134 pthread_t (*f_pthread_self)
135         (void);
136 int (*f_pthread_setspecific)
137         (pthread_key_t, const void *);
138 int (*f_pthread_spin_init)
139         (pthread_spinlock_t *__spin, int);
140 int (*f_pthread_spin_destroy)
141         (pthread_spinlock_t *__spin);
142 int (*f_pthread_spin_lock)
143         (pthread_spinlock_t *__spin);
144 int (*f_pthread_spin_trylock)
145         (pthread_spinlock_t *__spin);
146 int (*f_pthread_spin_unlock)
147         (pthread_spinlock_t *__spin);
148 int (*f_pthread_cancel)
149         (pthread_t);
150 int (*f_pthread_setcancelstate)
151         (int, int *);
152 int (*f_pthread_setcanceltype)
153         (int, int *);
154 void (*f_pthread_testcancel)
155         (void);
156 int (*f_pthread_getschedparam)
157         (pthread_t pthread, int *, struct sched_param *);
158 int (*f_pthread_setschedparam)
159         (pthread_t, int, const struct sched_param *);
160 int (*f_pthread_yield)
161         (void);
162 int (*f_pthread_setaffinity_np)
163         (pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
164 int (*f_nanosleep)
165         (const struct timespec *req, struct timespec *rem);
166 } _sys_pthread_funcs = {
167         .f_pthread_barrier_destroy = NULL,
168 };
169
170
171 /*
172  * this macro obtains the loaded address of a library function
173  * and saves it.
174  */
175 static void *__libc_dl_handle = RTLD_NEXT;
176
177 #define get_addr_of_loaded_symbol(name) do {                            \
178         char *error_str;                                                \
179         _sys_pthread_funcs.f_##name = dlsym(__libc_dl_handle, (#name)); \
180         error_str = dlerror();                                          \
181         if (error_str != NULL) {                                        \
182                 fprintf(stderr, "%s\n", error_str);                     \
183         }                                                               \
184 } while (0)
185
186
187 /*
188  * The constructor function initialises the
189  * function pointers for pthread library functions
190  */
191 void
192 pthread_intercept_ctor(void)__attribute__((constructor));
193 void
194 pthread_intercept_ctor(void)
195 {
196         override = 0;
197         /*
198          * Get the original functions
199          */
200         get_addr_of_loaded_symbol(pthread_barrier_destroy);
201         get_addr_of_loaded_symbol(pthread_barrier_init);
202         get_addr_of_loaded_symbol(pthread_barrier_wait);
203         get_addr_of_loaded_symbol(pthread_cond_broadcast);
204         get_addr_of_loaded_symbol(pthread_cond_destroy);
205         get_addr_of_loaded_symbol(pthread_cond_init);
206         get_addr_of_loaded_symbol(pthread_cond_signal);
207         get_addr_of_loaded_symbol(pthread_cond_timedwait);
208         get_addr_of_loaded_symbol(pthread_cond_wait);
209         get_addr_of_loaded_symbol(pthread_create);
210         get_addr_of_loaded_symbol(pthread_detach);
211         get_addr_of_loaded_symbol(pthread_equal);
212         get_addr_of_loaded_symbol(pthread_exit);
213         get_addr_of_loaded_symbol(pthread_getspecific);
214         get_addr_of_loaded_symbol(pthread_getcpuclockid);
215         get_addr_of_loaded_symbol(pthread_join);
216         get_addr_of_loaded_symbol(pthread_key_create);
217         get_addr_of_loaded_symbol(pthread_key_delete);
218         get_addr_of_loaded_symbol(pthread_mutex_destroy);
219         get_addr_of_loaded_symbol(pthread_mutex_init);
220         get_addr_of_loaded_symbol(pthread_mutex_lock);
221         get_addr_of_loaded_symbol(pthread_mutex_trylock);
222         get_addr_of_loaded_symbol(pthread_mutex_timedlock);
223         get_addr_of_loaded_symbol(pthread_mutex_unlock);
224         get_addr_of_loaded_symbol(pthread_once);
225         get_addr_of_loaded_symbol(pthread_rwlock_destroy);
226         get_addr_of_loaded_symbol(pthread_rwlock_init);
227         get_addr_of_loaded_symbol(pthread_rwlock_rdlock);
228         get_addr_of_loaded_symbol(pthread_rwlock_timedrdlock);
229         get_addr_of_loaded_symbol(pthread_rwlock_timedwrlock);
230         get_addr_of_loaded_symbol(pthread_rwlock_tryrdlock);
231         get_addr_of_loaded_symbol(pthread_rwlock_trywrlock);
232         get_addr_of_loaded_symbol(pthread_rwlock_unlock);
233         get_addr_of_loaded_symbol(pthread_rwlock_wrlock);
234         get_addr_of_loaded_symbol(pthread_self);
235         get_addr_of_loaded_symbol(pthread_setspecific);
236         get_addr_of_loaded_symbol(pthread_spin_init);
237         get_addr_of_loaded_symbol(pthread_spin_destroy);
238         get_addr_of_loaded_symbol(pthread_spin_lock);
239         get_addr_of_loaded_symbol(pthread_spin_trylock);
240         get_addr_of_loaded_symbol(pthread_spin_unlock);
241         get_addr_of_loaded_symbol(pthread_cancel);
242         get_addr_of_loaded_symbol(pthread_setcancelstate);
243         get_addr_of_loaded_symbol(pthread_setcanceltype);
244         get_addr_of_loaded_symbol(pthread_testcancel);
245         get_addr_of_loaded_symbol(pthread_getschedparam);
246         get_addr_of_loaded_symbol(pthread_setschedparam);
247         get_addr_of_loaded_symbol(pthread_yield);
248         get_addr_of_loaded_symbol(pthread_setaffinity_np);
249         get_addr_of_loaded_symbol(nanosleep);
250 }
251
252
253 /*
254  * Enable/Disable pthread override
255  * state
256  *  0 disable
257  *  1 enable
258  */
259 void pthread_override_set(int state)
260 {
261         override = state;
262 }
263
264
265 /*
266  * Return pthread override state
267  * return
268  *  0 disable
269  *  1 enable
270  */
271 int pthread_override_get(void)
272 {
273         return override;
274 }
275
276 /*
277  * This macro is used to catch and log
278  * invocation of stubs for unimplemented pthread
279  * API functions.
280  */
281 #define NOT_IMPLEMENTED do {                            \
282         if (override) {                                 \
283                 RTE_LOG(WARNING,                        \
284                         PTHREAD_SHIM,                   \
285                         "WARNING %s NOT IMPLEMENTED\n", \
286                         __func__);                      \
287         }                                               \
288 } while (0)
289
290 /*
291  * pthread API override functions follow
292  * Note in this example code only a subset of functions are
293  * implemented.
294  *
295  * The stub functions provided will issue a warning log
296  * message if an unimplemented function is invoked
297  *
298  */
299
300 int pthread_barrier_destroy(pthread_barrier_t *a)
301 {
302         NOT_IMPLEMENTED;
303         return _sys_pthread_funcs.f_pthread_barrier_destroy(a);
304 }
305
306 int
307 pthread_barrier_init(pthread_barrier_t *a,
308                      const pthread_barrierattr_t *b, unsigned c)
309 {
310         NOT_IMPLEMENTED;
311         return _sys_pthread_funcs.f_pthread_barrier_init(a, b, c);
312 }
313
314 int pthread_barrier_wait(pthread_barrier_t *a)
315 {
316         NOT_IMPLEMENTED;
317         return _sys_pthread_funcs.f_pthread_barrier_wait(a);
318 }
319
320 int pthread_cond_broadcast(pthread_cond_t *cond)
321 {
322         if (override) {
323
324                 lthread_cond_broadcast(*(struct lthread_cond **)cond);
325                 return 0;
326         }
327         return _sys_pthread_funcs.f_pthread_cond_broadcast(cond);
328 }
329
330 int pthread_mutex_destroy(pthread_mutex_t *mutex)
331 {
332         if (override)
333                 return lthread_mutex_destroy(*(struct lthread_mutex **)mutex);
334         return _sys_pthread_funcs.f_pthread_mutex_destroy(mutex);
335 }
336
337 int pthread_cond_destroy(pthread_cond_t *cond)
338 {
339         if (override)
340                 return lthread_cond_destroy(*(struct lthread_cond **)cond);
341         return _sys_pthread_funcs.f_pthread_cond_destroy(cond);
342 }
343
344 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
345 {
346         if (override)
347                 return lthread_cond_init(NULL,
348                                 (struct lthread_cond **)cond,
349                                 (const struct lthread_condattr *) attr);
350         return _sys_pthread_funcs.f_pthread_cond_init(cond, attr);
351 }
352
353 int pthread_cond_signal(pthread_cond_t *cond)
354 {
355         if (override) {
356                 lthread_cond_signal(*(struct lthread_cond **)cond);
357                 return 0;
358         }
359         return _sys_pthread_funcs.f_pthread_cond_signal(cond);
360 }
361
362 int
363 pthread_cond_timedwait(pthread_cond_t *__restrict cond,
364                        pthread_mutex_t *__restrict mutex,
365                        const struct timespec *__restrict time)
366 {
367         NOT_IMPLEMENTED;
368         return _sys_pthread_funcs.f_pthread_cond_timedwait(cond, mutex, time);
369 }
370
371 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
372 {
373         if (override) {
374                 pthread_mutex_unlock(mutex);
375                 int rv = lthread_cond_wait(*(struct lthread_cond **)cond, 0);
376
377                 pthread_mutex_lock(mutex);
378                 return rv;
379         }
380         return _sys_pthread_funcs.f_pthread_cond_wait(cond, mutex);
381 }
382
383 int
384 pthread_create(pthread_t *__restrict tid,
385                 const pthread_attr_t *__restrict attr,
386                 void *(func) (void *),
387                void *__restrict arg)
388 {
389         if (override) {
390                 int lcore = -1;
391
392                 if (attr != NULL) {
393                         /* determine CPU being requested */
394                         cpu_set_t cpuset;
395
396                         CPU_ZERO(&cpuset);
397                         pthread_attr_getaffinity_np(attr,
398                                                 sizeof(cpu_set_t),
399                                                 &cpuset);
400
401                         if (CPU_COUNT(&cpuset) != 1)
402                                 return POSIX_ERRNO(EINVAL);
403
404                         for (lcore = 0; lcore < LTHREAD_MAX_LCORES; lcore++) {
405                                 if (!CPU_ISSET(lcore, &cpuset))
406                                         continue;
407                                 break;
408                         }
409                 }
410                 return lthread_create((struct lthread **)tid, lcore,
411                                       (void (*)(void *))func, arg);
412         }
413         return _sys_pthread_funcs.f_pthread_create(tid, attr, func, arg);
414 }
415
416 int pthread_detach(pthread_t tid)
417 {
418         if (override) {
419                 struct lthread *lt = (struct lthread *)tid;
420
421                 if (lt == lthread_current())
422                         lthread_detach();
423                         return 0;
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 }