Commit 5171e8a4 authored by Claes's avatar Claes Committed by Esteban Blanc

qcom, qcom_StealQ() added, bugfix for DeleteQ and doc changes

parent 88e1a83e
...@@ -76,7 +76,7 @@ static qdb_sBuffer* inPool(pwr_tStatus* sts, void* p) ...@@ -76,7 +76,7 @@ static qdb_sBuffer* inPool(pwr_tStatus* sts, void* p)
} }
/** /**
* @brief Allocate a buffer. * @brief Allocate a buffer in the qcom pool.
*/ */
void* qcom_Alloc(pwr_tStatus* status, unsigned int size) void* qcom_Alloc(pwr_tStatus* status, unsigned int size)
{ {
...@@ -133,6 +133,31 @@ pwr_tBoolean qcom_AttachQ(pwr_tStatus* status, const qcom_sQid* qid) ...@@ -133,6 +133,31 @@ pwr_tBoolean qcom_AttachQ(pwr_tStatus* status, const qcom_sQid* qid)
return ODD(*sts); return ODD(*sts);
} }
pwr_tBoolean qcom_StealQ(pwr_tStatus *status, const qcom_sQid *qid)
{
qdb_sQue* qp;
pwr_dStatus(sts, status, QCOM__SUCCESS);
if (qdb->ap == NULL)
pwr_Return(NO, sts, QCOM__NOTINITED);
qdb_ScopeLock
{
qdb->ap->call_count++;
qdb->g->call_count++;
qp = qdb_Que(sts, qid, NULL);
if (qp == NULL)
pwr_StatusBreak(*sts, QCOM__NOQ);
qp->aid.aix = qdb->my_aix;
// TODO insert in sAppl
}
qdb_ScopeUnlock;
return ODD(*sts);
}
/** /**
* @brief Bind one queue to another. * @brief Bind one queue to another.
* *
...@@ -253,6 +278,10 @@ pwr_tBoolean qcom_CreateQ( ...@@ -253,6 +278,10 @@ pwr_tBoolean qcom_CreateQ(
return qp != NULL; return qp != NULL;
} }
/**
* @brief Delete a queue.
* Delete a queue and release all resources held by the queue.
*/
pwr_tBoolean qcom_DeleteQ(pwr_tStatus* status, const qcom_sQid* qid) pwr_tBoolean qcom_DeleteQ(pwr_tStatus* status, const qcom_sQid* qid)
{ {
qdb_sQue* qp; qdb_sQue* qp;
...@@ -270,6 +299,17 @@ pwr_tBoolean qcom_DeleteQ(pwr_tStatus* status, const qcom_sQid* qid) ...@@ -270,6 +299,17 @@ pwr_tBoolean qcom_DeleteQ(pwr_tStatus* status, const qcom_sQid* qid)
if (qp == NULL) if (qp == NULL)
pwr_StatusBreak(*sts, QCOM__NOQ); pwr_StatusBreak(*sts, QCOM__NOQ);
if (qp->flags.b.broadcast) {
qdb_sQbond* bp;
if ((bp = qdb_GetBond(sts, qp, qdb->exportque)) != NULL) {
pool_Qremove(sts, &qdb->pool, &bp->tgt_ll);
pool_Qremove(sts, &qdb->pool, &bp->src_ll);
pool_Free(sts, &qdb->pool, bp);
}
}
qdb_RemoveQue(sts, qp); qdb_RemoveQue(sts, qp);
} }
qdb_ScopeUnlock; qdb_ScopeUnlock;
...@@ -277,6 +317,13 @@ pwr_tBoolean qcom_DeleteQ(pwr_tStatus* status, const qcom_sQid* qid) ...@@ -277,6 +317,13 @@ pwr_tBoolean qcom_DeleteQ(pwr_tStatus* status, const qcom_sQid* qid)
return ODD(*sts); return ODD(*sts);
} }
/**
* @brief Disconnect from QCom.
* Disconnects an application from the Qcom message bus,
* all resources such as, queue, messages andbindings, held
* by the application will be released.
*/
pwr_tBoolean qcom_Exit(pwr_tStatus* status) pwr_tBoolean qcom_Exit(pwr_tStatus* status)
{ {
qdb_sAppl* ap = qdb->ap; qdb_sAppl* ap = qdb->ap;
...@@ -298,6 +345,9 @@ pwr_tBoolean qcom_Exit(pwr_tStatus* status) ...@@ -298,6 +345,9 @@ pwr_tBoolean qcom_Exit(pwr_tStatus* status)
return YES; return YES;
} }
/**
* @brief Free a previously allocated buffer.
*/
pwr_tBoolean qcom_Free(pwr_tStatus* status, void* p) pwr_tBoolean qcom_Free(pwr_tStatus* status, void* p)
{ {
qdb_sBuffer* bp; qdb_sBuffer* bp;
...@@ -417,6 +467,10 @@ void* qcom_Get( ...@@ -417,6 +467,10 @@ void* qcom_Get(
return dp; return dp;
} }
/**
* @brief Get the current qcom bus number.
*/
qcom_tBus qcom_MyBus(pwr_tStatus* status) qcom_tBus qcom_MyBus(pwr_tStatus* status)
{ {
qcom_tBus bus; qcom_tBus bus;
...@@ -432,6 +486,9 @@ qcom_tBus qcom_MyBus(pwr_tStatus* status) ...@@ -432,6 +486,9 @@ qcom_tBus qcom_MyBus(pwr_tStatus* status)
return bus; return bus;
} }
/**
* @brief Get the local qcom node.
*/
pwr_tBoolean qcom_MyNode(pwr_tStatus* status, qcom_sNode* node) pwr_tBoolean qcom_MyNode(pwr_tStatus* status, qcom_sNode* node)
{ {
pwr_dStatus(sts, status, QCOM__SUCCESS); pwr_dStatus(sts, status, QCOM__SUCCESS);
...@@ -448,6 +505,9 @@ pwr_tBoolean qcom_MyNode(pwr_tStatus* status, qcom_sNode* node) ...@@ -448,6 +505,9 @@ pwr_tBoolean qcom_MyNode(pwr_tStatus* status, qcom_sNode* node)
return YES; return YES;
} }
/**
* @brief Get the name of a qcom node.
*/
char* qcom_NodeName(pwr_tNodeId nid) char* qcom_NodeName(pwr_tNodeId nid)
{ {
static char name[80]; static char name[80];
...@@ -463,6 +523,9 @@ char* qcom_NodeName(pwr_tNodeId nid) ...@@ -463,6 +523,9 @@ char* qcom_NodeName(pwr_tNodeId nid)
return name; return name;
} }
/**
* @brief Get qcom node from node identity.
*/
pwr_tBoolean qcom_Node(pwr_tStatus* status, qcom_sNode* node, pwr_tNodeId nid) pwr_tBoolean qcom_Node(pwr_tStatus* status, qcom_sNode* node, pwr_tNodeId nid)
{ {
qdb_sNode* np = NULL; qdb_sNode* np = NULL;
...@@ -484,6 +547,17 @@ pwr_tBoolean qcom_Node(pwr_tStatus* status, qcom_sNode* node, pwr_tNodeId nid) ...@@ -484,6 +547,17 @@ pwr_tBoolean qcom_Node(pwr_tStatus* status, qcom_sNode* node, pwr_tNodeId nid)
return (np != NULL); return (np != NULL);
} }
/**
* @brief Get the next qcom node.
* If nid is pwr_cNNodeId the first node is returned.
*
* Example
* \code{.c}
* for (nid = qcom_cNNid; qcom_NextNode(&sts, &node, nid); nid = node.nid) {
* ...
* }
* \endcode
*/
pwr_tBoolean qcom_NextNode( pwr_tBoolean qcom_NextNode(
pwr_tStatus* status, qcom_sNode* node, pwr_tNodeId nid) pwr_tStatus* status, qcom_sNode* node, pwr_tNodeId nid)
{ {
...@@ -498,6 +572,17 @@ pwr_tBoolean qcom_NextNode( ...@@ -498,6 +572,17 @@ pwr_tBoolean qcom_NextNode(
{ {
if (nid == pwr_cNNodeId) { if (nid == pwr_cNNodeId) {
nl = pool_Qsucc(NULL, &qdb->pool, &qdb->g->node_lh); nl = pool_Qsucc(NULL, &qdb->pool, &qdb->g->node_lh);
if (nl == &qdb->g->node_lh) {
*sts = QCOM__NO_NODE;
break;
} else {
np = pool_Qitem(nl, qdb_sNode, node_ll);
if (np == NULL)
break;
qdb_NodeInfo(NULL, node, np);
break;
}
} else { } else {
np = hash_Search(sts, &qdb->nid_ht, &nid); np = hash_Search(sts, &qdb->nid_ht, &nid);
if (np == NULL) { if (np == NULL) {
...@@ -537,6 +622,20 @@ pwr_tBoolean qcom_NextNode( ...@@ -537,6 +622,20 @@ pwr_tBoolean qcom_NextNode(
return (np != NULL); return (np != NULL);
} }
/**
* @brief Connect to QCom.
*
* Before using Qcom an application must connect to Qcom.
* The application has an identity and name. The identity is generated by
* Qcom and is returned in 'aid'. If 'name' is a null pointer the
* application will be given the name 'unknown name'. Every message sent
* from an application contains the application identity and the identity
* can be read by the receiving application.
*
* Applications using GDH, MH_APPL
* or MH_OUTUNIT do not have to call qcom_Init(), it is done inside the
* gdh_Init() and mh_OutunitConnect() calls.
*/
pwr_tBoolean qcom_Init(pwr_tStatus* status, qcom_sAid* aid, const char* aname) pwr_tBoolean qcom_Init(pwr_tStatus* status, qcom_sAid* aid, const char* aname)
{ {
qdb_sAppl* ap = NULL; qdb_sAppl* ap = NULL;
...@@ -617,6 +716,30 @@ pwr_tBoolean qcom_Init(pwr_tStatus* status, qcom_sAid* aid, const char* aname) ...@@ -617,6 +716,30 @@ pwr_tBoolean qcom_Init(pwr_tStatus* status, qcom_sAid* aid, const char* aname)
return YES; return YES;
} }
/**
* @brief Put a new message.
*
* When sending a message an application can use private data, allocated
* on the stack, head, or static memory, or allocate data from the Qcom
* pool.
* \code{.c}
* char data[100];
* qcom_sPut put;
*
* // prepare data
* put.data = data;
* qcom_Put(&sts, &q, &put);
* \endcode
* Internally Qcom will allocate a buffer from the pool and copy user data
* to that buffer. Another way is to use a buffer allocated from the pool.
* \code{.c}
* put.data = qcom_Alloc(&sts, sizeof(data));
*
* // prepare data
* qcom_Put(&sts, &q, &put);
* \endcode
* Qcom checks if the buffer is allocated in the pool or not.
*/
pwr_tBoolean qcom_Put(pwr_tStatus* status, const qcom_sQid* qidp, qcom_sPut* pp) pwr_tBoolean qcom_Put(pwr_tStatus* status, const qcom_sQid* qidp, qcom_sPut* pp)
{ {
qdb_sBuffer* bp = NULL; qdb_sBuffer* bp = NULL;
...@@ -722,9 +845,9 @@ pwr_tBoolean qcom_Unbind( ...@@ -722,9 +845,9 @@ pwr_tBoolean qcom_Unbind(
/** /**
* @brief Compare two queue identities; * @brief Compare two queue identities;
* *
* return <0 if qid_1 < qid_2 * return <0 if qid_1 < qid_2 \n
* return 0 if qid_1 == qid_2 * return 0 if qid_1 == qid_2 \n
* return >0 if qid_1 < qid_2. * return >0 if qid_1 < qid_2.\n
* @return int * @return int
*/ */
...@@ -746,8 +869,8 @@ int qcom_QidCompare(const qcom_sQid* q1, const qcom_sQid* q2) ...@@ -746,8 +869,8 @@ int qcom_QidCompare(const qcom_sQid* q1, const qcom_sQid* q2)
/** /**
* @brief Test if two queue identities are equal. * @brief Test if two queue identities are equal.
* *
* return true if qid_1 == qid_2 * return true if qid_1 == qid_2 \n
* return false if qid_1 != qid_2. * return false if qid_1 != qid_2.\n
* @return pwr_tBoolean * @return pwr_tBoolean
*/ */
pwr_tBoolean qcom_QidIsEqual(const qcom_sQid* q1, const qcom_sQid* q2) pwr_tBoolean qcom_QidIsEqual(const qcom_sQid* q1, const qcom_sQid* q2)
...@@ -758,8 +881,8 @@ pwr_tBoolean qcom_QidIsEqual(const qcom_sQid* q1, const qcom_sQid* q2) ...@@ -758,8 +881,8 @@ pwr_tBoolean qcom_QidIsEqual(const qcom_sQid* q1, const qcom_sQid* q2)
/** /**
* @brief Test if two queue identities are different. * @brief Test if two queue identities are different.
* *
* return true if qid_1 != qid_2 * return true if qid_1 != qid_2 \n
* return false if qid_1 == qid_2. * return false if qid_1 == qid_2.\n
* @return pwr_tBoolean * @return pwr_tBoolean
*/ */
pwr_tBoolean qcom_QidIsNotEqual(const qcom_sQid* q1, const qcom_sQid* q2) pwr_tBoolean qcom_QidIsNotEqual(const qcom_sQid* q1, const qcom_sQid* q2)
...@@ -770,8 +893,8 @@ pwr_tBoolean qcom_QidIsNotEqual(const qcom_sQid* q1, const qcom_sQid* q2) ...@@ -770,8 +893,8 @@ pwr_tBoolean qcom_QidIsNotEqual(const qcom_sQid* q1, const qcom_sQid* q2)
/** /**
* @brief Test if queue identity is null. * @brief Test if queue identity is null.
* *
* return true if qid_1 == qcom_cNQid * return true if qid_1 == qcom_cNQid \n
* return false if qid_1 != qcom_cNQid. * return false if qid_1 != qcom_cNQid.\n
* @return pwr_tBoolean * @return pwr_tBoolean
*/ */
...@@ -783,8 +906,8 @@ pwr_tBoolean qcom_QidIsNull(const qcom_sQid* q) ...@@ -783,8 +906,8 @@ pwr_tBoolean qcom_QidIsNull(const qcom_sQid* q)
/** /**
* @brief Test if queue identity is not null. * @brief Test if queue identity is not null.
* *
* return true if qid_1 != qcom_cNQid * return true if qid_1 != qcom_cNQid \n
* return false if qid_1 == qcom_cNQid. * return false if qid_1 == qcom_cNQid.\n
* @return pwr_tBoolean * @return pwr_tBoolean
*/ */
...@@ -796,9 +919,9 @@ pwr_tBoolean qcom_QidIsNotNull(const qcom_sQid* q) ...@@ -796,9 +919,9 @@ pwr_tBoolean qcom_QidIsNotNull(const qcom_sQid* q)
/** /**
* @brief Compare two application identities; * @brief Compare two application identities;
* *
* return <0 if aid_1 < aid_2 * return <0 if aid_1 < aid_2 \n
* return 0 if aid_1 == aid_2 * return 0 if aid_1 == aid_2 \n
* return >0 if aid_1 > aid_2. * return >0 if aid_1 > aid_2.\n
* @return int * @return int
*/ */
...@@ -820,8 +943,8 @@ int qcom_AidCompare(const qcom_sAid* a1, const qcom_sAid* a2) ...@@ -820,8 +943,8 @@ int qcom_AidCompare(const qcom_sAid* a1, const qcom_sAid* a2)
/** /**
*@brief Test if two application identities are equal. *@brief Test if two application identities are equal.
* *
* return true if aid_1 == aid_2 * return true if aid_1 == aid_2 \n
* return false if aid_1 != aid_2. * return false if aid_1 != aid_2.\n
* @return pwr_tBoolean * @return pwr_tBoolean
*/ */
...@@ -833,8 +956,8 @@ pwr_tBoolean qcom_AidIsEqual(const qcom_sAid* a1, const qcom_sAid* a2) ...@@ -833,8 +956,8 @@ pwr_tBoolean qcom_AidIsEqual(const qcom_sAid* a1, const qcom_sAid* a2)
/** /**
* @brief Test if two application identities are different. * @brief Test if two application identities are different.
* *
* return true if aid_1 != aid_2 * return true if aid_1 != aid_2 \n
* return false if aid_1 == aid_2. * return false if aid_1 == aid_2.\n
* @return pwr_tBoolean * @return pwr_tBoolean
*/ */
...@@ -846,8 +969,8 @@ pwr_tBoolean qcom_AidIsNotEqual(const qcom_sAid* a1, const qcom_sAid* a2) ...@@ -846,8 +969,8 @@ pwr_tBoolean qcom_AidIsNotEqual(const qcom_sAid* a1, const qcom_sAid* a2)
/** /**
* @brief Test if application identity is null. * @brief Test if application identity is null.
* *
* return true if aid == qcom_cNAid * return true if aid == qcom_cNAid \n
* return false if aid != qcom_cNAid. * return false if aid != qcom_cNAid.\n
* @return pwr_tBoolean * @return pwr_tBoolean
*/ */
...@@ -859,8 +982,8 @@ pwr_tBoolean qcom_AidIsNull(const qcom_sAid* a) ...@@ -859,8 +982,8 @@ pwr_tBoolean qcom_AidIsNull(const qcom_sAid* a)
/** /**
* @brief Test if application identity is not null. * @brief Test if application identity is not null.
* *
* return true if aid != qcom_cNAid * return true if aid != qcom_cNAid \n
* return false if aid == qcom_cNAid. * return false if aid == qcom_cNAid.\n
* @return pwr_tBoolean * @return pwr_tBoolean
*/ */
pwr_tBoolean qcom_AidIsNotNull(const qcom_sAid* a) pwr_tBoolean qcom_AidIsNotNull(const qcom_sAid* a)
...@@ -882,6 +1005,16 @@ pwr_tBoolean qcom_AidIsNotNull(const qcom_sAid* a) ...@@ -882,6 +1005,16 @@ pwr_tBoolean qcom_AidIsNotNull(const qcom_sAid* a)
); );
*/ */
/**
* @brief Put a request and return the reply.
*
* The qcom_Request() call combines qcom_Put() and qcom_Get() in one call,
* and the application is guaranteed that at the return from qcom_Request()
* it either has the correct reply on the request or a time out. Internal
* to the qcom_Request() call, Qcom filters away any stray responses.
*
* The request should be answered with a qcom_Reply().
*/
void* qcom_Request(pwr_tStatus* status, const qcom_sQid* pqid, qcom_sPut* pp, void* qcom_Request(pwr_tStatus* status, const qcom_sQid* pqid, qcom_sPut* pp,
const qcom_sQid* gqid, qcom_sGet* gp, int tmo, pwr_tBitMask flags) const qcom_sQid* gqid, qcom_sGet* gp, int tmo, pwr_tBitMask flags)
{ {
...@@ -984,6 +1117,13 @@ void* qcom_Request(pwr_tStatus* status, const qcom_sQid* pqid, qcom_sPut* pp, ...@@ -984,6 +1117,13 @@ void* qcom_Request(pwr_tStatus* status, const qcom_sQid* pqid, qcom_sPut* pp,
return dp; return dp;
} }
/**
* @brief Reply to a qcom_Request.
* The qcom_Reply() call looks almost like a qcom_Put(), but the queue id is
* replaced with a qcom_sGet. Applications must agree on using
* qcom_Request/qcom_Reply, using a qcom_Put to reply on a qcom_Request will not work.
*/
pwr_tBoolean qcom_Reply(pwr_tStatus* status, qcom_sGet* gp, qcom_sPut* pp) pwr_tBoolean qcom_Reply(pwr_tStatus* status, qcom_sGet* gp, qcom_sPut* pp)
{ {
qdb_sBuffer* bp; qdb_sBuffer* bp;
...@@ -1069,6 +1209,18 @@ char* qcom_QidToString(char* s, qcom_sQid* qid, int prefix) ...@@ -1069,6 +1209,18 @@ char* qcom_QidToString(char* s, qcom_sQid* qid, int prefix)
return ls; return ls;
} }
/**
* @brief Wait for an event or a message.
*
* Wait for an event on the message queue (eid) matching the supplied
* mask, or an message on the message queue (qid).
*
* For qcom_WaitOr at least one of the bits in the mask has to match
* the bits in the event.
*
* @return pwr_tBoolean
*/
pwr_tBoolean qcom_WaitOr(pwr_tStatus* status, const qcom_sQid* qid, pwr_tBoolean qcom_WaitOr(pwr_tStatus* status, const qcom_sQid* qid,
const qcom_sQid* eid, int mask, int tmo, int* event) const qcom_sQid* eid, int mask, int tmo, int* event)
{ {
...@@ -1105,6 +1257,18 @@ pwr_tBoolean qcom_WaitOr(pwr_tStatus* status, const qcom_sQid* qid, ...@@ -1105,6 +1257,18 @@ pwr_tBoolean qcom_WaitOr(pwr_tStatus* status, const qcom_sQid* qid,
return result != 0; return result != 0;
} }
/**
* @brief Wait for an event or a message.
*
* Wait for an event on the message queue (eid) matching the supplied
* mask, or an message on the message queue (qid).
*
* For qcom_WaitAnd all the bits in the mask have to match
* the bits in the event.
*
* @return pwr_tBoolean
*/
pwr_tBoolean qcom_WaitAnd(pwr_tStatus* status, const qcom_sQid* qid, pwr_tBoolean qcom_WaitAnd(pwr_tStatus* status, const qcom_sQid* qid,
const qcom_sQid* eid, int mask, int tmo) const qcom_sQid* eid, int mask, int tmo)
{ {
......
...@@ -113,9 +113,10 @@ typedef enum { ...@@ -113,9 +113,10 @@ typedef enum {
} qcom_eNodeConnection; } qcom_eNodeConnection;
/** /**
* @brief ZZZ Text that appers when the Data structure is listed. * @brief Queue identity
* *
* More detailed text * Every queue within a Qcom bus is uniquely identified by a queue
* identity, used for identifying the target for sending a message.
*/ */
typedef struct { typedef struct {
qcom_tQix qix; /**< Queue index */ qcom_tQix qix; /**< Queue index */
...@@ -244,6 +245,8 @@ void* qcom_Alloc(pwr_tStatus* sts, unsigned int size); ...@@ -244,6 +245,8 @@ void* qcom_Alloc(pwr_tStatus* sts, unsigned int size);
pwr_tBoolean qcom_AttachQ(pwr_tStatus* sts, const qcom_sQid* qid); pwr_tBoolean qcom_AttachQ(pwr_tStatus* sts, const qcom_sQid* qid);
pwr_tBoolean qcom_StealQ(pwr_tStatus *status, const qcom_sQid *qid);
pwr_tBoolean qcom_Bind( pwr_tBoolean qcom_Bind(
pwr_tStatus* sts, const qcom_sQid* myQ, const qcom_sQid* toQ); pwr_tStatus* sts, const qcom_sQid* myQ, const qcom_sQid* toQ);
......
...@@ -1247,7 +1247,9 @@ pwr_tBoolean qdb_RemoveQue(pwr_tStatus* status, qdb_sQue* qp) ...@@ -1247,7 +1247,9 @@ pwr_tBoolean qdb_RemoveQue(pwr_tStatus* status, qdb_sQue* qp)
pool_Free(sts, &qdb->pool, qbp); pool_Free(sts, &qdb->pool, qbp);
} }
/* Left to do !!! Unlink all queues linked eve_lh. */ for (/* unlink all event queues linked eve_lh */
qbl = pool_Qsucc(NULL, &qdb->pool, &qp->eve_lh); qbl->self != qbl->flink;)
pool_Qremove(sts, &qdb->pool, qbl);
/* unlink que from own_ll */ /* unlink que from own_ll */
pool_Qremove(sts, &qdb->pool, &qp->que_ll); pool_Qremove(sts, &qdb->pool, &qp->que_ll);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment