1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause 2d30ea906Sjfb8856606 * Copyright(c) 2015 Intel Corporation 3a9643ea8Slogwang */ 4a9643ea8Slogwang 5a9643ea8Slogwang #ifndef _PTHREAD_SHIM_H_ 6a9643ea8Slogwang #define _PTHREAD_SHIM_H_ 72bfe3f2eSlogwang 82bfe3f2eSlogwang #include <rte_lcore.h> 9a9643ea8Slogwang 10a9643ea8Slogwang /* 11a9643ea8Slogwang * This pthread shim is an example that demonstrates how legacy code 12a9643ea8Slogwang * that makes use of POSIX pthread services can make use of lthreads 13a9643ea8Slogwang * with reduced porting effort. 14a9643ea8Slogwang * 15a9643ea8Slogwang * N.B. The example is not a complete implementation, only a subset of 16a9643ea8Slogwang * pthread APIs sufficient to demonstrate the principle of operation 17a9643ea8Slogwang * are implemented. 18a9643ea8Slogwang * 19a9643ea8Slogwang * In general pthread attribute objects do not have equivalent functions 20a9643ea8Slogwang * in lthreads, and are ignored. 21a9643ea8Slogwang * 22a9643ea8Slogwang * There is one exception and that is the use of attr to specify a 23a9643ea8Slogwang * core affinity in calls to pthread_create. 24a9643ea8Slogwang * 25a9643ea8Slogwang * The shim operates as follows:- 26a9643ea8Slogwang * 27a9643ea8Slogwang * On initialisation a constructor function uses dlsym to obtain and 28a9643ea8Slogwang * save the loaded address of the full set of pthread APIs that will 29a9643ea8Slogwang * be overridden. 30a9643ea8Slogwang * 31a9643ea8Slogwang * For each function there is a stub provided that will invoke either 32a9643ea8Slogwang * the genuine pthread library function saved saved by the constructor, 33a9643ea8Slogwang * or else the corresponding equivalent lthread function. 34a9643ea8Slogwang * 35a9643ea8Slogwang * The stub functions are implemented in pthread_shim.c 36a9643ea8Slogwang * 37a9643ea8Slogwang * The stub will take care of adapting parameters, and any police 38a9643ea8Slogwang * any constraints where lthread functionality differs. 39a9643ea8Slogwang * 40a9643ea8Slogwang * The initial thread must always be a pure lthread. 41a9643ea8Slogwang * 42a9643ea8Slogwang * The decision whether to invoke the real library function or the lthread 43a9643ea8Slogwang * function is controlled by a per pthread flag that can be switched 44a9643ea8Slogwang * on of off by the pthread_override_set() API described below. Typcially 45a9643ea8Slogwang * this should be done as the first action of the initial lthread. 46a9643ea8Slogwang * 47a9643ea8Slogwang * N.B In general it would be poor practice to revert to invoke a real 48a9643ea8Slogwang * pthread function when running as an lthread, since these may block and 49a9643ea8Slogwang * effectively stall the lthread scheduler. 50a9643ea8Slogwang * 51a9643ea8Slogwang */ 52a9643ea8Slogwang 53a9643ea8Slogwang 54a9643ea8Slogwang /* 55a9643ea8Slogwang * An exiting lthread must not terminate the pthread it is running in 56a9643ea8Slogwang * since this would mean terminating the lthread scheduler. 57a9643ea8Slogwang * We override pthread_exit() with a macro because it is typically declared with 58*2d9fd380Sjfb8856606 * __rte_noreturn 59a9643ea8Slogwang */ 60a9643ea8Slogwang void pthread_exit_override(void *v); 61a9643ea8Slogwang 62a9643ea8Slogwang #define pthread_exit(v) do { \ 63a9643ea8Slogwang pthread_exit_override((v)); \ 64a9643ea8Slogwang return NULL; \ 65a9643ea8Slogwang } while (0) 66a9643ea8Slogwang 67a9643ea8Slogwang /* 68a9643ea8Slogwang * Enable/Disable pthread override 69a9643ea8Slogwang * state 70a9643ea8Slogwang * 0 disable 71a9643ea8Slogwang * 1 enable 72a9643ea8Slogwang */ 73a9643ea8Slogwang void pthread_override_set(int state); 74a9643ea8Slogwang 75a9643ea8Slogwang 76a9643ea8Slogwang /* 77a9643ea8Slogwang * Return pthread override state 78a9643ea8Slogwang * return 79a9643ea8Slogwang * 0 disable 80a9643ea8Slogwang * 1 enable 81a9643ea8Slogwang */ 82a9643ea8Slogwang int pthread_override_get(void); 83a9643ea8Slogwang 84a9643ea8Slogwang 85a9643ea8Slogwang #endif /* _PTHREAD_SHIM_H_ */ 86