| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // Copyright (c) 2000-2019 Ericsson Telecom AB // |
| // // |
| // All rights reserved. This program and the accompanying materials // |
| // are made available under the terms of the Eclipse Public License v2.0 // |
| // which accompanies this distribution, and is available at // |
| // https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| /////////////////////////////////////////////////////////// |
| // Module: EPTF_CLL_PoolMgmt_Functions |
| // |
| // Purpose: |
| // This module contains macro constant and function definitions for the pool implementation. |
| // |
| // Module depends on: |
| // <EPTF_CLL_PoolMgmt_Definitions> |
| // <EPTF_CLL_QueueMgmt_Definitions> |
| // <EPTF_CLL_QueueMgmt_Functions> |
| // |
| // Current Owner: |
| // Jozsef Gyurusi (ethjgi) |
| // |
| // Last Review Date: |
| // 2007-06-20 |
| // |
| // Detailed Comments: |
| // The Makefile Generator treats this file as TTCN-3 include file. The .ttcnin file will be |
| // added to the Makefile as special TTCN-3 include file which will not be translated by the |
| // compiler, but will be checked for modification when building the test suite. |
| // |
| // Previous definition of EPTF_POOLTYPE macro (type of pool items) in a .ttcnpp file |
| // (p.e. |
| // |
| // #define EPTF_POOLTYPE *IndexTuple* |
| // |
| // ) is a precondition of using this |
| // pool implementation as a TTCN-3 include (see more info at <EPTF_POOLTYPE>)! |
| // This macro sets the <EPTF_POOLTYPE> as the user type *IndexTuple*. |
| // An appropriate TTCN-3 types module must also be provided (and imported into the .ttncpp module) |
| // by the user with some type and constant definitions considering the choosen |
| // type for <EPTF_POOLTYPE>: |
| // |
| // type record of integer *IndexTuple*; |
| // |
| // const *IndexTuple* c_emptyIndexTuple := {}; |
| // |
| /////////////////////////////////////////////////////////////// |
| |
| import from EPTF_CLL_QueueMgmt_Definitions all; |
| import from EPTF_CLL_QueueMgmt_Functions all; |
| #include "EPTF_CLL_PoolMgmt_Definitions.ttcnin" |
| |
| #ifndef EPTF_POOLTYPE |
| #error "undefined EPTF_POOLTYPE" |
| #endif |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Constant: c_EPTF_empty##EPTF_POOLTYPE##Pool |
| // |
| // Purpose: |
| // useful constant to init an empty <EPTF_POOLTYPE##Pool> at once |
| // |
| // References: |
| // <EPTF_POOLTYPE##Pool> := {order := <c_EPTF_emptyFreeBusyQueue>, poolData := <c_EPTF_empty##EPTF_POOLTYPE##List>} |
| // |
| /////////////////////////////////////////////////////////// |
| #define C_EPTF_EMPTY_POOL_(TYPEARG) \ |
| const TYPEARG##Pool c_EPTF_empty##TYPEARG##Pool := \ |
| {order := c_EPTF_emptyFreeBusyQueue, userData := c_EPTF_empty##TYPEARG##List} |
| |
| #define C_EPTF_EMPTY_POOL(TYPEARG) C_EPTF_EMPTY_POOL_(TYPEARG) |
| C_EPTF_EMPTY_POOL(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_init##EPTF_POOLTYPE##Pool |
| // |
| // Purpose: |
| // function to init an empty <EPTF_POOLTYPE##Pool> |
| // |
| // Parameters: |
| // pl_pool - *inout* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // Return Value: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_INIT_POOL_(TYPEARG) \ |
| function f_EPTF_init##TYPEARG##Pool(inout TYPEARG##Pool pl_pool) \ |
| {\ |
| f_EPTF_FBQ_initFreeBusyQueue(pl_pool.order);\ |
| pl_pool.userData := c_EPTF_empty##TYPEARG##List;\ |
| } |
| #define F_INIT_POOL(TYPEARG) F_INIT_POOL_(TYPEARG) |
| F_INIT_POOL(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_getNew##EPTF_POOLTYPE |
| // |
| // Purpose: |
| // function to get a new EPTF_POOLTYPE from the free chain. |
| // If there is no such item then it allocates on-the-fly. |
| // |
| // Parameters: |
| // pl_##EPTF_POOLTYPE##Pool - *inout* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // Return Value: |
| // integer - the index of the <EPTF_POOLTYPE> item |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // It uses the user defined c_empty##EPTF_POOLTYPE constant of type <EPTF_POOLTYPE> |
| // to initate a newly allocated value if needed (see <EPTF_CLL_PoolMgmt_Functions> for details). |
| // |
| /////////////////////////////////////////////////////////// |
| |
| #define F_GETNEWITEM_(TYPEARG) \ |
| function f_EPTF_getNew##TYPEARG(inout TYPEARG##Pool pl_pool) return integer\ |
| {\ |
| if (tsp_debugVerbose_PoolMgmt){\ |
| log("f_EPTF_getNew##EPTF_POOLTYPE has been called");\ |
| }\ |
| var integer idx := f_EPTF_FBQ_getOrCreateFreeSlot(pl_pool.order);\ |
| if (idx >= sizeof(pl_pool.userData)){\ |
| pl_pool.userData[idx]:=c_empty##TYPEARG;\ |
| if (tsp_debugVerbose_PoolMgmt) {\ |
| log("f_EPTF_getNew##EPTF_POOLTYPE needed to allocate new ##EPTF_POOLTYPE",\ |
| " at idx:",idx, ", initialized to:",pl_pool.userData[idx]);\ |
| }\ |
| }\ |
| return idx;\ |
| } |
| #define F_GETNEWITEM(TYPEARG) F_GETNEWITEM_(TYPEARG) |
| F_GETNEWITEM(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_putBack##EPTF_POOLTYPE |
| // |
| // Purpose: |
| // function to put a used <EPTF_POOLTYPE> item back to the pool, |
| // i.e., to make it available for future reuse (release this slot) |
| // |
| // Parameters: |
| // pl_##EPTF_POOLTYPE##Pool - *inout* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // pl_qidx - *in* *integer* - index of the element to be removed |
| // |
| // Return Value: |
| // boolean - false if any error has happened |
| // |
| // Errors: |
| // - If the event at index pl_qidx is not valid (i.e., |
| // <f_EPTF_##EPTF_POOLTYPE##IsBusy> (pl_##EPTF_POOLTYPE##Pool, pl_qidx) is false), |
| // then <f_EPTF_putBack##EPTF_POOLTYPE> fails |
| // |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_PUTBACKITEM_(TYPEARG) \ |
| function f_EPTF_putBack##TYPEARG(inout TYPEARG##Pool pl_pool, in integer pl_qidx)\ |
| return boolean {\ |
| if (tsp_debugVerbose_PoolMgmt) {\ |
| log("f_putBack##EPTF_POOLTYPE:", pl_qidx);\ |
| }\ |
| if (not f_EPTF_##TYPEARG##IsBusy(pl_pool, pl_qidx)){\ |
| log("Error: f_EPTF_putBack##EPTF_POOLTYPE: clearing invalid pool item at pl_qidx:",\ |
| pl_qidx);\ |
| return false;\ |
| }\ |
| f_EPTF_FBQ_moveFromBusyToFreeHead(pl_qidx,pl_pool.order);\ |
| return true;\ |
| } |
| #define F_PUTBACKITEM(TYPEARG) F_PUTBACKITEM_(TYPEARG) |
| F_PUTBACKITEM(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_getFirst##EPTF_POOLTYPE##Index |
| // |
| // Purpose: |
| // function to retrieve the index of the first busy <EPTF_POOLTYPE> |
| // from the pool |
| // |
| // Parameters: |
| // pl_##EPTF_POOLTYPE##Pool - *in* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // Return Value: |
| // *integer* - the index of the head of the pool |
| // |
| // Errors: |
| // - If the event at index pl_qidx is not valid (i.e., |
| // <f_EPTF_##EPTF_POOLTYPE##PoolIsEmpty> (pl_##EPTF_POOLTYPE##Pool) is true), |
| // then <f_EPTF_putBack##EPTF_POOLTYPE> fails and returns with -1 |
| // |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_GETFIRSTITEMINDEX_(TYPEARG) \ |
| function f_EPTF_getFirst##TYPEARG##Index(in TYPEARG##Pool pl_pool) return integer\ |
| {\ |
| if (tsp_debugVerbose_PoolMgmt) {\ |
| log("f_EPTF_getFirst##EPTF_POOLTYPE##Index has been called");\ |
| }\ |
| if (f_EPTF_##TYPEARG##PoolIsEmpty(pl_pool)){\ |
| log("Error: f_EPTF_getFirst##EPTF_POOLTYPE##Index: busy chain is empty:", pl_pool.order);\ |
| return -1;\ |
| }\ |
| var integer vl_head;\ |
| f_EPTF_FBQ_getBusyHeadIdx(vl_head,pl_pool.order);\ |
| return vl_head;\ |
| } |
| #define F_GETFIRSTITEMINDEX(TYPEARG) F_GETFIRSTITEMINDEX_(TYPEARG) |
| F_GETFIRSTITEMINDEX(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_getNext##EPTF_POOLTYPE##Index |
| // |
| // Purpose: |
| // function to advance to the next busy item, if any |
| // |
| // Parameters: |
| // pl_pool - *in* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // pl_idx - *inout integer* - the index, which will be advanced |
| // |
| // Return Value: |
| // boolean - true, if index has been advanced, false otherwise |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_GETNEXTITEMINDEX_(TYPEARG) \ |
| function f_EPTF_getNext##TYPEARG##Index(in TYPEARG##Pool pl_pool,inout integer pl_idx) return boolean\ |
| {\ |
| if (f_EPTF_##TYPEARG##IsBusy(pl_pool,pl_idx)) {\ |
| return f_EPTF_FBQ_getFwdBusyItemIdx(pl_idx,pl_pool.order);\ |
| } else { return false; }\ |
| } |
| #define F_GETNEXTITEMINDEX(TYPEARG) F_GETNEXTITEMINDEX_(TYPEARG) |
| F_GETNEXTITEMINDEX(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_##EPTF_POOLTYPE##PoolIsEmpty |
| // |
| // Purpose: |
| // function to check whether the pool is empty, or not |
| // |
| // Parameters: |
| // pl_##EPTF_POOLTYPE##Pool - *in* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // Return Value: |
| // *boolean* |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function returns true if the pool is empty, |
| // it does not contain any busy item. It can mean either that |
| // there is no <EPTF_POOLTYPE> slot allocated at all, or that all allocated |
| // <EPTF_POOLTYPE> slots are unused (i.e., free) |
| // Use this function to decide whether calling <f_EPTF_getFirst##EPTF_POOLTYPE##Index> makes sense, or not. |
| // |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_POOLISEMPTY_(TYPEARG) \ |
| function f_EPTF_##TYPEARG##PoolIsEmpty(in TYPEARG##Pool pl_pool) return boolean\ |
| {\ |
| if(f_EPTF_FBQ_getLengthOfBusyChain(pl_pool.order) <=0) {\ |
| return true\ |
| } else {\ |
| return false\ |
| };\ |
| } |
| #define F_POOLISEMPTY(TYPEARG) F_POOLISEMPTY_(TYPEARG) |
| F_POOLISEMPTY(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_##EPTF_POOLTYPE##IsBusy |
| // |
| // Purpose: |
| // function to check whether a given <EPTF_POOLTYPE> slot is used (busy), or not |
| // |
| // Parameters: |
| // pl_pool - *in* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // pl_idx - *in* *integer* - the index of the slot to be checked |
| // |
| // Return Value: |
| // boolean - true, if the <EPTF_POOLTYPE> slot is used |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // (none) |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_POOLISBUSY_(TYPEARG) \ |
| function f_EPTF_##TYPEARG##IsBusy(in TYPEARG##Pool pl_pool,in integer pl_idx) return boolean {\ |
| return f_EPTF_FBQ_itemIsBusy(pl_idx,pl_pool.order);\ |
| } |
| #define F_POOLISBUSY(TYPEARG) F_POOLISBUSY_(TYPEARG) |
| F_POOLISBUSY(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_get##EPTF_POOLTYPE |
| // |
| // Purpose: |
| // function to get a given <EPTF_POOLTYPE> slot from the pool without |
| // knowing the internal data structure, or accessing it directly |
| // |
| // Parameters: |
| // pl_pool - *in* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // pl_idx - *in* *integer* - the index of the pool item to be retrieved |
| // |
| // pl_poolItem - *out* <EPTF_POOLTYPE> - the pool item at the given index |
| // |
| // Return Value: |
| // boolean - true, if the pool item is succesfully retrieved |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_GETITEM_(TYPEARG) \ |
| function f_EPTF_get##TYPEARG(in TYPEARG##Pool pl_pool,in integer pl_idx,out TYPEARG pl_poolItem) return boolean {\ |
| if (not f_EPTF_##TYPEARG##IsBusy(pl_pool, pl_idx)) {\ |
| return false\ |
| } else {\ |
| pl_poolItem := pl_pool.userData[pl_idx];\ |
| return true;\ |
| }\ |
| } |
| #define F_GETITEM(TYPEARG) F_GETITEM_(TYPEARG) |
| F_GETITEM(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_set##EPTF_POOLTYPE |
| // |
| // Purpose: |
| // function to set a given <EPTF_POOLTYPE> slot within the pool without |
| // knowing the internal data structure, or accessing it directly |
| // |
| // Parameters: |
| // pl_pool - *inout* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // pl_idx - *in* *integer* - the index of the pool item to be set |
| // |
| // pl_poolItem - *in* <EPTF_POOLTYPE> - the new value of the pool item to be set |
| // |
| // Return Value: |
| // boolean |
| // |
| // Errors: |
| // - It is an error, if the slot to be set is not already busy |
| // (i.e., used/allocated) |
| // |
| // Detailed Comments: |
| // boolean - true, if the tuple is succesfully set |
| // |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_SETITEM_(TYPEARG) \ |
| function f_EPTF_set##TYPEARG(inout TYPEARG##Pool pl_pool,in integer pl_idx,in TYPEARG pl_poolItem) return boolean {\ |
| if (not f_EPTF_##TYPEARG##IsBusy(pl_pool, pl_idx)) {\ |
| pl_pool.userData[pl_idx] := pl_poolItem;\ |
| f_EPTF_FBQ_moveFromFreeToBusyTail(pl_idx,pl_pool.order);\ |
| return true;\ |
| } else {return false }\ |
| } |
| #define F_SETITEM(TYPEARG) F_SETITEM_(TYPEARG) |
| F_SETITEM(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_setNew##EPTF_POOLTYPE |
| // |
| // Purpose: |
| // function to create a new <EPTF_POOLTYPE> slot its value within the pool without |
| // knowing the internal data structure, or accessing it directly |
| // |
| // Parameters: |
| // pl_pool - *inout* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // pl_poolItem - *in* <EPTF_POOLTYPE> - the new value of the pool item to be set |
| // |
| // Return Value: |
| // integer - the index of the <EPTF_POOLTYPE> item |
| // |
| // Errors: |
| // - It is an error, if the slot to be set is not already busy |
| // (i.e., used/allocated) |
| // |
| // Detailed Comments: |
| // boolean - true, if the tuple is succesfully set |
| // |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_SETNEWITEM_(TYPEARG) \ |
| function f_EPTF_setNew##TYPEARG(inout TYPEARG##Pool pl_pool,in TYPEARG pl_poolItem) return integer {\ |
| var integer idx := f_EPTF_FBQ_getOrCreateFreeSlot(pl_pool.order);\ |
| if (idx >= sizeof(pl_pool.userData)){\ |
| if (tsp_debugVerbose_PoolMgmt) {\ |
| log("f_EPTF_setNew##EPTF_POOLTYPE needed to allocate new ##EPTF_POOLTYPE",\ |
| " at idx:",idx, ", initialized to:",pl_poolItem);\ |
| }\ |
| }\ |
| pl_pool.userData[idx] := pl_poolItem;\ |
| f_EPTF_FBQ_moveFromFreeToBusyTail(idx,pl_pool.order);\ |
| return idx;\ |
| } |
| #define F_SETNEWITEM(TYPEARG) F_SETNEWITEM_(TYPEARG) |
| F_SETNEWITEM(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_setValue##EPTF_POOLTYPE |
| // |
| // Purpose: |
| // function to set a new value into the slot of the <EPTF_POOLTYPE##Pool> pool |
| // |
| // Parameters: |
| // pl_pool - *inout* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // pl_idx - *in* *integer* - the index of the pool item to be set |
| // pl_poolItem - *in* <EPTF_POOLTYPE> - the new value of the pool item to be set |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // |
| // Detailed Comments: |
| // |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_SETVALUEITEM_(TYPEARG) \ |
| function f_EPTF_setValue##TYPEARG(inout TYPEARG##Pool pl_pool,in integer pl_idx,in TYPEARG pl_poolItem) {\ |
| pl_pool.userData[pl_idx] := pl_poolItem;\ |
| } |
| #define F_SETVALUEITEM(TYPEARG) F_SETVALUEITEM_(TYPEARG) |
| F_SETVALUEITEM(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_getValue##EPTF_POOLTYPE |
| // |
| // Purpose: |
| // function to get the value of a slot of the <EPTF_POOLTYPE##Pool> pool |
| // |
| // Parameters: |
| // pl_pool - *inout* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // pl_idx - *in* *integer* - the index of the pool item to get |
| // |
| // Return Value: |
| // EPTF_POOLTYPE - the value <EPTF_POOLTYPE> item |
| // |
| // Errors: |
| // |
| // Detailed Comments: |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_GETVALUEITEM_(TYPEARG) \ |
| function f_EPTF_getValue##TYPEARG(inout TYPEARG##Pool pl_pool,in integer pl_idx) return TYPEARG {\ |
| return pl_pool.userData[pl_idx];\ |
| } |
| #define F_GETVALUEITEM(TYPEARG) F_GETVALUEITEM_(TYPEARG) |
| F_GETVALUEITEM(EPTF_POOLTYPE) |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_delete##EPTF_POOLTYPE |
| // |
| // Purpose: |
| // function to delete a used <EPTF_POOLTYPE> item from the pool, |
| // i.e., to make it available for future reuse (release this slot) |
| // Resets the element in the database to <c_empty##TYPEARG>. |
| // |
| // Parameters: |
| // pl_##EPTF_POOLTYPE##Pool - *inout* <EPTF_POOLTYPE##Pool> - the pool to operate on |
| // |
| // pl_qidx - *in* *integer* - index of the element to be removed |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - If the event at index pl_qidx is not valid (i.e., |
| // <f_EPTF_##EPTF_POOLTYPE##IsBusy> (pl_##EPTF_POOLTYPE##Pool, pl_qidx) is false), |
| // then <f_EPTF_delete##EPTF_POOLTYPE> fails |
| // |
| // |
| /////////////////////////////////////////////////////////// |
| #define F_DELETEITEM_(TYPEARG) \ |
| function f_EPTF_delete##TYPEARG(inout TYPEARG##Pool pl_pool, in integer pl_qidx) {\ |
| if (tsp_debugVerbose_PoolMgmt) {\ |
| log("f_delete##EPTF_POOLTYPE:", pl_qidx);\ |
| }\ |
| if (not f_EPTF_##TYPEARG##IsBusy(pl_pool, pl_qidx)){\ |
| log("Warning: f_EPTF_delete##EPTF_POOLTYPE: clearing free/invalid pool item at pl_qidx:",\ |
| pl_qidx);\ |
| return;\ |
| }\ |
| f_EPTF_FBQ_moveFromBusyToFreeTail(pl_qidx,pl_pool.order);\ |
| pl_pool.userData[pl_qidx] := c_empty##TYPEARG;\ |
| return;\ |
| } |
| #define F_DELETEITEM(TYPEARG) F_DELETEITEM_(TYPEARG) |
| F_DELETEITEM(EPTF_POOLTYPE) |
| |