summaryrefslogtreecommitdiff
path: root/src/common/thread.h
blob: 1aba44c15225bc0acaedf6eac8264aa50c06869e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
 * This file is part of Hercules.
 * http://herc.ws - http://github.com/HerculesWS/Hercules
 *
 * Copyright (C) 2012-2020 Hercules Dev Team
 * Copyright (C) rAthena Project (www.rathena.org)
 *
 * Hercules is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef COMMON_THREAD_H
#define COMMON_THREAD_H

#include "common/hercules.h"

/** @file
 * Basic Threading abstraction (for pthread / win32 based systems).
 */

/* Opaque Types */
struct thread_handle;                ///< Thread handle.
typedef void *(*threadFunc)(void *); ///< Thread entry point function.

/* Enums */

/// Thread priority
enum thread_priority {
	THREADPRIO_LOW = 0,
	THREADPRIO_NORMAL,
	THREADPRIO_HIGH
};

/// The thread interface
struct thread_interface {
	/// Interface initialization.
	void (*init) (void);

	/// Interface finalization.
	void (*final) (void);

	/**
	 * Creates a new Thread.
	 *
	 * @param enty_point Thread's entry point.
	 * @param param      General purpose parameter, would be given as
	 *                   parameter to the thread's entry point.
	 *
	 * @return The created thread object.
	 * @retval NULL in vase of failure.
	 */
	struct thread_handle *(*create) (threadFunc entry_point, void *param);

	/**
	 * Creates a new Thread (with more creation options).
	 *
	 * @param enty_point Thread's entry point.
	 * @param param      General purpose parameter, would be given as
	 *                   parameter to the thread's entry point.
	 * @param stack_size Stack Size in bytes.
	 * @param prio       Priority of the Thread in the OS scheduler.
	 *
	 * @return The created thread object.
	 * @retval NULL in case of failure.
	 */
	struct thread_handle *(*create_opt) (threadFunc entry_point, void *param, size_t stack_size, enum thread_priority prio);

	/**
	 * Destroys the given Thread immediately.
	 *
	 * @remark
	 *   The Handle gets invalid after call! don't use it afterwards.
	 *
	 * @param handle The thread to destroy.
	 */
	void (*destroy) (struct thread_handle *handle);

	/**
	 * Returns the thread handle of the thread calling this function.
	 *
	 * @remark
	 *   This won't work in the program's main thread.
	 *
	 * @warning
	 *   The underlying implementation might not perform very well, cache
	 *   the value received!
	 *
	 * @return the thread handle.
	 * @retval NULL in case of failure.
	 */
	struct thread_handle *(*self) (void);

	/**
	 * Returns own thread id (TID).
	 *
	 * @remark
	 *   This is an unique identifier for the calling thread, and depends
	 *   on platform/ compiler, and may not be the systems Thread ID!
	 *
	 * @return the thread ID.
	 * @retval -1 in case of failure.
	 */
	int (*get_tid) (void);

	/**
	 * Waits for the given thread to terminate.
	 *
	 * @param[in]  handle        The thread to wait (join) for.
	 * @param[out] out_exit_code Pointer to return the exit code of the
	 *                           given thread after termination (optional).
	 *
	 * @retval true if the given thread has been terminated.
	 */
	bool (*wait) (struct thread_handle *handle, void **out_exit_code);

	/**
	 * Sets the given priority in the OS scheduler.
	 *
	 * @param handle The thread to set the priority for.
	 * @param prio   The priority to set (@see enum thread_priority).
	 */
	void (*prio_set) (struct thread_handle *handle, enum thread_priority prio);

	/**
	 * Gets the current priority of the given thread.
	 *
	 * @param handle The thread to get the priority for.
	 */
	enum thread_priority (*prio_get) (struct thread_handle *handle);

	/**
	 * Tells the OS scheduler to yield the execution of the calling thread.
	 *
	 * @remark
	 *   This will not "pause" the thread, it just allows the OS to spend
	 *   the remaining time of the slice to another thread.
	 */
	void (*yield) (void);
};

#ifdef HERCULES_CORE
void thread_defaults(void);
#endif // HERCULES_CORE

HPShared struct thread_interface *thread; ///< Pointer to the thread interface.

#endif /* COMMON_THREAD_H */