1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // The University of Illinois/NCSA
4 // Open Source License (NCSA)
5 //
6 // Copyright (c) 2014-2015, Advanced Micro Devices, Inc. All rights reserved.
7 //
8 // Developed by:
9 //
10 //                 AMD Research and AMD HSA Software Development
11 //
12 //                 Advanced Micro Devices, Inc.
13 //
14 //                 www.amd.com
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining a copy
17 // of this software and associated documentation files (the "Software"), to
18 // deal with the Software without restriction, including without limitation
19 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 // and/or sell copies of the Software, and to permit persons to whom the
21 // Software is furnished to do so, subject to the following conditions:
22 //
23 //  - Redistributions of source code must retain the above copyright notice,
24 //    this list of conditions and the following disclaimers.
25 //  - Redistributions in binary form must reproduce the above copyright
26 //    notice, this list of conditions and the following disclaimers in
27 //    the documentation and/or other materials provided with the distribution.
28 //  - Neither the names of Advanced Micro Devices, Inc,
29 //    nor the names of its contributors may be used to endorse or promote
30 //    products derived from this Software without specific prior written
31 //    permission.
32 //
33 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
36 // THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
37 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
38 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
39 // DEALINGS WITH THE SOFTWARE.
40 //
41 ////////////////////////////////////////////////////////////////////////////////
42 
43 // Minimal operating system abstraction interfaces.
44 
45 #ifndef HSA_RUNTIME_CORE_UTIL_OS_H_
46 #define HSA_RUNTIME_CORE_UTIL_OS_H_
47 
48 #include <string>
49 #include "utils.h"
50 
51 namespace os {
52 typedef void* LibHandle;
53 typedef void* Mutex;
54 typedef void* Thread;
55 typedef void* EventHandle;
56 
57 enum class os_t { OS_WIN = 0, OS_LINUX, OS_FREEBSD, OS_DRAGONFLY, COUNT };
os_index(os_t val)58 static __forceinline std::underlying_type<os_t>::type os_index(os_t val) {
59   return std::underlying_type<os_t>::type(val);
60 }
61 
62 #ifdef _WIN32
63 static const os_t current_os = os_t::OS_WIN;
64 #elif __linux__
65 static const os_t current_os = os_t::OS_LINUX;
66 #elif __FreeBSD__
67 static const os_t current_os = os_t::OS_FREEBSD;
68 #elif __DragonFly__
69 static const os_t current_os = os_t::OS_DRAGONFLY;
70 #else
71 static_assert(false, "Operating System not detected!");
72 #endif
73 
74 /// @brief: Loads dynamic library based on file name. Return value will be NULL
75 /// if failed.
76 /// @param: filename(Input), file name of the library.
77 /// @return: LibHandle.
78 LibHandle LoadLib(std::string filename);
79 
80 /// @brief: Gets the address of exported symbol. Return NULl if failed.
81 /// @param: lib(Input), library handle which exporting from.
82 /// @param: export_name(Input), the name of the exported symbol.
83 /// @return: void*.
84 void* GetExportAddress(LibHandle lib, std::string export_name);
85 
86 /// @brief: Unloads the dynamic library.
87 /// @param: lib(Input), library handle which will be unloaded.
88 void CloseLib(LibHandle lib);
89 
90 /// @brief: Creates a mutex, will return NULL if failed.
91 /// @param: void.
92 /// @return: Mutex.
93 Mutex CreateMutex();
94 
95 /// @brief: Tries to acquire the mutex once, if successed, return true.
96 /// @param: lock(Input), handle to the mutex.
97 /// @return: bool.
98 bool TryAcquireMutex(Mutex lock);
99 
100 /// @brief: Aquires the mutex, if the mutex is locked, it will wait until it is
101 /// released. If the mutex is acquired successfully, it will return true.
102 /// @param: lock(Input), handle to the mutex.
103 /// @return: bool.
104 bool AcquireMutex(Mutex lock);
105 
106 /// @brief: Releases the mutex.
107 /// @param: lock(Input), handle to the mutex.
108 /// @return: void.
109 void ReleaseMutex(Mutex lock);
110 
111 /// @brief: Destroys the mutex.
112 /// @param: lock(Input), handle to the mutex.
113 /// @return: void.
114 void DestroyMutex(Mutex lock);
115 
116 /// @brief: Puts current thread to sleep.
117 /// @param: delayInMs(Input), time in millisecond for sleeping.
118 /// @return: void.
119 void Sleep(int delayInMs);
120 
121 /// @brief: Puts current thread to sleep.
122 /// @param: delayInMs(Input), time in millisecond for sleeping.
123 /// @return: void.
124 void uSleep(int delayInUs);
125 
126 /// @brief: Yields current thread.
127 /// @param: void.
128 /// @return: void.
129 void YieldThread();
130 
131 typedef void (*ThreadEntry)(void*);
132 
133 /// @brief: Creates a thread will return NULL if failed.
134 /// @param: entry_function(Input), a pointer to the function which the thread
135 /// starts from.
136 /// @param: entry_argument(Input), a pointer to the argument of the thread
137 /// function.
138 /// @param: stack_size(Input), size of the thread's stack, 0 by default.
139 /// @return: Thread, a handle to thread created.
140 Thread CreateThread(ThreadEntry entry_function, void* entry_argument,
141                     uint stack_size = 0);
142 
143 /// @brief: Destroys the thread.
144 /// @param: thread(Input), thread handle to what will be destroyed.
145 /// @return: void.
146 void CloseThread(Thread thread);
147 
148 /// @brief: Waits for specific thread to finish, if successed, return true.
149 /// @param: thread(Input), handle to waiting thread.
150 /// @return: bool.
151 bool WaitForThread(Thread thread);
152 
153 /// @brief: Waits for multiple threads to finish, if successed, return ture.
154 /// @param; threads(Input), a pointer to a list of thread handle.
155 /// @param: thread_count(Input), number of threads to be waited on.
156 /// @return: bool.
157 bool WaitForAllThreads(Thread* threads, uint thread_count);
158 
159 /// @brief: Sets the environment value.
160 /// @param: env_var_name(Input), name of the environment value.
161 /// @param: env_var_value(Input), value of the environment value.s
162 /// @return: void.
163 void SetEnvVar(std::string env_var_name, std::string env_var_value);
164 
165 /// @brief: Gets the value of environment value.
166 /// @param: env_var_name(Input), name of the environment value.
167 /// @return: std::string, value of the environment value, returned as string.
168 std::string GetEnvVar(std::string env_var_name);
169 
170 /// @brief: Gets the max virtual memory size accessible to the application.
171 /// @param: void.
172 /// @return: size_t, size of the accessible memory to the application.
173 size_t GetUserModeVirtualMemorySize();
174 
175 /// @brief: Gets the max physical host system memory size.
176 /// @param: void.
177 /// @return: size_t, size of the physical host system memory.
178 size_t GetUsablePhysicalHostMemorySize();
179 
180 /// @brief: Gets the virtual memory base address. It is hardcoded to 0.
181 /// @param: void.
182 /// @return: uintptr_t, always 0.
183 uintptr_t GetUserModeVirtualMemoryBase();
184 
185 /// @brief os event api, create an event
186 /// @param: auto_reset whether an event can reset the status automatically
187 /// @param: init_state initial state of the event
188 /// @return: event handle
189 EventHandle CreateOsEvent(bool auto_reset, bool init_state);
190 
191 /// @brief os event api, destroy an event
192 /// @param: event handle
193 /// @return: whether destroy is correct
194 int DestroyOsEvent(EventHandle event);
195 
196 /// @brief os event api, wait on event
197 /// @param: event Event handle
198 /// @param: milli_seconds wait time
199 /// @return: Indicate success or timeout
200 int WaitForOsEvent(EventHandle event, unsigned int milli_seconds);
201 
202 /// @brief os event api, set event state
203 /// @param: event Event handle
204 /// @return: Whether event set is correct
205 int SetOsEvent(EventHandle event);
206 
207 /// @brief os event api, reset event state
208 /// @param: event Event handle
209 /// @return: Whether event reset is correct
210 int ResetOsEvent(EventHandle event);
211 
212 /// @brief reads a clock which is deemed to be accurate for elapsed time
213 /// measurements, though not necessarilly fast to query
214 /// @return clock counter value
215 uint64_t ReadAccurateClock();
216 
217 /// @brief retrieves the frequency in Hz of the unit used in ReadAccurateClock.
218 /// It does not necessarilly reflect the resolution of the clock, but is the
219 /// value needed to convert a difference in the clock's counter value to elapsed
220 /// seconds.  This frequency does not change at runtime.
221 /// @return returns the frequency
222 uint64_t AccurateClockFrequency();
223 }
224 
225 #endif  // HSA_RUNTIME_CORE_UTIL_OS_H_
226