libFAUDES
Sections
Index
|
cfl_platform.hGo to the documentation of this file.00001 /** @file cfl_platform.h Platform dependant wrappers */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2013 Thomas Moor 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2.1 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 00023 #ifndef FAUDES_PLATFORM_H 00024 #define FAUDES_PLATFORM_H 00025 00026 /** Sense POSIX versus Windows */ 00027 #ifndef FAUDES_POSIX 00028 #ifndef FAUDES_WINDOWS 00029 00030 #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) 00031 #define FAUDES_WINDOWS 00032 #else 00033 #define FAUDES_POSIX 00034 #endif 00035 00036 #endif 00037 #endif 00038 00039 00040 // Std headers 00041 #include <cstdlib> 00042 #include <cstring> 00043 #include <limits> 00044 #include <string> 00045 #include <iostream> 00046 #include <sstream> 00047 #include <fstream> 00048 #include <iomanip> 00049 #include <map> 00050 #include <set> 00051 00052 // Extra POSIX headers 00053 #ifdef FAUDES_POSIX 00054 00055 #include <stdlib.h> 00056 #include <cerrno> 00057 #include <fcntl.h> 00058 00059 #ifdef FAUDES_SYSTIME 00060 #include <time.h> 00061 #include <sys/time.h> 00062 #endif 00063 00064 #ifdef FAUDES_NETWORK 00065 #include <sys/socket.h> 00066 #include <arpa/inet.h> 00067 #include <netdb.h> 00068 #endif 00069 00070 #ifdef FAUDES_THREADS 00071 #include <pthread.h> 00072 #endif 00073 00074 00075 #endif 00076 00077 00078 // Extra Windows/MinGW headers 00079 #ifdef FAUDES_WINDOWS 00080 00081 #ifndef WIN32_LEAN_AND_MEAN 00082 #define WIN32_LEAN_AND_MEAN 00083 #define FAUDES_LEAN_AND_MEAN 00084 #endif 00085 #include <windows.h> 00086 #ifdef FAUDES_LEAN_AND_MEAN 00087 #undef FAUDES_LEAN_AND_MEAN 00088 #undef WIN32_LEAN_AND_MEAN 00089 #endif 00090 00091 #ifdef FAUDES_SYSTIME 00092 #include <time.h> 00093 #include <sys/time.h> 00094 #endif 00095 00096 #ifdef FAUDES_NETWORK 00097 #include <winsock2.h> 00098 #include <fcntl.h> 00099 #endif 00100 00101 #ifdef FAUDES_THREADS 00102 #include <process.h> 00103 #endif 00104 00105 00106 #endif 00107 00108 00109 00110 // Path-seperators (see cfl_helper.cpp) 00111 // * the first separator is the one used to prepend directories etc 00112 // * all other separators are used to extract basenames 00113 // * using gcc/make also on Windows, we occasionaly get Unix style files names 00114 // in the build process ... thus we allways define the Unix "/" as a separator 00115 // * summary: we use "/" for POSIX and "\\:/" for Windows. 00116 extern const std::string faudes_pathseps_str; 00117 inline const std::string& faudes_pathseps(void) { 00118 return faudes_pathseps_str; 00119 } 00120 00121 // Path-seperator (first char of above, see cfl_helper.cpp) 00122 extern const std::string faudes_pathsep_str; 00123 inline const std::string& faudes_pathsep(void) { 00124 return faudes_pathsep_str; 00125 } 00126 00127 00128 // Uniform exit-signalhandler for POSIX / Windows/MinGW (see e.g. simfaudes.cpp) 00129 void faudes_termsignal(void (*sighandler)(int)); 00130 00131 // Uniform signal names for POSIX / Windows/MinGW (see e.g. simfaudes.cpp) 00132 const char* faudes_strsignal(int sig); 00133 00134 // Uniform sleep for POSIX and Windows/MinGW (see e.g. iodevice plug-in) 00135 #ifdef FAUDES_POSIX 00136 inline void faudes_sleep(long int sec) {sleep(sec);} 00137 inline void faudes_usleep(long int usec) {usleep(usec);} 00138 #endif 00139 #ifdef FAUDES_WINDOWS 00140 inline void faudes_sleep(long int sec) {Sleep((sec) * 1000);} 00141 inline void faudes_usleep(long int usec) {Sleep((usec) / 1000);} 00142 #endif 00143 00144 00145 00146 #ifdef FAUDES_SYSTIME 00147 00148 // Uniform system time using POSIX pthreads semantics 00149 #ifdef FAUDES_POSIX 00150 typedef timespec faudes_systime_t; 00151 typedef long int faudes_mstime_t; 00152 #endif 00153 #ifdef FAUDES_WINDOWS 00154 typedef struct { 00155 long int tv_sec; 00156 long int tv_nsec; 00157 } faudes_systime_t; 00158 typedef long int faudes_mstime_t; 00159 #endif 00160 00161 // Uniform system time definitions 00162 void faudes_gettimeofday(faudes_systime_t* now); 00163 void faudes_diffsystime(const faudes_systime_t& end, const faudes_systime_t& begin, faudes_systime_t* res); 00164 void faudes_sumsystime(const faudes_systime_t& begin, const faudes_systime_t& duration, faudes_systime_t* res); 00165 void faudes_msdelay(faudes_mstime_t msecs,faudes_systime_t* end); 00166 void faudes_usdelay(faudes_mstime_t usecs,faudes_systime_t* end); 00167 00168 #endif 00169 00170 00171 00172 #ifdef FAUDES_NETWORK 00173 00174 // Uniform POSIX sockets (see iop_modbus.cpp and iop_simplenet.cpp) 00175 #ifdef FAUDES_POSIX 00176 inline int faudes_closesocket(int fd) {return close(fd);} 00177 inline int faudes_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen) { 00178 return setsockopt(fd,level,optname,optval,optlen);} 00179 inline int faudes_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen) { 00180 return getsockopt(fd,level,optname,optval,optlen);} 00181 int faudes_setsocket_nonblocking(int fd, bool noblo); 00182 int faudes_getsocket_error(int fd); 00183 #endif 00184 #ifdef FAUDES_WINDOWS 00185 typedef int socklen_t; 00186 inline int faudes_closesocket(int fd) {return closesocket(fd);} 00187 inline int faudes_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen) { 00188 return setsockopt(fd,level,optname,(char*) optval,optlen);} 00189 inline int faudes_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen) { 00190 return getsockopt(fd,level,optname,(char*) optval,optlen);} 00191 int faudes_setsocket_nonblocking(int fd, bool noblo); 00192 int faudes_getsocket_error(int fd); 00193 #endif 00194 00195 // POSIX sockets to have BSD style REUSEPORT option (see iop_modbus.cpp and iop_simplenet.cpp) 00196 #ifndef SO_REUSEPORT 00197 #define SO_REUSEPORT SO_REUSEADDR 00198 #endif 00199 00200 #endif 00201 00202 00203 #ifdef FAUDES_THREADS 00204 00205 /* 00206 The remaining section of this file provides elementary support for threads, 00207 using a minimalistic subset of the POSIX threads interface. It is tailored for 00208 the use of edge-detection and networking as required by the iodevice plug-in. 00209 In general, libFAUDES is not threadsafe due to global variables, e.g. 00210 symoltables. This may change in a future revision. 00211 */ 00212 00213 00214 // Common return codes 00215 #define FAUDES_THREAD_SUCCESS 0 00216 #define FAUDES_THREAD_ERROR 1 00217 #define FAUDES_THREAD_TIMEOUT 2 00218 00219 00220 00221 #ifdef FAUDES_POSIX 00222 // Thread data type (use plain POSIX thread) 00223 typedef pthread_t faudes_thread_t; 00224 // Thread functions (all inline, plain pthread wrapper) 00225 inline int faudes_thread_create(faudes_thread_t *thr, void *(*fnct)(void *), void *arg){ 00226 // prepare attribute for plain joinable thread 00227 pthread_attr_t attr; 00228 pthread_attr_init(&attr); 00229 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 00230 // start execute 00231 int ret = pthread_create(thr, &attr, fnct, arg); 00232 // done 00233 pthread_attr_destroy(&attr); 00234 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00235 } 00236 inline faudes_thread_t faudes_thread_current(void) { 00237 return pthread_self(); 00238 } 00239 inline int faudes_thread_detach(faudes_thread_t thr) { 00240 return pthread_detach(thr)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00241 } 00242 inline int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1) { 00243 return pthread_equal(thr0, thr1); 00244 } 00245 inline void faudes_thread_exit(void* res) { 00246 pthread_exit(res); 00247 } 00248 inline int faudes_thread_join(faudes_thread_t thr, void **res) { 00249 return pthread_join(thr, res) == 0 ? FAUDES_THREAD_ERROR : FAUDES_THREAD_SUCCESS; 00250 } 00251 #endif 00252 00253 00254 #ifdef FAUDES_WINDOWS 00255 // Thread data type 00256 // We wrap the client function to provide pointer-typed 00257 // return values (as opposed to Windows int-typed return values) 00258 typedef struct { 00259 HANDLE mHandle; // Windows thread handle 00260 void *(*mFnct)(void *); // client function 00261 void *mArg; // argument 00262 void *mRes; // result 00263 } faudes_thread_record_t; 00264 typedef faudes_thread_record_t* faudes_thread_t; 00265 // Thread functions (Windows to mimic plain pthreads) 00266 int faudes_thread_create(faudes_thread_t *thr, void *(*fnct)(void *), void *arg); 00267 faudes_thread_t faudes_thread_current(void); 00268 int faudes_thread_detach(faudes_thread_t thr); 00269 int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1); 00270 void faudes_thread_exit(void* res); 00271 int faudes_thread_join(faudes_thread_t thr, void **res); 00272 #endif 00273 00274 00275 #ifdef FAUDES_POSIX 00276 // Mutex data type (use plain POSIX mutex) 00277 typedef pthread_mutex_t faudes_mutex_t; 00278 // Mutex functions (all inline, plain pthread wrapper) 00279 inline int faudes_mutex_init(faudes_mutex_t* mtx){ 00280 return pthread_mutex_init(mtx, NULL)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00281 } 00282 inline void faudes_mutex_destroy(faudes_mutex_t* mtx){ 00283 pthread_mutex_destroy(mtx); 00284 } 00285 inline int faudes_mutex_lock(faudes_mutex_t *mtx) { 00286 return pthread_mutex_lock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00287 } 00288 inline int faudes_mutex_trylock(faudes_mutex_t *mtx){ 00289 return (pthread_mutex_trylock(mtx) == 0) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00290 } 00291 inline int faudes_mutex_unlock(faudes_mutex_t *mtx){ 00292 return pthread_mutex_unlock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00293 } 00294 #endif 00295 00296 00297 #ifdef FAUDES_WINDOWS 00298 // Mutex data type (use Windows "critical section") 00299 typedef CRITICAL_SECTION faudes_mutex_t; 00300 // Mutex functions (all inline, wraps to Windows "critical section") 00301 inline int faudes_mutex_init(faudes_mutex_t *mtx){ 00302 InitializeCriticalSection(mtx); 00303 return FAUDES_THREAD_SUCCESS; 00304 } 00305 inline void faudes_mutex_destroy(faudes_mutex_t *mtx){ 00306 DeleteCriticalSection(mtx); 00307 } 00308 inline int faudes_mutex_lock(faudes_mutex_t *mtx) { 00309 EnterCriticalSection(mtx); 00310 return FAUDES_THREAD_SUCCESS; 00311 } 00312 inline int faudes_mutex_trylock(faudes_mutex_t *mtx){ 00313 return TryEnterCriticalSection(mtx) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00314 } 00315 inline int faudes_mutex_unlock(faudes_mutex_t *mtx){ 00316 LeaveCriticalSection(mtx); 00317 return FAUDES_THREAD_SUCCESS; 00318 } 00319 #endif 00320 00321 00322 #ifdef FAUDES_POSIX 00323 // Condition variable data type (use plain POSIX condition variables) 00324 typedef pthread_cond_t faudes_cond_t; 00325 // Condition functions (all inline, plain pthread wrapper) 00326 inline int faudes_cond_init(faudes_cond_t* cond) { 00327 return pthread_cond_init(cond, NULL) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00328 } 00329 inline void faudes_cond_destroy(faudes_cond_t* cond) { 00330 pthread_cond_destroy(cond); 00331 } 00332 inline int faudes_cond_signal(faudes_cond_t *cond){ 00333 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00334 } 00335 inline int faudes_cond_broadcast(faudes_cond_t *cond) { 00336 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00337 } 00338 inline int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx) { 00339 return pthread_cond_wait(cond, mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00340 } 00341 inline int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, const faudes_systime_t *abstime) { 00342 int ret = pthread_cond_timedwait(cond, mtx, abstime); 00343 if(ret == ETIMEDOUT) return FAUDES_THREAD_TIMEOUT; 00344 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR; 00345 } 00346 // Extension: timed wait with duration as opposed to absolute time 00347 inline int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration) { 00348 faudes_systime_t abstime; 00349 faudes_msdelay(duration,&abstime); 00350 return faudes_cond_timedwait(cond,mtx,&abstime); 00351 } 00352 #endif 00353 00354 00355 #ifdef FAUDES_WINDOWS 00356 // Condition variable data type 00357 // The approach is taken from "Strategies for Implementing POSIX Condition Variables 00358 // on Win32" by Douglas C. Schmidt and Irfan Pyarali, Department of Computer 00359 // Science, Washington University. 00360 typedef struct { 00361 HANDLE mEvents[2]; // signal and broadcast event handles 00362 unsigned int mWaitersCount; // count the number of waiters 00363 CRITICAL_SECTION mWaitersCountMutex; // mutex access to waiterscount 00364 } faudes_cond_t; 00365 // Condition functions (Windows to mimic plain pthread conditions) 00366 int faudes_cond_init(faudes_cond_t* cond); 00367 void faudes_cond_destroy(faudes_cond_t* cond); 00368 int faudes_cond_signal(faudes_cond_t *cond); 00369 int faudes_cond_broadcast(faudes_cond_t *cond); 00370 int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx); 00371 int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, const faudes_systime_t *abstime); 00372 int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration); 00373 #endif 00374 00375 00376 00377 00378 00379 #endif // threads 00380 00381 #endif // header 00382 |
libFAUDES 2.22s --- 2013.10.07 --- c++ source docu by doxygen