StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
platform.h
1 // Platform independent calls for
2 //
3 // semephores
4 // mutex's
5 // msgQueues
6 // thread creation
7 //
8 #ifndef _PLATFORM_H_
9 #define _PLATFORM_H_
10 
11 #ifndef unix
12 #ifdef __unix__
13 #define unix
14 #endif
15 #endif
16 
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <rtsLog.h>
21 #include <iccp.h>
22 
23 #ifdef __CINT__
24 #define unix
25 #endif
26 
27 
28 #ifdef sun
29 //#include <thread.h>
30 #include <synch.h>
31 #elif defined unix
32 //#include <pthread.h>
33 #include <semaphore.h>
34 #endif
35 
36 #ifdef unix
37 #include <pthread.h>
38 #include <sys/mman.h>
39 #include <SUNRT/msgQLib.h>
40 #include <SUNRT/ipcQLib.hh>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <fcntl.h>
44 #include <errno.h>
45 #include <unistd.h>
46 #include <signal.h>
47 #include <UNIX/ThreadsMsgQueue.hh>
48 #include <sched.h>
49 #else // VXWORKS
50 #include <vxWorks.h>
51 #include <msgQLib.h>
52 #include <taskLib.h>
53 #endif
54 
55 // just in case...
56 typedef unsigned int UINT32;
57 typedef unsigned short UINT16;
58 typedef unsigned char UINT8;
59 
60 #ifdef vxworks
61 extern "C" {
62 void *memcpy32(UINT32 *dst, UINT32 *src, int cou);
63 } ;
64 #endif
65 
66 //
67 // main() function
68 //
69 // use for platform independent entry points
70 // grabArgs() populates argc, argv
71 //
72 #ifdef vxworks
73 #define pMain(a) a(char *args)
74 #define pGrabArgs() int argc=1; \
75 char *argv[20]; \
76 char *__next_ = strtok(args," "); \
77 argv[0] = "unknown"; \
78 while (__next_) { \
79  argv[argc++] = __next_; \
80  __next_ = strtok(NULL, " "); \
81 }
82 #else
83 #define pMain(a) main(int argc, char *argv[])
84 #define pGrabArgs()
85 #endif
86 
87 inline void pSleep(int secs)
88 {
89 #ifdef vxworks
90  taskDelay(secs*100);
91 #else
92  sleep(secs);
93 #endif
94 }
95 
96 // 1/100 second delay....
97 inline void pTaskDelay(int ticks)
98 {
99 #ifdef vxworks
100  taskDelay(ticks);
101 #else
102  usleep(ticks * 10000);
103 #endif
104 }
105 
106 //
107 // Task creation
108 //
109 //#ifdef sun
110 //typedef thread_t pTASKID;
111 //#elif unix
112 #ifdef unix
113 typedef pthread_t pTASKID;
114 #else
115 typedef int pTASKID;
116 #endif
117 
118 inline pTASKID pTaskSelf()
119 {
120 #ifdef unix
121  return pthread_self();
122 #else
123  return taskIdSelf();
124 #endif
125 }
126 
127 inline pTASKID pTaskSpawn(char *name, int priority, void *f(void *), void *args)
128 {
129  pTASKID tid;
130 
131 #ifdef unix
132  pthread_attr_t attr;
133  pthread_attr_init(&attr);
134 
135 // struct sched_param sched;
136 // sched.sched_priority = priority;
137 // if(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) ||
138 // pthread_attr_setschedpolicy(&attr, SCHED_FIFO) ||
139 // pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) ||
140 // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) ||
141 // pthread_attr_setschedparam(&attr, &sched))
142 // {
143 // #ifndef sun
144 // LOG(NOTE, "Can't setup custom attributes for task %s, not setting priority",name,0,0,0,0);
145 // #endif
146 // pthread_attr_init(&attr);
147 // }
148 
149  //#ifdef sun
150  // if(thr_create(NULL, NULL, f, args, 0,&tid))
151  //#else
152  if(pthread_create(&tid, &attr, f, args))
153  //#endif
154  {
155  LOG(NOTE, "Can't setup custom attributes for task %s, not setting priority",name,0,0,0,0);
156  if(pthread_create(&tid, NULL, f, args)) {
157  LOG(CRIT, "Error creating %s thread: (%s)", name, strerror(errno));
158  sleep(10);
159  exit(0);
160  }
161  }
162 #else
163  tid = taskSpawn(name,priority,0,4096,(FUNCPTR)f,(int)args,0,0,0,0,0,0,0,0,0);
164 #endif
165 
166  return tid;
167 }
168 
169 inline int pChangePriority(int prio)
170 {
171 #ifdef sun
172  return -1;
173 #elif defined linux
174 // pTASKID tid = pthread_self();
175 // struct sched_param sched;
176 // int policy;
177 // pthread_getschedparam(tid,&policy,&sched);
178 // int old = sched.sched_priority;
179 // sched.sched_priority = prio;
180 // int ret = pthread_setschedparam(tid,SCHED_FIFO,&sched);
181 // if(ret == 0)
182 // return old;
183 // else
184 // return -1;
185  return -1;
186 #else
187  pTASKID tid = taskIdSelf();
188  int old=0;
189  taskPriorityGet(tid, &old);
190  taskPrioritySet(tid, prio);
191  return old;
192 #endif
193 }
194 
195 inline int pGetMaxPriority()
196 {
197 #ifdef unix
198  return sched_get_priority_max(SCHED_FIFO);
199 #else
200  return 255;
201 #endif
202 }
203 
204 inline void pLockAllMemory()
205 {
206 #ifdef vxworks
207  return;
208 #else
209  if(mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
210  {
211  LOG(DBG, "Error locking all memory",0,0,0,0,0);
212  }
213 #endif
214 }
215 
216 inline void pTaskDelete(pTASKID tid)
217 {
218 #ifdef sun
219  LOG(WARN, "thread cancelation not supported in solaris");
220 #elif defined unix
221  pthread_cancel(tid);
222 #else
223  taskDelete(tid);
224 #endif
225 }
226 
227 // Semaphores / mutexes
228 // solaris : solaris posix-like semaphores
229 // linux : posix
230 // vxworks : vxworks semaphores
231 //
232 
233 
234 
235 #ifdef sun
236 typedef sema_t* SEM_ID;
237 typedef mutex_t* MUX_ID;
238 #elif defined unix
239 typedef sem_t* SEM_ID;
240 typedef pthread_mutex_t* MUX_ID;
241 #endif
242 
243 #ifdef vxworks
244 typedef SEM_ID MUX_ID;
245 #endif
246 
247 
248 #ifdef sun
249 #define pSEM_PROTO(semName) sema_t rp_##semName; SEM_ID semName = &rp_##semName
250 #define pMUX_PROTO(muxName) mutex_t rp_##muxName; MUX_ID muxName = &rp_##muxName
251 #elif defined unix
252 #define pSEM_PROTO(semName) sem_t rp_##semName; SEM_ID semName = &rp_##semName
253 #define pMUX_PROTO(muxName) pthread_mutex_t rp_##muxName; MUX_ID muxName = &rp_##muxName
254 #else
255 #define pSEM_PROTO(semName) SEM_ID semName
256 #define pMUX_PROTO(muxName) pSEM_PROTO(muxName)
257 #endif
258 
259 
260 
261 inline void pSemCInit(SEM_ID &sem, int value)
262 {
263 #ifdef unix
264  int ret;
265 #ifdef sun
266  ret = sema_init(sem, value, USYNC_THREAD, NULL);
267 #else // linux
268  ret = sem_init(sem,0,value);
269 #endif
270 
271  if(ret != 0)
272  {
273  LOG(CRIT, "Error creating semaphore (%s)",strerror(errno));
274  }
275 
276 #else // vxworks
277  sem = semCCreate(SEM_Q_PRIORITY, value);
278  //sem = semCCreate(SEM_Q_FIFO, value);
279 #endif
280 }
281 
282 inline void pSemBInit(SEM_ID &sem, int value)
283 {
284 #ifdef unix
285  pSemCInit(sem, value);
286 #else
287  sem = semBCreate(SEM_Q_PRIORITY, (value == 0) ? SEM_EMPTY : SEM_FULL );
288  //sem = semBCreate(SEM_Q_FIFO, (value == 0) ? SEM_EMPTY : SEM_FULL );
289 #endif
290 }
291 
292 
293 inline void pMuxInit(MUX_ID &mux)
294 {
295 #ifdef sun
296  mutex_init(mux, USYNC_THREAD, NULL);
297 #elif defined unix // linux
298  pthread_mutex_init(mux, NULL);
299 #else // vxworks
300  mux = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
301  //mux = semBCreate(SEM_Q_FIFO, SEM_FULL);
302 #endif
303 }
304 
305 // Returns true if successfull
306 inline bool pSemTryTake(SEM_ID sem)
307 {
308  int ret;
309 #ifdef unix
310 #ifdef sun
311  ret = sema_trywait(sem);
312 #else
313  ret = sem_trywait(sem);
314 #endif
315  if(ret == -1) return false;
316  else return true;
317 #else // vxworks
318  ret = semTake(sem, 0);
319  if(ret == ERROR) return false;
320  else return true;
321 #endif
322 }
323 
324 inline bool pSemTake(SEM_ID sem)
325 {
326  int ret=true;
327 #ifdef unix
328  int iret;
329 
330  do {
331 #ifdef sun
332  iret = sema_wait(sem);
333 #else
334  iret = sem_wait(sem);
335 #endif
336  if((iret) && (errno != EINTR)) {
337  LOG(CRIT, "semTake error %s",strerror(errno));
338  }
339  } while (iret);
340 
341 #else // vxworks
342  ret = semTake(sem, 100);
343  if(ret == ERROR)
344  ret = false;
345  else
346  ret = true;
347 #endif
348 
349  return ret;
350 }
351 
352 inline void pSemGive(SEM_ID sem)
353 {
354 #ifdef sun
355  sema_post(sem);
356 #elif defined unix
357  sem_post(sem);
358 #else // vxworks
359  semGive(sem);
360 #endif
361 }
362 
363 inline void pMuxLock(MUX_ID mux)
364 {
365 #ifdef sun
366  mutex_lock(mux);
367 #elif defined unix
368  pthread_mutex_lock(mux);
369 #else
370  semTake(mux,WAIT_FOREVER);
371 #endif
372 }
373 
374 // This is only implemented on linux...
375 // other platforms block...
376 #if defined(__linux__) || defined(__APPLE__)
377 
378 inline bool pMuxTryLock(MUX_ID mux)
379 {
380 #ifdef sun
381  mutex_lock(mux);
382  return true;
383 #elif defined unix
384  int ret = pthread_mutex_trylock(mux);
385  if(ret == 0) return true;
386  return false;
387 #else
388  semTake(mux,WAIT_FOREVER);
389  return true ;
390 #endif
391 }
392 #endif
393 
394 inline void pMuxUnlock(MUX_ID mux)
395 {
396 #ifdef sun
397  mutex_unlock(mux);
398  // usleep(1); // thr_yield();
399 #elif defined unix
400  pthread_mutex_unlock(mux);
401 #else
402  semGive(mux);
403 #endif
404 }
405 
406 
407 //
408 // message queues
409 //
410 // THREAD_MSG_QUEUE
411 // IPCQLIB
412 // SYSVQLIB
413 // vxworks
414 //
415 // vxworks and thread_msg_queues require an array..
416 // ipcqlib requires nothing (The first Queue creating defines the static variables)
417 //
418 
419 // Make sure IPCQLIB, THREAD_MSG_QUEUE, SYSVQLIB, or vxworks is defined...
420 #if !defined(IPCQLIB) && !defined(THREAD_MSG_QUEUE) && !defined(SYSVQLIB)
421 #ifdef sun
422 #define IPCQLIB
423 #endif
424 
425 #if defined(__linux__) || defined(__APPLE__)
426 #define THREAD_MSG_QUEUE
427 #endif
428 #endif
429 
430 #ifdef vxworks
431 #undef IPCQLIB
432 #undef THREAD_MSG_QUEUE
433 #undef SYSVQLIB
434 #endif
435 
436 #ifdef vxworks
437 #define QUELIB_STRING "vxworks"
438 #elif defined(IPCQLIB)
439 #define QUELIB_STRING "ipcqlib"
440 #elif defined(THREAD_MSG_QUEUE)
441 #define QUELIB_STRING "thrMsgQ"
442 #elif defined(SYSVQLIB)
443 #define QUELIB_STRING "sysvqlib"
444 #else
445 #define QUELIB_STRING "noQs"
446 #endif
447 
448 #ifdef THREAD_MSG_QUEUE
449 extern thrMsgQueue<ic_msg> **pMsgQArray;
450 #define pALLOC_MSGQARRAY(name) thrMsgQueue<ic_msg> *name[256]
451 #define pMSGQARRAY_PROTO(name) thrMsgQueue<ic_msg> *name[]
452 inline void pSetupMsgQArray(thrMsgQueue<ic_msg> *qarray[]) {
453  pMsgQArray = qarray;
454 }
455 #elif defined(IPCQLIB)
456 #define pALLOC_MSGQARRAY(name) void *name
457 #define pMSGQARRAY_PROTO(name) void *name
458 inline void pSetupMsgQArray(void *) {};
459 #elif defined(SYSVQLIB)
460 #define pALLOC_MSGQARRAY(name) void *name
461 #define pMSGQARRAY_PROTO(name) void *name
462 inline void pSetupMsgQArray(void *) {};
463 #else
464 extern MSG_Q_ID *pMsgQArray;
465 #define pALLOC_MSGQARRAY(name) MSG_Q_ID name[256]
466 #define pMSGQARRAY_PROTO(name) MSG_Q_ID *name
467 inline void pSetupMsgQArray(MSG_Q_ID *qarray) {
468  pMsgQArray = qarray;
469 
470  LOG(DBG, "pMsgQArray = 0x%x",pMsgQArray,0,0,0,0);
471 }
472 #endif
473 
474 inline bool pMsgQValid(int node, int task)
475 {
476 #ifdef THREAD_MSG_QUEUE
477  if(pMsgQArray[task] == NULL) return false;
478  else return true;
479 #elif defined(IPCQLIB)
480  ipcQClass *c = ipcQClass::find(node, task, 1);
481 
482  if(c) return true;
483  return false;
484 #elif defined(SYSVQLIB)
485  if(msgQTest(task)) return true;
486  else return false;
487 #else
488  if(pMsgQArray[task] == NULL) return false;
489  else return true;
490 #endif
491 }
492 
493 inline bool pMsgQCreate(int task, int size, int nmsgs, int mynode=0)
494 {
495 #ifdef THREAD_MSG_QUEUE
496  if(pMsgQArray[task] != NULL)
497  return false;
498 
499  pMsgQArray[task] = new thrMsgQueue<ic_msg>(nmsgs);
500  return true;
501 #elif defined(IPCQLIB)
502  static ipcQClass *c;
503  if (ipcQClass::daqTasks[task] != NULL)
504  {
505  LOG(NOTE, "Task %d already used",task,0,0,0,0);
506  return false;
507  }
508  c = new ipcQClass(task,1,mynode); // let the static take care of saving it!!!
509 
510  LOG(NOTE, "Task %d created",task,0,0,0,0);
511 
512  return true;
513 #elif defined(SYSVQLIB)
514  if(msgQCreate(task, nmsgs, size) == 0) return true;
515  return false;
516 #else
517  //if(pMsgQArray[task] != NULL) return false;
518 
519  pMsgQArray[task] = msgQCreate(nmsgs, size, MSG_Q_PRIORITY);
520  //pMsgQArray[task] = msgQCreate(nmsgs, size, MSG_Q_FIFO);
521 
522  if(pMsgQArray[task] == NULL) {
523  LOG(CRIT, "Can't create message queue %d (%s)",task, strerror(errno),0,0,0);
524  return false;
525  }
526 
527  LOG(DBG, "(pMsgQArray = 0x%x) msq %d = 0x%x",pMsgQArray,task,pMsgQArray[task],0,0);
528  return true;
529 #endif
530 }
531 
532 inline void pMsgQDelete(int task)
533 {
534 #ifdef vxworks
535  msgQDelete(pMsgQArray[task]);
536  pMsgQArray[task] = NULL;
537 #endif
538 }
539 
540 // Returns 0 if good
541 // Returns -1 if bad
542 inline int pMsgQSend(int task, void *msg, int size, int node=0)
543 {
544 #ifdef THREAD_MSG_QUEUE
545  int n=pMsgQArray[task]->free();
546  if(n < 10) {
547  LOG(WARN, "The queue %d is nearly full %d free",task,n,0,0,0);
548  }
549  if(n==0) {
550  LOG(CRIT, "The queue %d is full, dropping message",task,0,0,0,0);
551  return -1;
552  }
553  return pMsgQArray[task]->send((ic_msg *)msg);
554 #elif defined(IPCQLIB)
555 
556  ipcQClass *c;
557 
558  //if(node == 0)
559  // c = ipcQClass::daqTasks[task];
560  // else
561  c = ipcQClass::find(node, task, 1);
562 
563 
564 
565  if(!c) {
566  LOG("ERR", "Queue %d/0x%x does not exist",task,node,0,0,0);
567  return -1;
568  }
569 
570  if(c->send((void *)msg, size, 0) == size) return 0;
571 
572  else return -1;
573 
574 #elif defined(SYSVQLIB)
575  return msgQSend(task, (char *)msg, size);
576 #else
577  if(msgQSend(pMsgQArray[task], (char *)msg, size, NO_WAIT, MSG_PRI_NORMAL) == OK) return 0;
578  else return -1;
579 #endif
580 }
581 
582 inline int pMsgQReceive(int task, void *msg, int size, int node=0)
583 {
584 #ifdef THREAD_MSG_QUEUE
585  if(pMsgQArray[task]->receive((ic_msg *)msg))
586  {
587  return 0;
588  }
589  else
590  return sizeof(ic_msg);
591 
592 #elif defined(IPCQLIB)
593  ipcQClass *c;
594 
595  // if(node == 0)
596  // c = ipcQClass::daqTasks[task];
597  //else
598 
599  c = ipcQClass::find(node, task, 1);
600 
601  if(!c) {
602  LOG("ERR", "Queue %d/0x%x does not exist",task,node,0,0,0);
603  return -1;
604  }
605  return c->receive((void *)msg, size, 1);
606 
607 #elif defined(SYSVQLIB)
608  int ret;
609  do {
610  ret = msgQReceive(task, (char *)msg, size);
611  } while((ret == -1) && (errno == EINTR));
612 
613  return ret;
614 #else
615  return msgQReceive(pMsgQArray[task], (char *)msg, size, WAIT_FOREVER);
616 #endif
617 }
618 
619 inline void pMemcpy(void *x, void *y, int bytes)
620 {
621 // #ifdef vxworks
622 // memcpy32((UINT32 *)x,(UINT32 *)y,bytes);
623 // #else
624  memcpy(x,y,bytes);
625  //#endif
626 }
627 
628 #endif
Definition: iccp.h:685