00001
00002
00003
00004
00005
00006
00007
00008 #ifndef _PLATFORM_H_
00009 #define _PLATFORM_H_
00010
00011 #include <stdio.h>
00012 #include <string.h>
00013 #include <stdlib.h>
00014 #include <rtsLog.h>
00015 #include <iccp.h>
00016
00017 #ifdef sun
00018
00019 #include <synch.h>
00020 #elif unix
00021
00022 #include <semaphore.h>
00023 #endif
00024
00025 #ifdef unix
00026 #include <pthread.h>
00027 #include <sys/mman.h>
00028 #include <SUNRT/msgQLib.h>
00029 #include <SUNRT/ipcQLib.hh>
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 #include <fcntl.h>
00033 #include <errno.h>
00034 #include <unistd.h>
00035 #include <signal.h>
00036 #include <UNIX/ThreadsMsgQueue.hh>
00037 #include <sched.h>
00038 #else // VXWORKS
00039 #include <vxWorks.h>
00040 #include <msgQLib.h>
00041 #include <taskLib.h>
00042 #endif
00043
00044
00045 typedef unsigned int UINT32;
00046 typedef unsigned short UINT16;
00047 typedef unsigned char UINT8;
00048
00049 #ifdef vxworks
00050 extern "C" {
00051 void *memcpy32(UINT32 *dst, UINT32 *src, int cou);
00052 } ;
00053 #endif
00054
00055
00056
00057
00058
00059
00060
00061 #ifdef vxworks
00062 #define pMain(a) a(char *args)
00063 #define pGrabArgs() int argc=1; \
00064 char *argv[20]; \
00065 char *__next_ = strtok(args," "); \
00066 argv[0] = "unknown"; \
00067 while (__next_) { \
00068 argv[argc++] = __next_; \
00069 __next_ = strtok(NULL, " "); \
00070 }
00071 #else
00072 #define pMain(a) main(int argc, char *argv[])
00073 #define pGrabArgs()
00074 #endif
00075
00076 inline void pSleep(int secs)
00077 {
00078 #ifdef vxworks
00079 taskDelay(secs*100);
00080 #else
00081 sleep(secs);
00082 #endif
00083 }
00084
00085
00086 inline void pTaskDelay(int ticks)
00087 {
00088 #ifdef vxworks
00089 taskDelay(ticks);
00090 #else
00091 usleep(ticks * 10000);
00092 #endif
00093 }
00094
00095
00096
00097
00098
00099
00100
00101 #ifdef unix
00102 typedef pthread_t pTASKID;
00103 #else
00104 typedef int pTASKID;
00105 #endif
00106
00107 inline pTASKID pTaskSelf()
00108 {
00109 #ifdef unix
00110 return pthread_self();
00111 #else
00112 return taskIdSelf();
00113 #endif
00114 }
00115
00116 inline pTASKID pTaskSpawn(char *name, int priority, void *f(void *), void *args)
00117 {
00118 pTASKID tid;
00119
00120 #ifdef unix
00121 pthread_attr_t attr;
00122 pthread_attr_init(&attr);
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 if(pthread_create(&tid, &attr, f, args))
00142
00143 {
00144 LOG(NOTE, "Can't setup custom attributes for task %s, not setting priority",name,0,0,0,0);
00145 if(pthread_create(&tid, NULL, f, args)) {
00146 LOG(CRIT, "Error creating %s thread: (%s)", name, strerror(errno));
00147 sleep(10);
00148 exit(0);
00149 }
00150 }
00151 #else
00152 tid = taskSpawn(name,priority,0,4096,(FUNCPTR)f,(int)args,0,0,0,0,0,0,0,0,0);
00153 #endif
00154
00155 return tid;
00156 }
00157
00158 inline int pChangePriority(int prio)
00159 {
00160 #ifdef sun
00161 return -1;
00162 #elif linux
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 return -1;
00175 #else
00176 pTASKID tid = taskIdSelf();
00177 int old=0;
00178 taskPriorityGet(tid, &old);
00179 taskPrioritySet(tid, prio);
00180 return old;
00181 #endif
00182 }
00183
00184 inline int pGetMaxPriority()
00185 {
00186 #ifdef unix
00187 return sched_get_priority_max(SCHED_FIFO);
00188 #else
00189 return 255;
00190 #endif
00191 }
00192
00193 inline void pLockAllMemory()
00194 {
00195 #ifdef vxworks
00196 return;
00197 #else
00198 if(mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
00199 {
00200 LOG(DBG, "Error locking all memory",0,0,0,0,0);
00201 }
00202 #endif
00203 }
00204
00205 inline void pTaskDelete(pTASKID tid)
00206 {
00207 #ifdef sun
00208 LOG(WARN, "thread cancelation not supported in solaris");
00209 #elif unix
00210 pthread_cancel(tid);
00211 #else
00212 taskDelete(tid);
00213 #endif
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 #ifdef sun
00225 typedef sema_t* SEM_ID;
00226 typedef mutex_t* MUX_ID;
00227 #elif unix
00228 typedef sem_t* SEM_ID;
00229 typedef pthread_mutex_t* MUX_ID;
00230 #endif
00231
00232 #ifdef vxworks
00233 typedef SEM_ID MUX_ID;
00234 #endif
00235
00236
00237 #ifdef sun
00238 #define pSEM_PROTO(semName) sema_t rp_##semName; SEM_ID semName = &rp_##semName
00239 #define pMUX_PROTO(muxName) mutex_t rp_##muxName; MUX_ID muxName = &rp_##muxName
00240 #elif unix
00241 #define pSEM_PROTO(semName) sem_t rp_##semName; SEM_ID semName = &rp_##semName
00242 #define pMUX_PROTO(muxName) pthread_mutex_t rp_##muxName; MUX_ID muxName = &rp_##muxName
00243 #else
00244 #define pSEM_PROTO(semName) SEM_ID semName
00245 #define pMUX_PROTO(muxName) pSEM_PROTO(muxName)
00246 #endif
00247
00248
00249
00250 inline void pSemCInit(SEM_ID &sem, int value)
00251 {
00252 #ifdef unix
00253 int ret;
00254 #ifdef sun
00255 ret = sema_init(sem, value, USYNC_THREAD, NULL);
00256 #else // linux
00257 ret = sem_init(sem,0,value);
00258 #endif
00259
00260 if(ret != 0)
00261 {
00262 LOG(CRIT, "Error creating semaphore (%s)",strerror(errno));
00263 }
00264
00265 #else // vxworks
00266 sem = semCCreate(SEM_Q_PRIORITY, value);
00267
00268 #endif
00269 }
00270
00271 inline void pSemBInit(SEM_ID &sem, int value)
00272 {
00273 #ifdef unix
00274 pSemCInit(sem, value);
00275 #else
00276 sem = semBCreate(SEM_Q_PRIORITY, (value == 0) ? SEM_EMPTY : SEM_FULL );
00277
00278 #endif
00279 }
00280
00281
00282 inline void pMuxInit(MUX_ID &mux)
00283 {
00284 #ifdef sun
00285 mutex_init(mux, USYNC_THREAD, NULL);
00286 #elif unix // linux
00287 pthread_mutex_init(mux, NULL);
00288 #else // vxworks
00289 mux = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
00290
00291 #endif
00292 }
00293
00294
00295 inline bool pSemTryTake(SEM_ID sem)
00296 {
00297 int ret;
00298 #ifdef unix
00299 #ifdef sun
00300 ret = sema_trywait(sem);
00301 #else
00302 ret = sem_trywait(sem);
00303 #endif
00304 if(ret == -1) return false;
00305 else return true;
00306 #else // vxworks
00307 ret = semTake(sem, 0);
00308 if(ret == ERROR) return false;
00309 else return true;
00310 #endif
00311 }
00312
00313 inline bool pSemTake(SEM_ID sem)
00314 {
00315 int ret=true;
00316 #ifdef unix
00317 int iret;
00318
00319 do {
00320 #ifdef sun
00321 iret = sema_wait(sem);
00322 #else
00323 iret = sem_wait(sem);
00324 #endif
00325 if((iret) && (errno != EINTR)) {
00326 LOG(CRIT, "semTake error %s",strerror(errno));
00327 }
00328 } while (iret);
00329
00330 #else // vxworks
00331 ret = semTake(sem, 100);
00332 if(ret == ERROR)
00333 ret = false;
00334 else
00335 ret = true;
00336 #endif
00337
00338 return ret;
00339 }
00340
00341 inline void pSemGive(SEM_ID sem)
00342 {
00343 #ifdef sun
00344 sema_post(sem);
00345 #elif unix
00346 sem_post(sem);
00347 #else // vxworks
00348 semGive(sem);
00349 #endif
00350 }
00351
00352 inline void pMuxLock(MUX_ID mux)
00353 {
00354 #ifdef sun
00355 mutex_lock(mux);
00356 #elif unix
00357 pthread_mutex_lock(mux);
00358 #else
00359 semTake(mux,WAIT_FOREVER);
00360 #endif
00361 }
00362
00363
00364
00365 #ifdef linux
00366 inline bool pMuxTryLock(MUX_ID mux)
00367 {
00368 #ifdef sun
00369 mutex_lock(mux);
00370 return true;
00371 #elif unix
00372 int ret = pthread_mutex_trylock(mux);
00373 if(ret == 0) return true;
00374 return false;
00375 #else
00376 semTake(mux,WAIT_FOREVER);
00377 return true ;
00378 #endif
00379 }
00380 #endif
00381
00382 inline void pMuxUnlock(MUX_ID mux)
00383 {
00384 #ifdef sun
00385 mutex_unlock(mux);
00386
00387 #elif unix
00388 pthread_mutex_unlock(mux);
00389 #else
00390 semGive(mux);
00391 #endif
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 #if !defined(IPCQLIB) && !defined(THREAD_MSG_QUEUE) && !defined(SYSVQLIB)
00409 #ifdef sun
00410 #define IPCQLIB
00411 #endif
00412
00413 #ifdef linux
00414 #define THREAD_MSG_QUEUE
00415 #endif
00416 #endif
00417
00418 #ifdef vxworks
00419 #undef IPCQLIB
00420 #undef THREAD_MSG_QUEUE
00421 #undef SYSVQLIB
00422 #endif
00423
00424 #ifdef vxworks
00425 #define QUELIB_STRING "vxworks"
00426 #elif defined(IPCQLIB)
00427 #define QUELIB_STRING "ipcqlib"
00428 #elif defined(THREAD_MSG_QUEUE)
00429 #define QUELIB_STRING "thrMsgQ"
00430 #elif defined(SYSVQLIB)
00431 #define QUELIB_STRING "sysvqlib"
00432 #else
00433 #define QUELIB_STRING "noQs"
00434 #endif
00435
00436 #ifdef THREAD_MSG_QUEUE
00437 extern thrMsgQueue<ic_msg> **pMsgQArray;
00438 #define pALLOC_MSGQARRAY(name) thrMsgQueue<ic_msg> *name[256]
00439 #define pMSGQARRAY_PROTO(name) thrMsgQueue<ic_msg> *name[]
00440 inline void pSetupMsgQArray(thrMsgQueue<ic_msg> *qarray[]) {
00441 pMsgQArray = qarray;
00442 }
00443 #elif defined(IPCQLIB)
00444 #define pALLOC_MSGQARRAY(name) void *name
00445 #define pMSGQARRAY_PROTO(name) void *name
00446 inline void pSetupMsgQArray(void *) {};
00447 #elif defined(SYSVQLIB)
00448 #define pALLOC_MSGQARRAY(name) void *name
00449 #define pMSGQARRAY_PROTO(name) void *name
00450 inline void pSetupMsgQArray(void *) {};
00451 #else
00452 extern MSG_Q_ID *pMsgQArray;
00453 #define pALLOC_MSGQARRAY(name) MSG_Q_ID name[256]
00454 #define pMSGQARRAY_PROTO(name) MSG_Q_ID *name
00455 inline void pSetupMsgQArray(MSG_Q_ID *qarray) {
00456 pMsgQArray = qarray;
00457
00458 LOG(DBG, "pMsgQArray = 0x%x",pMsgQArray,0,0,0,0);
00459 }
00460 #endif
00461
00462 inline bool pMsgQValid(int node, int task)
00463 {
00464 #ifdef THREAD_MSG_QUEUE
00465 if(pMsgQArray[task] == NULL) return false;
00466 else return true;
00467 #elif defined(IPCQLIB)
00468 ipcQClass *c = ipcQClass::find(node, task, 1);
00469
00470 if(c) return true;
00471 return false;
00472 #elif defined(SYSVQLIB)
00473 if(msgQTest(task)) return true;
00474 else return false;
00475 #else
00476 if(pMsgQArray[task] == NULL) return false;
00477 else return true;
00478 #endif
00479 }
00480
00481 inline bool pMsgQCreate(int task, int size, int nmsgs, int mynode=0)
00482 {
00483 #ifdef THREAD_MSG_QUEUE
00484 if(pMsgQArray[task] != NULL)
00485 return false;
00486
00487 pMsgQArray[task] = new thrMsgQueue<ic_msg>(nmsgs);
00488 return true;
00489 #elif defined(IPCQLIB)
00490 static ipcQClass *c;
00491 if (ipcQClass::daqTasks[task] != NULL)
00492 {
00493 LOG(NOTE, "Task %d already used",task,0,0,0,0);
00494 return false;
00495 }
00496 c = new ipcQClass(task,1,mynode);
00497
00498 LOG(NOTE, "Task %d created",task,0,0,0,0);
00499
00500 return true;
00501 #elif defined(SYSVQLIB)
00502 if(msgQCreate(task, nmsgs, size) == 0) return true;
00503 return false;
00504 #else
00505
00506
00507 pMsgQArray[task] = msgQCreate(nmsgs, size, MSG_Q_PRIORITY);
00508
00509
00510 if(pMsgQArray[task] == NULL) {
00511 LOG(CRIT, "Can't create message queue %d (%s)",task, strerror(errno),0,0,0);
00512 return false;
00513 }
00514
00515 LOG(DBG, "(pMsgQArray = 0x%x) msq %d = 0x%x",pMsgQArray,task,pMsgQArray[task],0,0);
00516 return true;
00517 #endif
00518 }
00519
00520 inline void pMsgQDelete(int task)
00521 {
00522 #ifdef vxworks
00523 msgQDelete(pMsgQArray[task]);
00524 pMsgQArray[task] = NULL;
00525 #endif
00526 }
00527
00528
00529
00530 inline int pMsgQSend(int task, void *msg, int size, int node=0)
00531 {
00532 #ifdef THREAD_MSG_QUEUE
00533 int n=pMsgQArray[task]->free();
00534 if(n < 10) {
00535 LOG(WARN, "The queue %d is nearly full %d free",task,n,0,0,0);
00536 }
00537 if(n==0) {
00538 LOG(CRIT, "The queue %d is full, dropping message",task,0,0,0,0);
00539 return -1;
00540 }
00541 return pMsgQArray[task]->send((ic_msg *)msg);
00542 #elif defined(IPCQLIB)
00543
00544 ipcQClass *c;
00545
00546
00547
00548
00549 c = ipcQClass::find(node, task, 1);
00550
00551
00552
00553 if(!c) {
00554 LOG("ERR", "Queue %d/0x%x does not exist",task,node,0,0,0);
00555 return -1;
00556 }
00557
00558 if(c->send((void *)msg, size, 0) == size) return 0;
00559
00560 else return -1;
00561
00562 #elif defined(SYSVQLIB)
00563 return msgQSend(task, (char *)msg, size);
00564 #else
00565 if(msgQSend(pMsgQArray[task], (char *)msg, size, NO_WAIT, MSG_PRI_NORMAL) == OK) return 0;
00566 else return -1;
00567 #endif
00568 }
00569
00570 inline int pMsgQReceive(int task, void *msg, int size, int node=0)
00571 {
00572 #ifdef THREAD_MSG_QUEUE
00573 if(pMsgQArray[task]->receive((ic_msg *)msg))
00574 {
00575 return 0;
00576 }
00577 else
00578 return sizeof(ic_msg);
00579
00580 #elif defined(IPCQLIB)
00581 ipcQClass *c;
00582
00583
00584
00585
00586
00587 c = ipcQClass::find(node, task, 1);
00588
00589 if(!c) {
00590 LOG("ERR", "Queue %d/0x%x does not exist",task,node,0,0,0);
00591 return -1;
00592 }
00593 return c->receive((void *)msg, size, 1);
00594
00595 #elif defined(SYSVQLIB)
00596 int ret;
00597 do {
00598 ret = msgQReceive(task, (char *)msg, size);
00599 } while((ret == -1) && (errno == EINTR));
00600
00601 return ret;
00602 #else
00603 return msgQReceive(pMsgQArray[task], (char *)msg, size, WAIT_FOREVER);
00604 #endif
00605 }
00606
00607 inline void pMemcpy(void *x, void *y, int bytes)
00608 {
00609
00610
00611
00612 memcpy(x,y,bytes);
00613
00614 }
00615
00616 #endif