From 3d61697e688c99ff9265238b2eab474f7f1bcfc8 Mon Sep 17 00:00:00 2001 From: Octasic Inc Date: Wed, 23 Nov 2005 15:07:18 +0200 Subject: importing OCT612x-01.00-PR38 --- software/apilib/llman/octapi_llman.c | 2715 ++++++++++++++++++++++++++++++++++ 1 file changed, 2715 insertions(+) create mode 100644 software/apilib/llman/octapi_llman.c (limited to 'software/apilib/llman/octapi_llman.c') diff --git a/software/apilib/llman/octapi_llman.c b/software/apilib/llman/octapi_llman.c new file mode 100644 index 0000000..13c68eb --- /dev/null +++ b/software/apilib/llman/octapi_llman.c @@ -0,0 +1,2715 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman.c + + Copyright (c) 2001-2005 Octasic Inc. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API 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 General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR38 $ + +$Octasic_Revision: 21 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "octapi_llman_private.h" +#include "apilib/octapi_llman.h" +#include "apilib/octapi_largmath.h" + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocGetSize. +| +| Description: This function determines the amount of memory needed to +| manage the allocation of a fixed amount of resources. +| The memory is measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctapiLlmAllocGetSize(UINT32 number_of_items,UINT32 * l_size) +{ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + *l_size = (sizeof(LLM_ALLOC)) + (number_of_items * sizeof(UINT32)); + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInit. +| +| Description: This function intializes the LLM_ALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| **l void The memory used by the LLM_ALLOC structure. +| number_of_items UINT32 The number of resources to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctapiLlmAllocInit(void ** l,UINT32 number_of_items) +{ + LLM_ALLOC* ls; + UINT32 i; + + /* Check the number of items required.*/ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + /* If no memory has been allocated yet:*/ + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)(*l); + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + ls->number_of_items = number_of_items; + + /* Linked list links all structures in ascending order.*/ + for(i=0;ilinked_list[i] = i+1; + } + + ls->linked_list[number_of_items - 1] = 0xFFFFFFFF; /* Invalid link.*/ + + /* Next avail is 0.*/ + ls->next_avail_num = 0; + + /* Number of allocated items is null.*/ + ls->allocated_items = 0; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInfo. +| +| Description: This function returns the number of free and allocated +| block in the LLMAN list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *allocated_items UINT32 Number of allocated items. +| *available_items UINT32 Number of available items. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctapiLlmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items) +{ + LLM_ALLOC* ls; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + *allocated_items = ls->allocated_items; + *available_items = ls->number_of_items - ls->allocated_items; + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInfo. +| +| Description: This function allocates the resource indicated by blocknum. +| If the resource can be allocated then GENERIC_OK is returned. +| Else an error. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *block_num UINT32 The resource to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctapiLlmAllocAlloc(void * l,UINT32 * blocknum) +{ + LLM_ALLOC* ls; + UINT32 allocated_block; + UINT32* node; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + /* Get next available block number.*/ + allocated_block = ls->next_avail_num; + + /* Check if block is invalid.*/ + if (allocated_block == 0xFFFFFFFF) + { + /* Make blocknum NULL.*/ + *blocknum = 0xFFFFFFFF; + + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + } + + node = &ls->linked_list[allocated_block]; + + /* Copy next block number.*/ + ls->next_avail_num = *node; + + /* Tag as used the current block number.*/ + *node = 0xFFFFFFFE; + + /* Return proper block number.*/ + *blocknum = allocated_block; + + /* Update block usage number.*/ + ls->allocated_items++; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocDealloc. +| +| Description: This function deallocates the resource indicated by blocknum. +| If the resource is not already allocated an error is returned. +| Else GENERIC_OK is returned. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| block_num UINT32 The resource to be deallocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctapiLlmAllocDealloc(void * l,UINT32 blocknum) +{ + LLM_ALLOC* ls; + UINT32* node; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + /* Check for null item pointer.*/ + if (blocknum == 0xFFFFFFFF) return(GENERIC_OK); + + /* Check if blocknum is within specified item range.*/ + if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + node = &ls->linked_list[blocknum]; + + /* Check if block is really used as of now.*/ + if (*node != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Add link to list.*/ + *node = ls->next_avail_num; + + /* Point to returned block.*/ + ls->next_avail_num = blocknum; + + /* Update block usage number.*/ + ls->allocated_items--; + + return(GENERIC_OK); +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocGetSize. +| +| Description: This function determines the amount of memory needed to +| manage the allocation of a fixed amount of resources. +| The memory is measured in bytes. +| +| This version is a time manage version of llman. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiTllmAllocGetSize(UINT32 number_of_items,UINT32 * l_size) +{ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + *l_size = (sizeof(TLLM_ALLOC)) + (number_of_items * sizeof(TLLM_ALLOC_NODE)); + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocInit. +| +| Description: This function intializes the TLLM_ALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| **l void The memory used by the LLM_ALLOC structure. +| number_of_items UINT32 The number of resources to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiTllmAllocInit(void ** l,UINT32 number_of_items) +{ + TLLM_ALLOC* ls; + UINT32 i; + + /* Check the number of items required.*/ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + /* If no memory has been allocated yet.*/ + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)(*l); + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + ls->number_of_items = number_of_items; + + /* Linked list links all structures in ascending order.*/ + for(i=0;ilinked_list[i].value = i+1; + } + + ls->linked_list[number_of_items - 1].value = 0xFFFFFFFF; /* Invalid link.*/ + + /* Next avail is 0.*/ + ls->next_avail_num = 0; + + /* Number of allocated items is null.*/ + ls->allocated_items = 0; + + /* Set the number of timeout entry.*/ + ls->number_of_timeout = 0; + + /* Next timeout is 0.*/ + ls->next_timeout_num = 0xFFFFFFFF; + ls->last_timeout_num = 0xFFFFFFFF; + + /* Set the known time to 0.*/ + ls->last_known_time[ 0 ] = 0; + ls->last_known_time[ 1 ] = 0; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocInfo. +| +| Description: This function returns the number of free and allocated +| block in the TLLMAN list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *allocated_items UINT32 Number of allocated items. +| *available_items UINT32 Number of available items. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiTllmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items) +{ + TLLM_ALLOC* ls; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + *allocated_items = ls->allocated_items; + *available_items = ls->number_of_items - ls->allocated_items; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocAlloc. +| +| Description: This function allocates the resource indicated by blocknum. +| If the resource can be allocated then GENERIC_OK is returned. +| Else an error. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *block_num UINT32 The resource to be allocated. +| *current_time UINT32 +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiTllmAllocAlloc(void * l,UINT32 * blocknum, UINT32 *current_time) +{ + TLLM_ALLOC* ls; + UINT32 allocated_block; + TLLM_ALLOC_NODE* node; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + if ( ls->allocated_items == ls->number_of_items && + ls->next_timeout_num != 0xFFFFFFFF ) + { + UINT32 l_ulResult; + l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time ); + if ( l_ulResult != GENERIC_OK ) + return l_ulResult; + } + + /* Get next available block number.*/ + allocated_block = ls->next_avail_num; + + /* Check if block is invalid.*/ + if (allocated_block == 0xFFFFFFFF) + { + /* Make blocknum NULL.*/ + *blocknum = 0xFFFFFFFF; + + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + } + + node = &ls->linked_list[allocated_block]; + + /* Copy next block number.*/ + ls->next_avail_num = node->value; + + /* Tag as used the current block number.*/ + node->value = 0xFFFFFFFE; + + /* Return proper block number.*/ + *blocknum = allocated_block; + + /* Update block usage number.*/ + ls->allocated_items++; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocDealloc. +| +| Description: This function deallocates the resource indicated by blocknum. +| If the resource is not already allocated an error is returned. +| Else GENERIC_OK is returned. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| block_num UINT32 The resource to be deallocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiTllmAllocDealloc(void * l,UINT32 blocknum, UINT32 timeout_value, UINT32 current_time[2]) +{ + TLLM_ALLOC* ls; + TLLM_ALLOC_NODE* node; + UINT32 l_ulResult; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + /* Check for null item pointer.*/ + if (blocknum == 0xFFFFFFFF) return(GENERIC_OK); + + /* Check if blocknum is within specified item range.*/ + if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + if ( ls->next_timeout_num != 0xFFFFFFFF ) + { + l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time ); + if ( l_ulResult != GENERIC_OK ) + return l_ulResult; + } + + node = &ls->linked_list[blocknum]; + + /* Check if block is really used as of now.*/ + if (node->value != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Add link to timeout list.*/ + if ( ls->last_timeout_num != 0xFFFFFFFF ) + { + TLLM_ALLOC_NODE* last_node; + + /* insert the node at the end of the list.*/ + node->value = 0xFFFFFFFF; + last_node = &ls->linked_list[ ls->last_timeout_num ]; + last_node->value = blocknum; + } + else + { + /* The node is alone in the list.*/ + node->value = 0xFFFFFFFF; + ls->next_timeout_num = blocknum; + } + + ls->last_timeout_num = blocknum; + ls->number_of_timeout++; + + /* Set the timeout time of the node.*/ + l_ulResult = OctApiLmAdd( current_time, 1, &timeout_value, 0, node->timeout, 1 ); + if (l_ulResult != GENERIC_OK) + return(l_ulResult); + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmCheckTimeoutList. +| +| Description: This function will verify if the timeout time +| of all the node present in the timeout list are bigger +| then the current time. If so the node will be returned +| ot the free node list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *ls TLLM_ALLOC The memory used by the TLLM_ALLOC structure. +| current_time UINT32[2] The current time in msec. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiTllmCheckTimeoutList(TLLM_ALLOC *ls, UINT32 current_time[2]) +{ + UINT32 result; + UINT32 fConditionFlag = TRUE; + + /* Free-up any pending memory before trying the allocation:*/ + if ((ls->last_known_time[0] != current_time[0] || + ls->last_known_time[1] != current_time[1]) && + (current_time[1] != 0 || current_time[0] != 0)) /* Time has changed.*/ + { + TLLM_ALLOC_NODE *pcurrent_node; + UINT32 current_num; + USHORT neg; + + /* Remember time for next time!*/ + ls->last_known_time[0] = current_time[0]; + ls->last_known_time[1] = current_time[1]; + + + while ( fConditionFlag == TRUE ) + { + /* Get a node from the timeout list.*/ + pcurrent_node = &ls->linked_list[ ls->next_timeout_num ]; + current_num = ls->next_timeout_num; + + /* Check if first node has timeout.*/ + result = OctApiLmCompare(current_time,1,pcurrent_node->timeout ,1,&neg); + if (result != GENERIC_OK) return(result); + + /* if the timeout tiem was exceeded, set the block as free.*/ + if ( neg == FALSE ) + { + /* set the next node pointer.*/ + ls->next_timeout_num = pcurrent_node->value; + ls->number_of_timeout--; + + /* reset the last pointer of the timeout list.*/ + if ( ls->number_of_timeout == 0 ) + ls->last_timeout_num = 0xFFFFFFFF; + + /* return the node the free list.*/ + pcurrent_node->value = ls->next_avail_num; + ls->next_avail_num = current_num; + ls->allocated_items--; + } + else /* node not in timeout */ + { + fConditionFlag = FALSE; + break; + } + + if ( ls->next_timeout_num == 0xFFFFFFFF ) + { + fConditionFlag = FALSE; + break; /* end of timeout list.*/ + } + } + } + + return(GENERIC_OK); +} +/**************************************** llm_alloc section **********************************************/ + + + + + + + +/**************************************** llm_list section **********************************************/ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListGetSize +| +| Description: This function determines the amount of memory needed by +| the LLM_LIST structure to manage the allocation of +| number_of_items number of resources. The memory is +| measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size) +{ + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + *l_size = sizeof(LLM_LIST) + (number_of_lists * sizeof(LLM_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4)); + + return(GENERIC_OK); +} + +LLM_LIST_ITEM * OctApiLlmListGetItemPointer(LLM_LIST * ls, UINT32 item_number) +{ + return (LLM_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInit. +| +| Description: This function intializes the LLM_TALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size) +{ + LLM_LIST* ls; + LLM_LIST_ITEM* item; + UINT32 i; + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + UINT32 total_lists; + BYTE* lsbyte; + + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + /* Get the size of the Alloc structure used to manage head of list structures.*/ + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize parameters in the structure.*/ + ls->head_alloc_size = head_alloc_size; + ls->user_info_bytes = user_info_size; + ls->user_info_size = user_info_size_roundup; + ls->total_items = number_of_items; + ls->assigned_items = 0; + ls->total_lists = number_of_lists; + ls->assigned_lists = 0; + ls->next_empty_item = 0; + ls->item_size = sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4; + + /* Complete the build!*/ + ls = (LLM_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize the head of queue Alloc structure.*/ + result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists); + if(result != GENERIC_OK) return(result); + + /* Initialize the linked list of the items:*/ + for(i=0; ili + ls->item_size * i); + + if (i == (number_of_items - 1)) + item->forward_link = 0xFFFFFFFF; + else + item->forward_link = i + 1; + } + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInfo. +| +| Description: This function returns the status of the LLM_LIST structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *allocated_lists UINT32 The number of linked_lists allocated. +| *free_lists UINT32 The number of linked_lists still free. +| *allocated_items UINT32 The number of items allocated to lists. +| *free_items UINT32 The number of items still free. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListInfo(void * l,UINT32 * allocated_lists,UINT32 * allocated_items, + UINT32 * free_lists,UINT32 * free_items) +{ + LLM_LIST* ls; + BYTE* lsbyte; + UINT32 total_lists; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + *allocated_items = ls->assigned_items; + *free_items = ls->total_items - ls->assigned_items; + + *allocated_lists = ls->assigned_lists; + *free_lists = ls->total_lists - ls->assigned_lists; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCreate. +| +| Description: This function creates a linked list. The target which is +| allocated the newly created list can request additions +| or removals from the list later on. To target identifies +| its list with the returned list handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the new list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListCreate(void * l,UINT32 * list_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 blocknum; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum); + if (result != GENERIC_OK) return(result); + + /* The handle is the block number.*/ + *list_handle = blocknum; + + /* Initialize the list head structure.*/ + lh = &ls->lh[blocknum]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListDelete. +| +| Description: This function deletes the linked list indicated by the +| handle list_handle. Any items which are still allocated +| to the list are first deallocated. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListDelete(void * l,UINT32 list_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Release internal list header handle...*/ + result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle); + if (result != GENERIC_OK) return(result); + + lh = &ls->lh[list_handle]; + + /* Deallocate all items in the list!*/ + if (lh->list_length != 0) + { + LLM_LIST_ITEM * item; + + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + /* Release the items using only the links.*/ + item->forward_link = ls->next_empty_item; + ls->next_empty_item = lh->head_pointer; + + /* Remove items from item counter.*/ + ls->assigned_items -= lh->list_length; + } + + lh->list_length = 0xFFFFFFFF; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists--; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListLength. +| +| Description: This function returns the number of items allocated to the +| list indicated by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| *number_of_items UINT32 The number of items in the list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 total_lists; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + *number_of_items_in_list = lh->list_length; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListItemData +| +| Description: This function returns a pointer to the user data associated +| with an item. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the list node in question. +| **item_data_pnt void The pointer to the user data, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListItemData(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + UINT32 total_lists; + UINT32 list_length; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + list_length = lh->list_length; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (list_length <= item_number) return(OCTAPI_LLM_ELEMENT_NOT_FOUND); + + /* Determine where the search will start.*/ + if (list_length == (item_number + 1)) /* Last item in list:*/ + { + cur_list_pnt = lh->tail_pointer; + cur_list_num = item_number; + } + else if (lh->cache_item_number <= item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + /* Write new cache entry.*/ + lh->cache_item_pointer = cur_list_pnt; + lh->cache_item_number = cur_list_num; + + /* Get item info.*/ + *item_data_pnt = (void *)item->user_info; + + return(GENERIC_OK); + } + else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInsertItem. +| +| Description: This function allocates a node to the linked list specified +| by the handle list_handle. The position of the new item +| can be specified. A position of 0xFFFFFFFF means append to the +| list( use the OCTAPI_LLM_LIST_APPEND define for clarity); +| a position of 0 mean insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListInsertItem(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* free_item; + UINT32 free_item_pnt; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (lh->list_length < item_number && item_number != 0xFFFFFFFF) + return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + + /* Get a free item from the free item list!*/ + free_item_pnt = ls->next_empty_item; + free_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt); + ls->next_empty_item = free_item->forward_link; + + if (item_number == 0xFFFFFFFF) + item_number = lh->list_length; + + if (lh->list_length == 0) /* First item and only item:*/ + { + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + lh->head_pointer = free_item_pnt; + } + else if (item_number == 0) /* First item and but list not empty:*/ + { + free_item->forward_link = lh->head_pointer; + lh->head_pointer = free_item_pnt; + } + else if (item_number == lh->list_length) /* Append:*/ + { + LLM_LIST_ITEM * last_item; + last_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + last_item->forward_link = free_item_pnt; + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + } + else /* Insert:*/ + { + LLM_LIST_ITEM * last_item = NULL; + LLM_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + + if (lh->cache_item_number < item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1); + + free_item->forward_link = cur_list_pnt; + last_item->forward_link = free_item_pnt; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + } + + /* Increase the list length.*/ + lh->list_length++; + ls->assigned_items++; + *item_data_pnt = (void *)free_item->user_info; + + /* Write new cache entry.*/ + lh->cache_item_pointer = free_item_pnt; + lh->cache_item_number = item_number; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCreateFull. +| +| Description: This function allocates the desired number of nodes to +| the linked list specified by the handle list_handle. +| The position of the new item can be specified. A +| position of 0xFFFFFFFF means append to the list (use the +| OCTAPI_LLM_LIST_APPEND define for clarity); a position +| of 0 means insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListCreateFull(void* l, UINT32 list_length, UINT32* plist_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* free_item; + LLM_LIST_ITEM* last_item = NULL; + UINT32 free_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 list_handle; + UINT32 list_length_m1; + UINT32 next_empty_item; + UINT32 result; + UINT32 i; + BYTE* lsbyte; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure another list can be created.*/ + if (ls->assigned_lists == ls->total_lists) + return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED); + + /* Make sure there are enough free nodes to fill the new list.*/ + if (list_length > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Create list (i.e. get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &list_handle); + if (result != GENERIC_OK) return(result); + + /* Initialize the list head structure.*/ + lh = &ls->lh[list_handle]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + lh = &ls->lh[list_handle]; + list_length_m1 = list_length - 1; + next_empty_item = ls->next_empty_item; + + for (i=0; ili + ls->item_size * free_item_pnt); + next_empty_item = free_item->forward_link; + + /* Branch according to whether the node is the first in list, last, or in + the middle.*/ + if (i == 0) + { + /* First item.*/ + free_item->forward_link = 0xFFFFFFFF; + lh->head_pointer = free_item_pnt; + lh->tail_pointer = free_item_pnt; + } + else if (i == list_length_m1) + { + /* Last item.*/ + last_item->forward_link = free_item_pnt; + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + } + else + { + /* Node somewhere in the middle.*/ + last_item->forward_link = free_item_pnt; + } + + /* Store pointer to free item as pointer to last item (for next iteration).*/ + last_item = free_item; + } + + /* Store new value of next_empty_item.*/ + ls->next_empty_item = next_empty_item; + + /* Write new cache entry.*/ + lh->cache_item_pointer = free_item_pnt; + lh->cache_item_number = list_length_m1; + + /* Set the list length.*/ + lh->list_length = list_length; + ls->assigned_items += list_length; + + /* Return pointer to new list.*/ + *plist_handle = list_handle; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListAppendItems. +| +| Description: This function allocates the desired number of nodes to +| the linked list specified by the handle list_handle. +| The position of the new item can be specified. A +| position of 0xFFFFFFFF means append to the list (use the +| OCTAPI_LLM_LIST_APPEND define for clarity); a position +| of 0 means insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListAppendItems(void* l, UINT32 list_handle, UINT32 num_items) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item_list; + LLM_LIST_ITEM* curr_item = NULL; + LLM_LIST_ITEM* free_item; + UINT32 curr_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 next_empty_item; + UINT32 item_size; + UINT32 i; + BYTE* lsbyte; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure there is at least one item.*/ + if (num_items == 0) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure there are enough free nodes.*/ + if (num_items > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Get pointer to list structure.*/ + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + item_list = ls->li; + item_size = ls->item_size; + next_empty_item = ls->next_empty_item; + + for (i=0; ihead_pointer == 0xFFFFFFFF) + { + /* Current and next items are one and the same!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Set new head and tail pointers.*/ + lh->head_pointer = next_empty_item; + lh->tail_pointer = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next item.*/ + next_empty_item = curr_item->forward_link; + + /* Set first item to be only item in list.*/ + curr_item->forward_link = 0xFFFFFFFF; + } + else + { + /* Get a free item from the free item list!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer); + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + else + { + /* Update pointers to current item and free item.*/ + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + + /* Terminate list.*/ + if ( curr_item != NULL ) + curr_item->forward_link = 0xFFFFFFFF; + + /* Update llman structure variables.*/ + ls->next_empty_item = next_empty_item; + ls->assigned_items += num_items; + + /* Update list variables.*/ + lh->list_length += num_items; + lh->cache_item_pointer = curr_item_pnt; + lh->cache_item_number = lh->list_length - 1; + lh->tail_pointer = curr_item_pnt; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListAppendAndSetItems. +| +| Description: +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListAppendAndSetItems(void* l, UINT32 list_handle, UINT32 num_items, void* data_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item_list; + LLM_LIST_ITEM* curr_item = NULL; + LLM_LIST_ITEM* free_item; + UINT32 curr_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 next_empty_item; + UINT32 user_info_bytes; + UINT32 item_size; + UINT32 i; + BYTE* lsbyte; + void* data_item; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure there is at least one item.*/ + if (num_items == 0) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure there are enough free nodes.*/ + if (num_items > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Get pointer to list structure.*/ + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + item_list = ls->li; + user_info_bytes = ls->user_info_bytes; + item_size = ls->item_size; + next_empty_item = ls->next_empty_item; + data_item = data_list; + + for (i=0; ihead_pointer == 0xFFFFFFFF) + { + /* Current and next items are one and the same!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Set new head and tail pointers.*/ + lh->head_pointer = next_empty_item; + lh->tail_pointer = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next item.*/ + next_empty_item = curr_item->forward_link; + + /* Set first item to be only item in list.*/ + curr_item->forward_link = 0xFFFFFFFF; + } + else + { + /* Get a free item from the free item list!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer); + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + else + { + /* Update pointers to current item and free item.*/ + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + + /* Copy data to new item.*/ + OctApiLlmMemCpy(curr_item->user_info, data_item, user_info_bytes); + + /* Update data_item pointer for next iteration (item).*/ + data_item = (void *)((BYTE *)data_item + user_info_bytes); + } + + + /* Terminate list.*/ + if ( curr_item != NULL ) + curr_item->forward_link = 0xFFFFFFFF; + + /* Update llman structure variables.*/ + ls->next_empty_item = next_empty_item; + ls->assigned_items += num_items; + + /* Update list variables.*/ + lh->list_length += num_items; + lh->cache_item_pointer = curr_item_pnt; + lh->cache_item_number = lh->list_length - 1; + lh->tail_pointer = curr_item_pnt; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListSetItems. +| +| Description: This function takes a start entry (0 to length - 1), +| a pointer to a list of data (each item of list is the +| size of one data unit, specified at init), and the +| length of the data list. From this, the data will be +| copied from the data list to the linked list, from +| entry start_entry to (start_entry + data_length - 1). +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListSetItems(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item = NULL; + UINT32 total_lists; + UINT32 item_pnt = 0xFFFFFFFF; + UINT32 i, j; + BYTE* lsbyte; + void* pdata_item = NULL; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure the start_entry is within limits.*/ + if (start_item >= lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure the end_entry is within limits.*/ + lh = &ls->lh[list_handle]; + if ((start_item + data_length) > lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Set the data of each node.*/ + for (i=0; icache_item_number + 1)) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer); + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + else + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer); + item_pnt = lh->head_pointer; + for (j=0; jforward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + } + + pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes)); + } + else + { + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + + pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes); + } + + /* Set the value of the item's user data.*/ + OctApiLlmMemCpy(item->user_info, pdata_item, ls->user_info_bytes); + } + + /* Write new cache entry.*/ + lh->cache_item_pointer = item_pnt; + lh->cache_item_number = start_item + data_length - 1; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCopyData. +| +| Description: This function takes a start entry (0 to length - 1), +| a pointer to a list of data (each item of list is the +| size of one data unit, specified at init), and the +| length of the data list. From this, the data will be +| copied from the linked list to the data list, from +| entry start_entry of the linked list to +| (start_entry + data_length - 1). +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListCopyData(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item = NULL; + UINT32 item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 i, j; + BYTE* lsbyte; + void* pdata_item = NULL; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure the start_entry is within limits.*/ + if (start_item >= lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure the end_entry is within limits.*/ + lh = &ls->lh[list_handle]; + if ((start_item + data_length) > lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Set the data of each node.*/ + for (i=0; icache_item_number + 1)) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer); + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + else + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer); + for (j=0; jforward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + } + + pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes)); + } + else + { + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + + pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes); + } + + /* Set the value of the item's user data.*/ + OctApiLlmMemCpy(pdata_item, item->user_info, ls->user_info_bytes); + } + + /* Write new cache entry.*/ + lh->cache_item_pointer = item_pnt; + lh->cache_item_number = start_item + data_length - 1; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListRemoveItem. +| +| Description: This function deallocates a node of the linked list specified +| by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the item to be removed. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlmListRemoveItem(void * l,UINT32 list_handle,UINT32 item_number) +{ + LLM_LIST* ls; + LLM_LIST_ITEM* freed_item = NULL; + LLM_LIST_HEAD* lh; + UINT32 freed_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (lh->list_length <= item_number) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + if (item_number == 0 && lh->list_length == 1)/* First item and only item:*/ + { + freed_item_pnt = lh->head_pointer; + freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + } + else if (item_number == 0) /* First item and but list not empty:*/ + { + freed_item_pnt = ls->lh[list_handle].head_pointer; + freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + lh->head_pointer = freed_item->forward_link; + + lh->cache_item_number = 0; + lh->cache_item_pointer = freed_item->forward_link; + } + else /* Discard non-first item! (Caution: this could be the last item!)*/ + { + LLM_LIST_ITEM * last_item = NULL; + LLM_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + + if (lh->cache_item_number < item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1); + + if ((item_number + 1) == lh->list_length) + { + lh->tail_pointer = last_list_pnt; + last_item->forward_link = 0xFFFFFFFF; + } + else + { + last_item->forward_link = item->forward_link; + } + freed_item_pnt = cur_list_pnt; + freed_item = item; + + /* Reset cache entry.*/ + lh->cache_item_pointer = last_list_pnt; + lh->cache_item_number = cur_list_num - 1; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + } + + /* Decrease the list length.*/ + lh->list_length--; + ls->assigned_items--; + + /* Return free block to free block list:*/ + freed_item->forward_link = ls->next_empty_item; + ls->next_empty_item = freed_item_pnt; + + return(GENERIC_OK); +} + +/**************************************** llm2 function section *****************************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListGetSize +| +| Description: This function determines the amount of memory needed by +| the LLM2_LIST structure to manage the allocation of +| number_of_items number of resources. The memory is +| measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlm2ListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size) +{ + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + *l_size = sizeof(LLM2_LIST) + (number_of_lists * sizeof(LLM2_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4)); + + return(GENERIC_OK); +} + +LLM2_LIST_ITEM * OctApiLlm2ListGetItemPointer(LLM2_LIST * ls, UINT32 item_number) +{ + return (LLM2_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListInit. +| +| Description: This function intializes the LLM2_TALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlm2ListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size) +{ + LLM2_LIST* ls; + LLM2_LIST_ITEM* item; + UINT32 i; + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + UINT32 total_lists; + BYTE* lsbyte; + + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + /* Get the size of the Alloc structure used to manage head of list structures.*/ + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize parameters in the structure.*/ + ls->head_alloc_size = head_alloc_size; + ls->user_info_bytes = user_info_size; + ls->user_info_size = user_info_size_roundup; + ls->total_items = number_of_items; + ls->assigned_items = 0; + ls->total_lists = number_of_lists; + ls->assigned_lists = 0; + ls->next_empty_item = 0; + ls->item_size = sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4; + + /* Complete the build!*/ + ls = (LLM2_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize the head of queue Alloc structure.*/ + result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists); + if(result != GENERIC_OK) return(result); + + /* Initialize the linked list of the items:*/ + for(i=0; ili + ls->item_size * i); + + if (i == (number_of_items - 1)) + item->forward_link = 0xFFFFFFFF; + else + item->forward_link = i + 1; + } + + return(GENERIC_OK); +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListCreate. +| +| Description: This function creates a linked list. The target which is +| allocated the newly created list can request additions +| or removals from the list later on. To target identifies +| its list with the returned list handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the new list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlm2ListCreate(void * l,UINT32 * list_handle) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 blocknum; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum); + if (result != GENERIC_OK) return(result); + + /* The handle is the block number.*/ + *list_handle = blocknum; + + /* Initialize the list head structure.*/ + lh = &ls->lh[blocknum]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListDelete. +| +| Description: This function deletes the linked list indicated by the +| handle list_handle. Any items which are still allocated +| to the list are first deallocated. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| *list_handle UINT32 The handle to the list. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlm2ListDelete(void * l,UINT32 list_handle) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + /* Release internal list header handle...*/ + result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle); + if (result != GENERIC_OK) return(result); + + lh = &ls->lh[list_handle]; + + /* Deallocate all items in the list!*/ + if (lh->list_length != 0) + { + LLM2_LIST_ITEM * item; + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + /* Release the items using only the links.*/ + item->forward_link = ls->next_empty_item; + ls->next_empty_item = lh->head_pointer; + + /* Remove items from item counter.*/ + ls->assigned_items -= lh->list_length; + } + + lh->list_length = 0xFFFFFFFF; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + ls->assigned_lists--; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListLength. +| +| Description: This function returns the number of items allocated to the +| list indicated by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| *number_of_items UINT32 The number of items in the list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlm2ListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 total_lists; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + *number_of_items_in_list = lh->list_length; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListItemData +| +| Description: This function returns a pointer to the user data associated +| with an item. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the list node in question. +| **item_data_pnt void The pointer to the user data, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlm2ListItemData(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, PUINT32 item_number_pnt) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + LLM2_LIST_ITEM* item; + UINT32 cur_list_pnt; + UINT32 cur_list_key = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 list_length; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + list_length = lh->list_length; + + *item_data_pnt = NULL; + *item_number_pnt = 0; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + /* Determine where the search will start.*/ + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + if (cur_list_key == item_key) /* Item key found.*/ + { + /* Get item info.*/ + *item_data_pnt = (void *)item->user_info; + + return(GENERIC_OK); + } + else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM2_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + (*item_number_pnt)++; + } + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListInsertItem. +| +| Description: This function allocates a node to the linked list specified +| by the handle list_handle. The position of the new item +| will be defined based on the key value. All entry are inserted +| in the list in incremental Key value. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +| **prev_item_data void Address of the user data space for the previous item. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlm2ListInsertItem(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, void ** prev_item_data_pnt, void ** prev_prev_item_data_pnt, PUINT32 insert_status_pnt ) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + LLM2_LIST_ITEM* free_item; + UINT32 free_item_pnt; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 ulPassCount = 0; + UINT32 fConditionFlag = TRUE; + + /* Set the status of the insertion.*/ + *insert_status_pnt = OCTAPI_LLM2_INSERT_ERROR; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM2_NO_STRUCTURES_LEFT); + + /* Get a free item from the free item list!*/ + free_item_pnt = ls->next_empty_item; + free_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt); + free_item->key = item_key; + ls->next_empty_item = free_item->forward_link; + + if (lh->list_length == 0) /* First item and only item:*/ + { + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + lh->head_pointer = free_item_pnt; + *insert_status_pnt = OCTAPI_LLM2_INSERT_FIRST_NODE; + + /* There is no previous node information to return.*/ + *prev_item_data_pnt = NULL; + *prev_prev_item_data_pnt = NULL; + } + else /* Insert:*/ + { + LLM2_LIST_ITEM * last_last_item = NULL; + LLM2_LIST_ITEM * last_item = NULL; + LLM2_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_key = 0xFFFFFFFF; + + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + /* Increment the pass count to determine if the addition will happen next to last.*/ + ulPassCount++; + + if (cur_list_key >= item_key) /* Item new node between the last and the curent. */ + { + if (last_list_pnt == 0xFFFFFFFF) /* Must insert at the head of the list.*/ + { + free_item->forward_link = cur_list_pnt; + lh->head_pointer = free_item_pnt; + } + else /* Standard insertion.*/ + { + free_item->forward_link = cur_list_pnt; + last_item->forward_link = free_item_pnt; + } + + /* Check if the entry was made before the last one.*/ + if ( ulPassCount == lh->list_length ) + *insert_status_pnt = OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE; + else + *insert_status_pnt = OCTAPI_LLM2_INSERT_LIST_NODE; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found, must insert at the end.*/ + { + free_item->forward_link = 0xFFFFFFFF; + item->forward_link = free_item_pnt; + lh->tail_pointer = free_item_pnt; + + *insert_status_pnt = OCTAPI_LLM2_INSERT_LAST_NODE; + + fConditionFlag = FALSE; + break; + } + else /* Item was not found, but continue searching.*/ + { + last_last_item = last_item; + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + } + + /* Return the previous node if possible.*/ + if ( *insert_status_pnt == OCTAPI_LLM2_INSERT_LIST_NODE || + *insert_status_pnt == OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE ) + { + if ( last_item != NULL ) + *prev_item_data_pnt = (void *)last_item->user_info; + + if ( last_last_item != NULL ) + *prev_prev_item_data_pnt = (void *)last_last_item->user_info; + else + *prev_prev_item_data_pnt = NULL; + } + else + { + *prev_item_data_pnt = (void *)item->user_info; + + if ( ( last_last_item != NULL ) && ( last_item != NULL ) ) + *prev_prev_item_data_pnt = (void *)last_item->user_info; + else + *prev_prev_item_data_pnt = NULL; + } + } + + /* Increase the list length.*/ + lh->list_length++; + ls->assigned_items++; + *item_data_pnt = (void *)free_item->user_info; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListRemoveItem. +| +| Description: This function deallocates a node of the linked list specified +| by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| item_key UINT32 The key of the item to be removed. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 OctApiLlm2ListRemoveItem(void * l,UINT32 list_handle,UINT32 item_key, PUINT32 prev_item_key_pnt, PUINT32 prev_prev_item_key_pnt, PUINT32 remove_status_pnt ) +{ + LLM2_LIST* ls; + LLM2_LIST_ITEM* freed_item = NULL; + LLM2_LIST_HEAD* lh; + UINT32 freed_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + UINT32 ulPassCount = 0; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + /* Set the status of the removal to error as a default value.*/ + *remove_status_pnt = OCTAPI_LLM2_REMOVE_ERROR; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + if (lh->list_length == 1)/* First item and only item if he matches.*/ + { + freed_item_pnt = lh->head_pointer; + freed_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + if ( freed_item->key == item_key ) + { + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + } + else + return(OCTAPI_LLM2_INTERNAL_ERROR1); + + /* Indicate that there was no node prior to the one removed.*/ + *prev_item_key_pnt = 0xFFFFFFFF; + *prev_prev_item_key_pnt = 0xFFFFFFFF; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE; + } + else /* Discard non-first item! (Caution: this could be the last item!)*/ + { + LLM2_LIST_ITEM * last_last_item = NULL; + LLM2_LIST_ITEM * last_item = NULL; + LLM2_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_key; + + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while( fConditionFlag == TRUE ) + { + ulPassCount++; + if (cur_list_key == item_key) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) /* First item in the list.*/ + { + lh->head_pointer = item->forward_link; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE; + } + else if ( item->forward_link == 0xFFFFFFFF) /* Last item of the list.*/ + { + last_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = last_list_pnt; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_LAST_NODE; + } + else + { + last_item->forward_link = item->forward_link; + + if ( ulPassCount == ( lh->list_length - 1 ) ) + *remove_status_pnt = OCTAPI_LLM2_REMOVE_BEFORE_LAST_NODE; + else + *remove_status_pnt = OCTAPI_LLM2_REMOVE_LIST_NODE; + } + + freed_item_pnt = cur_list_pnt; + freed_item = item; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM2_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_last_item = last_item; + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + } + + /* Return the key of the node before the node removed if possible.*/ + if ( last_list_pnt == 0xFFFFFFFF ) + *prev_item_key_pnt = 0xFFFFFFFF; + else if ( last_item != NULL ) + *prev_item_key_pnt = last_item->key; + + /* Return the key of the node before before the node removed if possible.*/ + if ( last_last_item == NULL ) + *prev_prev_item_key_pnt = 0xFFFFFFFF; + else + *prev_prev_item_key_pnt = last_last_item->key; + + } + + /* Decrease the list length.*/ + lh->list_length--; + ls->assigned_items--; + + /* Return free block to free block list:*/ + freed_item->forward_link = ls->next_empty_item; + ls->next_empty_item = freed_item_pnt; + + return(GENERIC_OK); +} + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmMemCpy. +| +| Description: This function copies data from a source to a destination. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *f_pvDestination VOID The destination where to copy the data. +| *f_pvSource VOID The source where to copy the data from. +| f_ulSize UINT32 The number of bytes to copy. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +VOID * OctApiLlmMemCpy( VOID *f_pvDestination, const VOID * f_pvSource, UINT32 f_ulSize ) +{ + CHAR * pbyDst; + const CHAR * pbySrc; + UINT32 * f_pulAlignedDst; + const UINT32 * f_pulAlignedSrc; + + pbyDst = (CHAR *)f_pvDestination; + pbySrc = (const CHAR *)f_pvSource; + + /* + * If the size is small, or either SRC or DST is unaligned, + * then punt into the byte copy loop. This should be rare. + */ + if ( ( f_ulSize < sizeof(UINT32) ) + || ( ( (UINT32)( pbySrc ) & ( sizeof(UINT32) - 1 ) ) | ( (UINT32)( pbyDst ) & ( sizeof(UINT32) - 1 ) ) ) ) + { + while ( f_ulSize-- ) + *pbyDst++ = *pbySrc++; + return f_pvDestination; + } + + f_pulAlignedDst = (UINT32 *)pbyDst; + f_pulAlignedSrc = (const UINT32 *)pbySrc; + + /* Copy 4X long words at a time if possible. */ + while ( f_ulSize >= 4 * sizeof(UINT32) ) + { + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + f_ulSize -= 4 * sizeof(UINT32); + } + + /* Copy one long word at a time if possible. */ + while ( f_ulSize >= sizeof(UINT32) ) + { + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + f_ulSize -= sizeof(UINT32); + } + + /* Pick up any residual with a byte copier. */ + pbyDst = (CHAR *)f_pulAlignedDst; + pbySrc = (const CHAR *)f_pulAlignedSrc; + while ( f_ulSize-- ) + *pbyDst++ = *pbySrc++; + + return f_pvDestination; +} + +/**************************************** llm_list section **********************************************/ + -- cgit v1.2.3