/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ File: octapi_llman.c Copyright (c) 2001-2011 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.04.05 $ $Octasic_Revision: 22 $ \*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #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) ) || ( ( (unsigned long)( pbySrc ) & ( sizeof(UINT32) - 1 ) ) | ( (unsigned long)( 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 **********************************************/