ObjFW  Check-in [b4023e6bc0]

Overview
Comment:Change the definition of thread priorities

The old definition was quite unpredictable and too platform-specific.
The new one defines -1.0 as lowest priority that still schedules, 0.0 as
the normal priority (meaning the same as the main thread) and +1.0 as
the highest priority that still allows getting preempted.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: b4023e6bc06c9190b1e8e693a2643f4e1b502b0a81d5ef41f33392580a232974
User & Date: js on 2016-03-28 16:50:16
Other Links: manifest | tags
Context
2016-03-28
19:33
URL encoding: Make sure an unsigned shift is used check-in: 179c625d15 user: js tags: trunk
16:50
Change the definition of thread priorities check-in: b4023e6bc0 user: js tags: trunk
11:26
Move Haiku-specific include to the right file check-in: f58ea581f0 user: js tags: trunk
Changes

Modified src/OFThread.h from [7293edf304] to [383f3c4912].

218
219
220
221
222
223
224




225
226
227
228
229
230
231
232
233
234



235
236
237
238
239
240
241
242
 * @param name The name for the thread
 */
- (void)setName: (nullable OFString*)name;

/*!
 * @brief Returns the priority of the thread.
 *




 * @return The priority of the thread
 */
- (float)priority;

/*!
 * @brief Sets the priority of the thread.
 *
 * @note This has to be set before the thread is started!
 *
 * @param priority The priority for the thread, with 0.0 being the lowest and



 *		   1.0 the highest
 */
- (void)setPriority: (float)priority;

/*!
 * @brief Returns the stack size of the thread.
 *
 * @return The stack size of the thread







>
>
>
>









|
>
>
>
|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
 * @param name The name for the thread
 */
- (void)setName: (nullable OFString*)name;

/*!
 * @brief Returns the priority of the thread.
 *
 * This is a value between -1.0 (meaning lowest priority that still schedules)
 * and +1.0 (meaning highest priority that still allows getting preemptted)
 * with normal priority being 0.0 (meaning being the same as the main thread).
 *
 * @return The priority of the thread
 */
- (float)priority;

/*!
 * @brief Sets the priority of the thread.
 *
 * @note This has to be set before the thread is started!
 *
 * @param priority The priority of the thread. This is a value between -1.0
 *		   (meaning lowest priority that still schedules) and +1.0
 *		   (meaning highest priority that still allows getting
 *		   preemptted) with normal priority being 0.0 (meaning being
 *		   the same as the main thread).
 */
- (void)setPriority: (float)priority;

/*!
 * @brief Returns the stack size of the thread.
 *
 * @return The stack size of the thread

Modified src/threading_pthread.m from [706256fda3] to [22a0bb4722].

22
23
24
25
26
27
28


29
30
31
32






















33
34
35
36
37
38
39

#import "macros.h"

#ifdef OF_HAIKU
# include <kernel/OS.h>
#endif



struct thread_ctx {
	void (*function)(id object);
	id object;
};























static void*
function_wrapper(void *data)
{
	struct thread_ctx *ctx = data;

	pthread_cleanup_push(free, data);







>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

#import "macros.h"

#ifdef OF_HAIKU
# include <kernel/OS.h>
#endif

static int minPrio, maxPrio, normalPrio;

struct thread_ctx {
	void (*function)(id object);
	id object;
};

/*
 * This is done here to make sure this is done as early as possible in the main
 * thread.
 */
static void __attribute__((constructor))
init(void)
{
	pthread_attr_t pattr;
	int policy;
	struct sched_param param;

	OF_ENSURE(pthread_attr_init(&pattr) == 0);
	OF_ENSURE(pthread_attr_getschedpolicy(&pattr, &policy) == 0);
	OF_ENSURE((minPrio = sched_get_priority_min(policy)) != -1);
	OF_ENSURE((maxPrio = sched_get_priority_max(policy)) != -1);
	OF_ENSURE(pthread_attr_getschedparam(&pattr, &param) == 0);

	normalPrio = param.sched_priority;

	pthread_attr_destroy(&pattr);
}

static void*
function_wrapper(void *data)
{
	struct thread_ctx *ctx = data;

	pthread_cleanup_push(free, data);
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
{
	pthread_attr_t pattr;

	if (pthread_attr_init(&pattr) != 0)
		return false;

	@try {
		int policy, minPrio, maxPrio;
		struct sched_param param;

		if (pthread_attr_getschedpolicy(&pattr, &policy) != 0)
			return false;

		minPrio = sched_get_priority_min(policy);
		maxPrio = sched_get_priority_max(policy);

		if (pthread_attr_getschedparam(&pattr, &param) != 0)
			return false;

		/* Prevent possible division by zero */
		if (minPrio != maxPrio)
			attr->priority = (float)(param.sched_priority -
			    minPrio) / (maxPrio - minPrio);
		else
			attr->priority = 0;

		if (pthread_attr_getstacksize(&pattr, &attr->stackSize) != 0)
			return false;
	} @finally {
		pthread_attr_destroy(&pattr);
	}








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







73
74
75
76
77
78
79

















80
81
82
83
84
85
86
87
{
	pthread_attr_t pattr;

	if (pthread_attr_init(&pattr) != 0)
		return false;

	@try {

















		attr->priority = 0;

		if (pthread_attr_getstacksize(&pattr, &attr->stackSize) != 0)
			return false;
	} @finally {
		pthread_attr_destroy(&pattr);
	}

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118








119
120
121
122
123
124
125
	if (pthread_attr_init(&pattr) != 0)
		return false;

	@try {
		struct thread_ctx *ctx;

		if (attr != NULL) {
			int policy, minPrio, maxPrio;
			struct sched_param param;

			if (attr->priority < 0 || attr->priority > 1)
				return false;

			if (pthread_attr_getschedpolicy(&pattr, &policy) != 0)
				return false;

			minPrio = sched_get_priority_min(policy);
			maxPrio = sched_get_priority_max(policy);

			param.sched_priority = (float)minPrio +
			    attr->priority * (maxPrio - minPrio);

#ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED
			if (pthread_attr_setinheritsched(&pattr,
			    PTHREAD_EXPLICIT_SCHED) != 0)
				return false;
#endif









			if (pthread_attr_setschedparam(&pattr, &param) != 0)
				return false;

			if (attr->stackSize > 0) {
				if (pthread_attr_setstacksize(&pattr,
				    attr->stackSize) != 0)
					return false;







<


|

<
<
<
<
<
<
<
<
<







>
>
>
>
>
>
>
>







98
99
100
101
102
103
104

105
106
107
108









109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
	if (pthread_attr_init(&pattr) != 0)
		return false;

	@try {
		struct thread_ctx *ctx;

		if (attr != NULL) {

			struct sched_param param;

			if (attr->priority < -1 || attr->priority > 1)
				return false;










#ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED
			if (pthread_attr_setinheritsched(&pattr,
			    PTHREAD_EXPLICIT_SCHED) != 0)
				return false;
#endif

			if (attr->priority < 0) {
				param.sched_priority = minPrio +
				    (1.0 + attr->priority) *
				    (normalPrio - minPrio);
			} else
				param.sched_priority = normalPrio +
				    attr->priority * (maxPrio - normalPrio);

			if (pthread_attr_setschedparam(&pattr, &param) != 0)
				return false;

			if (attr->stackSize > 0) {
				if (pthread_attr_setstacksize(&pattr,
				    attr->stackSize) != 0)
					return false;

Modified src/threading_winapi.m from [eefc937c4b] to [89698eef26].

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43





44

45
46
47
48
49
50
51
#include "config.h"

#import "macros.h"

bool
of_thread_attr_init(of_thread_attr_t *attr)
{
	attr->priority =
	    (float)(THREAD_PRIORITY_NORMAL - THREAD_PRIORITY_LOWEST) /
	    (THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_LOWEST);
	attr->stackSize = 0;

	return true;
}

bool
of_thread_new(of_thread_t *thread, void (*function)(id), id object,
    const of_thread_attr_t *attr)
{
	size_t stackSize = 0;
	int priority = 0;

	if (attr != NULL) {
		if (attr->priority < 0 || attr->priority > 1)
			return false;


		priority = THREAD_PRIORITY_LOWEST + attr->priority *





		    (THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_LOWEST);

		stackSize = attr->stackSize;
	}

	*thread = CreateThread(NULL, stackSize,
	    (LPTHREAD_START_ROUTINE)function, (__bridge void*)object, 0, NULL);

	if (thread == NULL)







|
<
<













|


>
|
>
>
>
>
>
|
>







17
18
19
20
21
22
23
24


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "config.h"

#import "macros.h"

bool
of_thread_attr_init(of_thread_attr_t *attr)
{
	attr->priority = 0;


	attr->stackSize = 0;

	return true;
}

bool
of_thread_new(of_thread_t *thread, void (*function)(id), id object,
    const of_thread_attr_t *attr)
{
	size_t stackSize = 0;
	int priority = 0;

	if (attr != NULL) {
		if (attr->priority < -1 || attr->priority > 1)
			return false;

		if (attr->priority < 0)
			priority = THREAD_PRIORITY_LOWEST +
			    (1.0 + attr->priority) *
			    (THREAD_PRIORITY_NORMAL - THREAD_PRIORITY_LOWEST);
		else
			priority = THREAD_PRIORITY_NORMAL +
			    attr->priority *
			    (THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_NORMAL);

		stackSize = attr->stackSize;
	}

	*thread = CreateThread(NULL, stackSize,
	    (LPTHREAD_START_ROUTINE)function, (__bridge void*)object, 0, NULL);

	if (thread == NULL)