About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
libFAUDES

Sections

Index

cfl_platform.h

Go 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.22k --- 2013.04.02 --- c++ source docu by doxygen