RTAI/addons/cpp/rtai_pqueue_wrapper.h
Alec Ari dc658435df Initial checkout (vulcano)
Signed-off-by: Alec Ari <neotheuser@ymail.com>
2014-08-17 10:08:41 -05:00

272 lines
9 KiB
C

#ifndef _RTAI_PQUEUE_WRAPPER_H
#define _RTAI_PQUEUE_WRAPPER_H
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (©) 1999 Zentropic Computing, All rights reserved
//
// Authors: Trevor Woolven (trevw@zentropix.com)
// Original date: Thu 15 Jul 1999
// Id: @(#)$Id: rtai_pqueue_wrapper.h,v 1.4 2013/10/22 14:54:14 ando Exp $
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// pqueues interface for Real Time Linux.
//
///////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
#include "linux_wrapper.h"
#include "rtai.h"
#include "rtai_pthread_wrapper.h"
#include "zdefs.h"
// ----------------------------------------------------------------------------
#define TASK_FPU_DISABLE 0
#define TASK_FPU_ENABLE 1
//Posix definitions
#define MQ_OPEN_MAX 8 //Maximum number of message queues per process
#define MQ_PRIO_MAX 32 //Maximum number of message priorities
#define MQ_BLOCK 0 //Flag to set queue into blocking mode
#define MQ_NONBLOCK 1 //Flag to set queue into non-blocking mode
#define MQ_NAME_MAX 80 //Maximum length of a queue name string
#define MQ_MIN_MSG_PRIORITY 0 //Lowest priority message
#define MQ_MAX_MSG_PRIORITY MQ_PRIO_MAX //Highest priority message
//Definitions to support higher-level applications
typedef enum {FIFO_BASED, PRIORITY_BASED} QUEUEING_POLICY;
typedef enum {POSIX, VxWORKS} QUEUE_TYPE;
// ----------------------------------------------------------------------------
//Posix Queue Attributes
struct mq_attr {
long mq_maxmsg; //Maximum number of messages in queue
long mq_msgsize; //Maximum size of a message (in bytes)
long mq_flags; //Blocking/Non-blocking behaviour specifier
// not used in mq_open only relevant for
// mq_getattrs and mq_setattrs
long mq_curmsgs; //Number of messages currently in queue
};
typedef struct mq_attr MQ_ATTR;
typedef union sigval {
int sival_int;
void *sival_ptr;
} sigval_t;
/*
* sigevent definitions
*
* It seems likely that SIGEV_THREAD will have to be handled from
* userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
* thread manager then catches and does the appropriate nonsense.
* However, everything is written out here so as to not get lost.
*/
#define SIGEV_SIGNAL 0 /* notify via signal */
#define SIGEV_NONE 1 /* other notification: meaningless */
#define SIGEV_THREAD 2 /* deliver via thread creation */
#define SIGEV_MAX_SIZE 64
#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3)
typedef struct sigevent {
sigval_t sigev_value;
int sigev_signo;
int sigev_notify;
union {
int _pad[SIGEV_PAD_SIZE];
struct {
void (*_function)(sigval_t);
void *_attribute; /* really pthread_attr_t */
} _sigev_thread;
} _sigev_un;
} sigevent_t;
//Notification data
struct notify {
RT_TASK *task;
struct sigevent data;
};
// ----------------------------------------------------------------------------
//Generic Message format
//TODO: Consider moving this definition into rtai_utils.h
struct msg_hdr {
BOOL in_use;
size_t size; //Actual message size
uint priority; //Usage priority (message/task)
void *next; //Pointer to next message on queue
};
typedef struct msg_hdr MSG_HDR;
//Generic queue header
struct queue_control {
void *base; //Pointer to the base of the queue in memory
void *head; //Pointer to the element at the front of the queue
void *tail; //Pointer to the element at the back of the queue
MQ_ATTR attrs; //Queue attributes
};
typedef struct queue_control Q_CTRL;
//Data messages
struct msg {
MSG_HDR hdr;
char data; //Anchor point for message data
};
typedef struct msg MSG;
// ----------------------------------------------------------------------------
//Posix Queue Descriptors
struct _pqueue_descr_struct {
RT_TASK *owner; //Task that created the queue
int open_count; //Count of the number of tasks that have
// 'opened' the queue for access
char q_name[MQ_NAME_MAX]; //Name supplied for queue
uint q_id; //Queue Id (index into static list of queues)
BOOL marked_for_deletion; //Queue can be deleted once all tasks have
// closed it
Q_CTRL data; //Data queue (real messages)
mode_t permissions; //Permissions granted by creator (ugo, rwx)
struct notify notify; //Notification data (empty -> !empty)
pthread_cond_t emp_cond; //For blocking on empty queue
pthread_cond_t full_cond; //For blocking on full queue
pthread_mutex_t mutex; //For synchronisation of queue
};
typedef struct _pqueue_descr_struct MSG_QUEUE;
// ----------------------------------------------------------------------------
//Task-related Posix Queue data
//A task can open up to MQ_OPEN_MAX pqueues, each with 'potentially'
//different permissions (read, write, blocking/non-blocking etc)
//
struct _pqueue_access_data {
int q_id;
int oflags; //Queue access permissions & blocking spec
};
struct _pqueue_access_struct {
RT_TASK *this_task;
int n_open_pqueues;
struct _pqueue_access_data q_access[MQ_OPEN_MAX];
};
typedef struct _pqueue_access_struct *QUEUE_CTRL;
// ----------------------------------------------------------------------------
typedef unsigned long mqd_t;
#define INVALID_PQUEUE 0
typedef enum {FOR_READ, FOR_WRITE} Q_ACCESS;
///////////////////////////////////////////////////////////////////////////////
// ACCESS FUNCTIONS
///////////////////////////////////////////////////////////////////////////////
QUEUEING_POLICY get_task_queueing_policy(void);
QUEUEING_POLICY set_task_queuing_policy(QUEUEING_POLICY policy);
QUEUE_TYPE get_queue_type(void);
QUEUE_TYPE set_queue_type(QUEUE_TYPE type);
///////////////////////////////////////////////////////////////////////////////
// POSIX MESSAGE QUEUES API
//
// Note that error returns represent the appropriate macro found in errno.h
// eg: -EINVAL, -EBADF etc
//
///////////////////////////////////////////////////////////////////////////////
//--------------------------------< mq_open >----------------------------------
// Create and/or open a message queue
//
// Return codes: >= 0 valid Posix Queue Id
// < 0 error
//
extern mqd_t mq_open(char *mq_name, int oflags, mode_t permissions,
struct mq_attr *mq_attr);
//------------------------------< mq_receive >---------------------------------
// Receive a message from a message queue
//
// Return codes: >= 0 number of bytes received
// < 0 error
//
extern size_t mq_receive(mqd_t mq, char *msg_buffer,
size_t buflen, unsigned int *msgprio);
//--------------------------------< mq_send >----------------------------------
// Send a message to a queue
//
// Return codes: >= 0 number of bytes sent
// < 0 error
extern int mq_send(mqd_t mq, const char *msg, size_t msglen,
unsigned int msgprio);
//--------------------------------< mq_close >---------------------------------
// Close a message queue (note that the queue remains in existance!)
//
// Return codes: = 0 pQueue closed OK
// < 0 error
//
extern int mq_close(mqd_t mq);
//-------------------------------< mq_getattr >--------------------------------
// Get the attributes of a message queue
//
// Return codes: = 0 attributes copied successfully
// < 0 error
//
extern int mq_getattr(mqd_t mq, struct mq_attr *attrbuf);
//-------------------------------< mq_setattr >--------------------------------
// Set a subset of a message queue's attributes
//
// Return codes: = 0 attributes set successfully
// < 0 error
//
extern int mq_setattr(mqd_t mq, const struct mq_attr *new_attrs,
struct mq_attr *old_attrs);
//-------------------------------< mq_notify >---------------------------------
// Register a request to be notified whenever a message arrives on an empty
// queue
// Note that setting the 'notification' parameter to NULL cancels the task's
// earlier notification request
//
// Return codes: = 0 notification set/cleared successfully
// < 0 error
//
extern int mq_notify(mqd_t mq, const struct sigevent *notification);
//-------------------------------< mq_unlink >---------------------------------
// Destroy a message queue
//
// Returns: = 0 queue was successfully unlinked
// < 0 error
// > 0 'n' tasks still have the queue 'open'
//
extern int mq_unlink(char *mq_name);
// ---------------------------------< eof >------------------------------------
#ifdef __cplusplus
}
#endif
#endif // _RTAI_PQUEUE_WRAPPER_H_