00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _RTAI_MQ_H
00029 #define _RTAI_MQ_H
00030
00031 #include <linux/version.h>
00032 #include <rtai_sem.h>
00033 #include <rtai_schedcore.h>
00034
00035 #define MQ_OPEN_MAX 8
00036 #ifndef MQ_PRIO_MAX
00037 #define MQ_PRIO_MAX 32
00038 #endif
00039 #define MQ_BLOCK 0
00040 #define MQ_NONBLOCK 1
00041 #define MQ_NAME_MAX 80
00042
00043 #define MQ_MIN_MSG_PRIORITY 0
00044 #define MQ_MAX_MSG_PRIORITY MQ_PRIO_MAX
00045
00046 #define MAX_PQUEUES 4
00047
00048 #define MAX_MSGSIZE 50
00049 #define MAX_MSGS 10
00050
00051 #define O_NOTIFY_NP 0x1000
00052
00053 typedef struct mq_attr {
00054 long mq_maxmsg;
00055 long mq_msgsize;
00056 long mq_flags;
00057 long mq_curmsgs;
00058 } MQ_ATTR;
00059
00060 #define INVALID_PQUEUE 0
00061
00062 #ifdef __KERNEL__
00063
00064 #include <linux/types.h>
00065
00066 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,6)
00067 typedef int mqd_t;
00068 #endif
00069
00070 #ifndef __cplusplus
00071
00072 typedef int mq_bool_t;
00073
00074 #ifndef TRUE
00075 #define TRUE 1
00076 #define FALSE 0
00077 #endif
00078
00079 typedef struct msg_hdr {
00080 size_t size;
00081 uint priority;
00082 void *next;
00083 } MSG_HDR;
00084
00085 #define MSG_HDR_SIZE (sizeof(MSG_HDR))
00086
00087 typedef struct queue_control {
00088 int nodind;
00089 void **nodes;
00090 void *base;
00091 void *head;
00092 void *tail;
00093 MQ_ATTR attrs;
00094 } Q_CTRL;
00095
00096 typedef struct msg {
00097 MSG_HDR hdr;
00098 char data;
00099 } MQMSG;
00100
00101 struct notify {
00102 RT_TASK *task;
00103 struct sigevent data;
00104 };
00105
00106 typedef struct _pqueue_descr_struct {
00107 RT_TASK *owner;
00108 int open_count;
00109
00110 char q_name[MQ_NAME_MAX];
00111 uint q_id;
00112 mq_bool_t marked_for_deletion;
00113
00114 Q_CTRL data;
00115 mode_t permissions;
00116 struct notify notify;
00117 SEM emp_cond;
00118 SEM full_cond;
00119 SEM mutex;
00120 } MSG_QUEUE;
00121
00122 struct _pqueue_access_data {
00123 int q_id;
00124 int oflags;
00125 struct sigevent *usp_notifier;
00126 };
00127
00128 typedef struct _pqueue_access_struct {
00129 RT_TASK *this_task;
00130 int n_open_pqueues;
00131 struct _pqueue_access_data q_access[MQ_OPEN_MAX];
00132 } *QUEUE_CTRL;
00133
00134 typedef enum {
00135 FOR_READ,
00136 FOR_WRITE
00137 } Q_ACCESS;
00138
00139 #else
00140 extern "C" {
00141 #endif
00142
00143 int __rtai_mq_init(void);
00144
00145 void __rtai_mq_exit(void);
00146
00147 RTAI_SYSCALL_MODE mqd_t _mq_open(char *mq_name, int oflags, mode_t permissions, struct mq_attr *mq_attr, long space);
00148 static inline mqd_t mq_open(char *mq_name, int oflags, mode_t permissions, struct mq_attr *mq_attr)
00149 {
00150 return _mq_open(mq_name, oflags, permissions, mq_attr, 0);
00151 }
00152
00153 RTAI_SYSCALL_MODE size_t _mq_receive(mqd_t mq, char *msg_buffer, size_t buflen, unsigned int *msgprio, int space);
00154 static inline size_t mq_receive(mqd_t mq, char *msg_buffer, size_t buflen, unsigned int *msgprio)
00155 {
00156 return _mq_receive(mq, msg_buffer, buflen, msgprio, 1);
00157 }
00158
00159 RTAI_SYSCALL_MODE int _mq_send(mqd_t mq, const char *msg, size_t msglen, unsigned int msgprio, int space);
00160 static inline int mq_send(mqd_t mq, const char *msg, size_t msglen, unsigned int msgprio)
00161 {
00162 return _mq_send(mq, msg, msglen, msgprio, 1);
00163 }
00164
00165 RTAI_SYSCALL_MODE int mq_close(mqd_t mq);
00166
00167 RTAI_SYSCALL_MODE int mq_getattr(mqd_t mq, struct mq_attr *attrbuf);
00168
00169 RTAI_SYSCALL_MODE int mq_setattr(mqd_t mq, const struct mq_attr *new_attrs, struct mq_attr *old_attrs);
00170
00171 RTAI_SYSCALL_MODE int _mq_notify(mqd_t mq, RT_TASK *task, long space, long rem, const struct sigevent *notification);
00172 static inline int mq_notify(mqd_t mq, const struct sigevent *notification)
00173 {
00174 return _mq_notify(mq, rt_whoami(), 0, (notification ? 0 : 1), notification );
00175 }
00176
00177 RTAI_SYSCALL_MODE int mq_unlink(char *mq_name);
00178
00179 RTAI_SYSCALL_MODE size_t _mq_timedreceive(mqd_t mq, char *msg_buffer, size_t buflen, unsigned int *msgprio, const struct timespec *abstime, int space);
00180 static inline size_t mq_timedreceive(mqd_t mq, char *msg_buffer, size_t buflen, unsigned int *msgprio, const struct timespec *abstime)
00181 {
00182 return _mq_timedreceive(mq, msg_buffer, buflen, msgprio, abstime, 1);
00183 }
00184
00185 RTAI_SYSCALL_MODE int _mq_timedsend(mqd_t mq, const char *msg, size_t msglen, unsigned int msgprio, const struct timespec *abstime, int space);
00186 static inline int mq_timedsend(mqd_t mq, const char *msg, size_t msglen, unsigned int msgprio, const struct timespec *abstime)
00187 {
00188 return _mq_timedsend(mq, msg, msglen, msgprio, abstime, 1);
00189 }
00190
00191 #ifdef __cplusplus
00192 }
00193 #endif
00194
00195 #else
00196
00197 #include <signal.h>
00198 #include <rtai_lxrt.h>
00199 #include <rtai_signal.h>
00200
00201 #define MQIDX 0
00202
00203 typedef int mqd_t;
00204
00205 #ifdef __cplusplus
00206 extern "C" {
00207 #endif
00208
00209 struct suprt_fun_arg { mqd_t mq; RT_TASK *task; unsigned long cpuid; pthread_t self; };
00210
00211 #ifndef __SIGNAL_SUPPORT_FUN_MQ__
00212 #define __SIGNAL_SUPPORT_FUN_MQ__
00213
00214 static void signal_suprt_fun_mq(struct suprt_fun_arg *fun_arg)
00215 {
00216 struct sigtsk_t { RT_TASK *sigtask; RT_TASK *task; };
00217 struct suprt_fun_arg arg = *fun_arg;
00218 struct sigreq_t { RT_TASK *sigtask; RT_TASK *task; long signal;} sigreq = {NULL, arg.task, (arg.mq + MAXSIGNALS)};
00219 struct sigevent notification;
00220
00221 if ((sigreq.sigtask = rt_thread_init(rt_get_name(0), SIGNAL_TASK_INIPRIO, 0, SCHED_FIFO, 1 << arg.cpuid))) {
00222 if (!rtai_lxrt(RTAI_SIGNALS_IDX, sizeof(struct sigreq_t), RT_SIGNAL_REQUEST, &sigreq).i[LOW]) {
00223 struct arg_reg { mqd_t mq; RT_TASK *task; struct sigevent *usp_notification;} arg_reg = {arg.mq, arg.task, ¬ification};
00224 rtai_lxrt(MQIDX, sizeof(struct arg_reg), MQ_REG_USP_NOTIFIER, &arg_reg);
00225 mlockall(MCL_CURRENT | MCL_FUTURE);
00226 rt_make_hard_real_time();
00227 while (rtai_lxrt(RTAI_SIGNALS_IDX, sizeof(struct sigtsk_t), RT_SIGNAL_WAITSIG, &sigreq).i[LOW]) {
00228 if (notification.sigev_notify == SIGEV_THREAD) {
00229 notification._sigev_un._sigev_thread._function((sigval_t)notification.sigev_value.sival_int);
00230 } else if (notification.sigev_notify == SIGEV_SIGNAL) {
00231 pthread_kill((pthread_t)arg.self, notification.sigev_signo);
00232 }
00233 }
00234 rt_make_soft_real_time();
00235 }
00236 rt_task_delete(sigreq.sigtask);
00237 }
00238 }
00239
00240 #endif
00241
00242 RTAI_PROTO(int, rt_request_signal_mq, (mqd_t mq))
00243 {
00244 struct suprt_fun_arg arg = { mq, NULL, 0, pthread_self() };
00245 arg.cpuid = rtai_lxrt(RTAI_SIGNALS_IDX, sizeof(void *), RT_SIGNAL_HELPER, (void *)&arg.task).i[LOW];
00246 arg.task = rt_buddy();
00247 if (rt_thread_create(signal_suprt_fun_mq, &arg, SIGNAL_TASK_STACK_SIZE)) {
00248 int ret;
00249 ret = rtai_lxrt(RTAI_SIGNALS_IDX, sizeof(RT_TASK *), RT_SIGNAL_HELPER, &arg.task).i[LOW];
00250 return ret;
00251 }
00252 return -1;
00253 }
00254
00255
00256 RTAI_PROTO(mqd_t, mq_open,(char *mq_name, int oflags, mode_t permissions, struct mq_attr *mq_attr))
00257 {
00258 mqd_t ret;
00259 struct {char *mq_name; long oflags; long permissions; struct mq_attr *mq_attr; long namesize, attrsize; long space; } arg = { mq_name, oflags, permissions, mq_attr, strlen(mq_name) + 1, sizeof(struct mq_attr), 1 };
00260 if ((ret = (mqd_t)rtai_lxrt(MQIDX, SIZARG, MQ_OPEN, &arg).i[LOW]) >= 0) {
00261
00262 if (oflags & O_NOTIFY_NP) {
00263 rt_request_signal_mq (ret);
00264 }
00265 }
00266 return ret;
00267 }
00268
00269 RTAI_PROTO(size_t, mq_receive,(mqd_t mq, char *msg_buffer, size_t buflen, unsigned int *msgprio))
00270 {
00271 struct { long mq; char *msg_buffer; long buflen; unsigned int *msgprio; long space; } arg = { mq, msg_buffer, buflen, msgprio, 0 };
00272 return (size_t)rtai_lxrt(MQIDX, SIZARG, MQ_RECEIVE, &arg).i[LOW];
00273 }
00274
00275 RTAI_PROTO(int, mq_send,(mqd_t mq, const char *msg, size_t msglen, unsigned int msgprio))
00276 {
00277 struct { long mq; const char *msg; long msglen; unsigned long msgprio; long space; } arg = { mq, msg, msglen, msgprio, 0 };
00278 return rtai_lxrt(MQIDX, SIZARG, MQ_SEND, &arg).i[LOW];
00279 }
00280
00281 RTAI_PROTO(int, mq_close,(mqd_t mq))
00282 {
00283 struct { long mq; } arg = { mq };
00284 return rtai_lxrt(MQIDX, SIZARG, MQ_CLOSE, &arg).i[LOW];
00285 }
00286
00287 RTAI_PROTO(int, mq_getattr,(mqd_t mq, struct mq_attr *attrbuf))
00288 {
00289 struct { long mq; struct mq_attr *attrbuf; long attrsize; } arg = { mq, attrbuf, sizeof(struct mq_attr) };
00290 return rtai_lxrt(MQIDX, SIZARG, MQ_GETATTR, &arg).i[LOW];
00291 }
00292
00293 RTAI_PROTO(int, mq_setattr,(mqd_t mq, const struct mq_attr *new_attrs, struct mq_attr *old_attrs))
00294 {
00295 struct { long mq; const struct mq_attr *new_attrs; struct mq_attr *old_attrs; long attrsize; } arg = { mq, new_attrs, old_attrs, sizeof(struct mq_attr) };
00296 return rtai_lxrt(MQIDX, SIZARG, MQ_SETATTR, &arg).i[LOW];
00297 }
00298
00299 RTAI_PROTO(int, mq_notify,(mqd_t mq, const struct sigevent *notification))
00300 {
00301 int ret;
00302 struct { long mq; RT_TASK* task; long space; long rem; const struct sigevent *notification; long size;} arg = { mq, rt_buddy(), 1, (notification ? 0 : 1), notification, sizeof(struct sigevent) };
00303 if ((ret = rtai_lxrt(MQIDX, SIZARG, MQ_NOTIFY, &arg).i[LOW]) >= 0) {
00304 if (ret == O_NOTIFY_NP) {
00305 rt_request_signal_mq (mq);
00306 ret = 0;
00307 }
00308 }
00309 return ret;
00310 }
00311
00312 RTAI_PROTO(int, mq_unlink,(char *mq_name))
00313 {
00314 struct { char *mq_name; long size; } arg = { mq_name, strlen(mq_name) + 1};
00315 return rtai_lxrt(MQIDX, SIZARG, MQ_UNLINK, &arg).i[LOW];
00316 }
00317
00318 RTAI_PROTO(size_t, mq_timedreceive,(mqd_t mq, char *msg_buffer, size_t buflen, unsigned int *msgprio, const struct timespec *abstime))
00319 {
00320 struct { long mq; char *msg_buffer; long buflen; unsigned int *msgprio; const struct timespec *abstime; long space; } arg = { mq, msg_buffer, buflen, msgprio, abstime, 0 };
00321 return (size_t)rtai_lxrt(MQIDX, SIZARG, MQ_TIMEDRECEIVE, &arg).i[LOW];
00322 }
00323
00324 RTAI_PROTO(int, mq_timedsend,(mqd_t mq, const char *msg, size_t msglen, unsigned int msgprio, const struct timespec *abstime))
00325 {
00326 struct { long mq; const char *msg; long msglen; unsigned long msgprio; const struct timespec *abstime; long space; } arg = { mq, msg, msglen, msgprio, abstime, 0 };
00327 return rtai_lxrt(MQIDX, SIZARG, MQ_TIMEDSEND, &arg).i[LOW];
00328 }
00329
00330 #ifdef __cplusplus
00331 }
00332 #endif
00333
00334 #endif
00335
00336 #endif