1 /*
2  * Copyright (C) 2000-2015 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2013-2014 John Emmas <john@creativepost.co.uk>
4  * Copyright (C) 2017-2018 Robin Gareus <robin@gareus.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #ifndef __pbd_pthread_utils__
22 #define __pbd_pthread_utils__
23 
24 /* Accommodate thread setting (and testing) for both
25  * 'libpthread' and 'libpthread_win32' (whose implementations
26  * of 'pthread_t' are subtlely different)
27  */
28 #ifndef PTHREAD_MACROS_DEFINED
29 #define PTHREAD_MACROS_DEFINED
30 #ifdef  PTW32_VERSION  /* pthread_win32 */
31 #define mark_pthread_inactive(threadID)  threadID.p=0
32 #define is_pthread_active(threadID)      threadID.p!=0
33 #else                 /* normal pthread */
34 #define mark_pthread_inactive(threadID)  threadID=0
35 #define is_pthread_active(threadID)      threadID!=0
36 #endif  /* PTW32_VERSION */
37 #endif  /* PTHREAD_MACROS_DEFINED */
38 
39 #ifdef COMPILER_MSVC
40 #include <ardourext/pthread.h>
41 #else
42 #include <pthread.h>
43 #endif
44 #include <signal.h>
45 #include <string>
46 #include <stdint.h>
47 
48 #include "pbd/libpbd_visibility.h"
49 #include "pbd/signals.h"
50 
51 #define PBD_RT_STACKSIZE_PROC 0x80000 // 512kB
52 #define PBD_RT_STACKSIZE_HELP 0x08000 // 32kB
53 
54 /* these are relative to sched_get_priority_max()
55  * see pbd_absolute_rt_priority()
56  */
57 # define PBD_RT_PRI_MAIN pbd_pthread_priority (THREAD_MAIN)
58 # define PBD_RT_PRI_MIDI pbd_pthread_priority (THREAD_MIDI)
59 # define PBD_RT_PRI_PROC pbd_pthread_priority (THREAD_PROC)
60 
61 LIBPBD_API int  pthread_create_and_store (std::string name, pthread_t  *thread, void * (*start_routine)(void *), void * arg);
62 LIBPBD_API void pthread_cancel_one (pthread_t thread);
63 LIBPBD_API void pthread_cancel_all ();
64 LIBPBD_API void pthread_kill_all (int signum);
65 LIBPBD_API const char* pthread_name ();
66 LIBPBD_API void pthread_set_name (const char* name);
67 
68 enum PBDThreadClass {
69 	THREAD_MAIN, // main audio I/O thread
70 	THREAD_MIDI, // MIDI I/O threads
71 	THREAD_PROC // realtime worker
72 };
73 
74 LIBPBD_API int pbd_pthread_priority (PBDThreadClass);
75 
76 LIBPBD_API int pbd_pthread_create (
77 		const size_t stacksize,
78 		pthread_t *thread,
79 		void *(*start_routine) (void *),
80 		void *arg);
81 
82 
83 LIBPBD_API int pbd_realtime_pthread_create (
84 		const int policy, int priority, const size_t stacksize,
85 		pthread_t *thread,
86 		void *(*start_routine) (void *),
87 		void *arg);
88 
89 LIBPBD_API int  pbd_absolute_rt_priority (int policy, int priority);
90 LIBPBD_API int  pbd_set_thread_priority (pthread_t, const int policy, int priority);
91 LIBPBD_API bool pbd_mach_set_realtime_policy (pthread_t thread_id, double period_ns, bool main);
92 
93 namespace PBD {
94 	LIBPBD_API extern void notify_event_loops_about_thread_creation (pthread_t, const std::string&, int requests = 256);
95 	LIBPBD_API extern PBD::Signal3<void,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize;
96 }
97 
98 /* pthread-w32 does not support realtime scheduling
99  * (well, windows, doesn't..) and only supports SetThreadPriority()
100  *
101  * pthread_setschedparam() returns ENOTSUP if the policy is not SCHED_OTHER.
102  *
103  * however, pthread_create() with attributes, ignores the policy and
104  * only sets the priority (when PTHREAD_EXPLICIT_SCHED is used).
105  */
106 #ifdef PLATFORM_WINDOWS
107 #define PBD_SCHED_FIFO SCHED_OTHER
108 #else
109 #define PBD_SCHED_FIFO SCHED_FIFO
110 #endif
111 #endif /* __pbd_pthread_utils__ */
112