589 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			589 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#include "list.h"
							 | 
						|||
| 
								 | 
							
								#include "stdlib.h"
							 | 
						|||
| 
								 | 
							
								#include "string.h"
							 | 
						|||
| 
								 | 
							
								#include "stdio.h"
							 | 
						|||
| 
								 | 
							
								#include "board.h"
							 | 
						|||
| 
								 | 
							
								#include "mystdlib.h"
							 | 
						|||
| 
								 | 
							
								#include "debug.h"
							 | 
						|||
| 
								 | 
							
								#include "bytearray.h"
							 | 
						|||
| 
								 | 
							
								#include "rtthread.h"
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#define LIST_APPEND_SKIP  10
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								typedef struct{
							 | 
						|||
| 
								 | 
							
								  int32_t next;
							 | 
						|||
| 
								 | 
							
								  int32_t prev;
							 | 
						|||
| 
								 | 
							
								  uint32_t data[0];
							 | 
						|||
| 
								 | 
							
								}list_node_def;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								struct _list_def{
							 | 
						|||
| 
								 | 
							
								  int32_t all;
							 | 
						|||
| 
								 | 
							
								  int32_t used;
							 | 
						|||
| 
								 | 
							
								  int32_t block_size;
							 | 
						|||
| 
								 | 
							
								  int32_t block_size4;
							 | 
						|||
| 
								 | 
							
								  rt_mutex_t mutex;
							 | 
						|||
| 
								 | 
							
								  int32_t head;
							 | 
						|||
| 
								 | 
							
								  int32_t tail;
							 | 
						|||
| 
								 | 
							
								  sub_fun_def sub;
							 | 
						|||
| 
								 | 
							
								  del_fun_def del;
							 | 
						|||
| 
								 | 
							
								  str_fun_def str;
							 | 
						|||
| 
								 | 
							
								  uint32_t data[0];
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								//#define list_enter_mutex(l)\
							 | 
						|||
| 
								 | 
							
								//      rt_mutex_take((l)->mutex,RT_WAITING_FOREVER)
							 | 
						|||
| 
								 | 
							
								//      
							 | 
						|||
| 
								 | 
							
								//#define list_exit_mutex(l)\
							 | 
						|||
| 
								 | 
							
								//      rt_mutex_release((l)->mutex)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#define list_enter_mutex(l)
							 | 
						|||
| 
								 | 
							
								#define list_exit_mutex(l)
							 | 
						|||
| 
								 | 
							
								#define rt_mutex_create(...) 0
							 | 
						|||
| 
								 | 
							
								#define rt_mutex_delete(l)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								list_def *list_creat(int block_size,sub_fun_def sub,del_fun_def del,str_fun_def str)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  static uint16_t count=0;
							 | 
						|||
| 
								 | 
							
									char s1[16]={0};
							 | 
						|||
| 
								 | 
							
									sprintf(s1,"list_mut#%d",count);
							 | 
						|||
| 
								 | 
							
								  int size=0;
							 | 
						|||
| 
								 | 
							
								  int block_size4;
							 | 
						|||
| 
								 | 
							
								  list_def *l;
							 | 
						|||
| 
								 | 
							
								  size+=sizeof(list_def);
							 | 
						|||
| 
								 | 
							
								  // 4字节对齐
							 | 
						|||
| 
								 | 
							
								  block_size4=((block_size+3)/4)*4;
							 | 
						|||
| 
								 | 
							
								  size+=(sizeof(list_node_def)+block_size4)*LIST_APPEND_SKIP;
							 | 
						|||
| 
								 | 
							
								  l=malloc(size);
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  l->all=LIST_APPEND_SKIP;
							 | 
						|||
| 
								 | 
							
								  l->used=0;
							 | 
						|||
| 
								 | 
							
								  l->block_size=block_size;
							 | 
						|||
| 
								 | 
							
								  l->block_size4=block_size4;
							 | 
						|||
| 
								 | 
							
								  l->mutex=rt_mutex_create(s1,RT_IPC_FLAG_FIFO);
							 | 
						|||
| 
								 | 
							
								  l->head=-1;
							 | 
						|||
| 
								 | 
							
								  l->tail=-1;
							 | 
						|||
| 
								 | 
							
								  l->sub=sub;
							 | 
						|||
| 
								 | 
							
								  l->del=del;
							 | 
						|||
| 
								 | 
							
								  l->str=str;
							 | 
						|||
| 
								 | 
							
								  
							 | 
						|||
| 
								 | 
							
								  // 初始化列表
							 | 
						|||
| 
								 | 
							
								  list_node_def *node;
							 | 
						|||
| 
								 | 
							
								  node=(list_node_def *)l->data;
							 | 
						|||
| 
								 | 
							
								  for(int i=0;i<l->all;i++)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    node->next=-1;
							 | 
						|||
| 
								 | 
							
								    node->prev=-1;
							 | 
						|||
| 
								 | 
							
								    node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  count++;
							 | 
						|||
| 
								 | 
							
								  return l;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 对于数据里有指针数据的成员,需要提供del函数
							 | 
						|||
| 
								 | 
							
								void _list_delete(list_def **l)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  param_check(*l);
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(*l);
							 | 
						|||
| 
								 | 
							
								  if((*l)->del)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    for(int i=0;i<(*l)->used;i++)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								      (*l)->del(list_get(*l,i));
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_exit_mutex(*l);
							 | 
						|||
| 
								 | 
							
								  rt_mutex_delete((*l)->mutex);
							 | 
						|||
| 
								 | 
							
								  free(*l);
							 | 
						|||
| 
								 | 
							
								  *l=0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								int list_block_size4(list_def *l)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  return l->block_size4;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								//static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte)
							 | 
						|||
| 
								 | 
							
								//{
							 | 
						|||
| 
								 | 
							
								//  for(int i=0;i<num_4byte;i++)
							 | 
						|||
| 
								 | 
							
								//  {
							 | 
						|||
| 
								 | 
							
								//    dst[i]=src[i];
							 | 
						|||
| 
								 | 
							
								//  }
							 | 
						|||
| 
								 | 
							
								//}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								static list_def *list_expend(list_def *l)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  int size=0;
							 | 
						|||
| 
								 | 
							
								  int cpysize=0;
							 | 
						|||
| 
								 | 
							
								  list_def *r;
							 | 
						|||
| 
								 | 
							
								  size+=sizeof(list_def);
							 | 
						|||
| 
								 | 
							
								  size+=(sizeof(list_node_def)+l->block_size4)*(l->all);
							 | 
						|||
| 
								 | 
							
								  cpysize=size;
							 | 
						|||
| 
								 | 
							
								  size+=(sizeof(list_node_def)+l->block_size4)*(LIST_APPEND_SKIP);
							 | 
						|||
| 
								 | 
							
								  r=malloc(size);
							 | 
						|||
| 
								 | 
							
								  param_check(r);
							 | 
						|||
| 
								 | 
							
								  cpy4byte((uint32_t *)r,(uint32_t *)l,cpysize/4);
							 | 
						|||
| 
								 | 
							
								  // 初始化列表
							 | 
						|||
| 
								 | 
							
								  list_node_def *node;
							 | 
						|||
| 
								 | 
							
								  node=(list_node_def *)((uint32_t)r->data+r->all*(sizeof(list_node_def)+r->block_size4));
							 | 
						|||
| 
								 | 
							
								  for(int i=0;i<LIST_APPEND_SKIP;i++)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    node->next=-1;
							 | 
						|||
| 
								 | 
							
								    node->prev=-1;
							 | 
						|||
| 
								 | 
							
								    node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+r->block_size4);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  r->all+=LIST_APPEND_SKIP;
							 | 
						|||
| 
								 | 
							
								  free(l);
							 | 
						|||
| 
								 | 
							
								  return r;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 查找一个未使用的节点
							 | 
						|||
| 
								 | 
							
								static list_node_def *list_unused_node(list_def *l,int *index)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  list_node_def *node=0;
							 | 
						|||
| 
								 | 
							
								  node=(list_node_def *)l->data;
							 | 
						|||
| 
								 | 
							
								  for(int i=0;i<l->all;i++)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    if((node->next==-1)&&(node->prev==-1)){
							 | 
						|||
| 
								 | 
							
								      if(index) *index=i;
							 | 
						|||
| 
								 | 
							
								      return node;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  return node;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 取得指定序号的节点
							 | 
						|||
| 
								 | 
							
								static list_node_def *list_node(list_def *l,int index)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  list_node_def *node;
							 | 
						|||
| 
								 | 
							
								  param_check(index>=0&&index<l->all);
							 | 
						|||
| 
								 | 
							
								  node=(list_node_def *)((uint32_t)l->data+index*(sizeof(list_node_def)+l->block_size4));
							 | 
						|||
| 
								 | 
							
								  return node;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 取得节点的物理索引
							 | 
						|||
| 
								 | 
							
								static int list_phy_index(list_def *l,list_node_def *n)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  return ((uint32_t)n-(uint32_t)l->data)/(sizeof(list_node_def)+l->block_size4);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/*
							 | 
						|||
| 
								 | 
							
								// 改为统一使用insert函数
							 | 
						|||
| 
								 | 
							
								list_def *list_append(list_def **l,void *data)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  param_check(*l);
							 | 
						|||
| 
								 | 
							
								  list_def *r=*l;
							 | 
						|||
| 
								 | 
							
								  if((*l)->used>=(*l)->all)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    r=list_expend(*l);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_node_def *node;
							 | 
						|||
| 
								 | 
							
								  int index;
							 | 
						|||
| 
								 | 
							
								  node=list_unused_node(r,&index);
							 | 
						|||
| 
								 | 
							
								  param_check(node);
							 | 
						|||
| 
								 | 
							
								  memcpy(node->data,data,r->block_size);
							 | 
						|||
| 
								 | 
							
								  if(r->head==-1&&r->tail==-1)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    r->head=index;
							 | 
						|||
| 
								 | 
							
								    r->tail=index;
							 | 
						|||
| 
								 | 
							
								    node->next=index;
							 | 
						|||
| 
								 | 
							
								    node->prev=index;
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  else if(r->head!=-1&&r->tail!=-1)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    node->prev=r->tail;
							 | 
						|||
| 
								 | 
							
								    node->next=list_node(r,r->tail)->next;
							 | 
						|||
| 
								 | 
							
								    list_node(r,r->tail)->next=index;
							 | 
						|||
| 
								 | 
							
								    r->tail=index;
							 | 
						|||
| 
								 | 
							
								    list_node(r,r->head)->prev=index;
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  else
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    param_check(0);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  r->used++;
							 | 
						|||
| 
								 | 
							
								  *l=r;
							 | 
						|||
| 
								 | 
							
								  return r;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								*/
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 返回指定index的已使用节点
							 | 
						|||
| 
								 | 
							
								static list_node_def *list_used_node(list_def *l,int index)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  list_node_def *node=0;
							 | 
						|||
| 
								 | 
							
								  if(index>l->used/2)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    index=l->used-1-index;
							 | 
						|||
| 
								 | 
							
								    node=list_node(l,l->tail);
							 | 
						|||
| 
								 | 
							
								    for(int i=0;i<index;i++)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								      node=list_node(l,node->prev);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  else{
							 | 
						|||
| 
								 | 
							
								    node=list_node(l,l->head);
							 | 
						|||
| 
								 | 
							
								    for(int i=0;i<index;i++)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								      node=list_node(l,node->next);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  return node;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 获取第index项数据,不删除
							 | 
						|||
| 
								 | 
							
								// index支持负数,-1表示最后一项
							 | 
						|||
| 
								 | 
							
								// 返回数据引用
							 | 
						|||
| 
								 | 
							
								void *list_get(list_def *l,int index)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  void *ret=0;
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(l);
							 | 
						|||
| 
								 | 
							
								  list_node_def *node;
							 | 
						|||
| 
								 | 
							
								  if(index<0) index=l->used+index;
							 | 
						|||
| 
								 | 
							
								  if((index>=0&&index<l->used)==0)
							 | 
						|||
| 
								 | 
							
								    ret=0;
							 | 
						|||
| 
								 | 
							
								  else{
							 | 
						|||
| 
								 | 
							
								    node=list_used_node(l,index);
							 | 
						|||
| 
								 | 
							
								    param_check(node);
							 | 
						|||
| 
								 | 
							
								    ret=node->data;
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_exit_mutex(l);
							 | 
						|||
| 
								 | 
							
								  return ret;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 删除第index项数据
							 | 
						|||
| 
								 | 
							
								// index支持负数,-1表示最后一项
							 | 
						|||
| 
								 | 
							
								void list_remove(list_def *l,int index)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  list_node_def *node;
							 | 
						|||
| 
								 | 
							
								  int phy_index;
							 | 
						|||
| 
								 | 
							
								  if(index<0) index=l->used+index;
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(l);
							 | 
						|||
| 
								 | 
							
								  if((index>=0&&index<l->used)){
							 | 
						|||
| 
								 | 
							
								    node=list_used_node(l,index);
							 | 
						|||
| 
								 | 
							
								    param_check(node);
							 | 
						|||
| 
								 | 
							
								    phy_index=list_phy_index(l,node);
							 | 
						|||
| 
								 | 
							
								    if(l->used==1)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								      l->head=-1;
							 | 
						|||
| 
								 | 
							
								      l->tail=-1;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    else
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								      if(l->head==phy_index)
							 | 
						|||
| 
								 | 
							
								      {
							 | 
						|||
| 
								 | 
							
								        l->head=node->next;
							 | 
						|||
| 
								 | 
							
								      }
							 | 
						|||
| 
								 | 
							
								      if(l->tail==phy_index)
							 | 
						|||
| 
								 | 
							
								      {
							 | 
						|||
| 
								 | 
							
								        l->tail=node->prev;
							 | 
						|||
| 
								 | 
							
								      }
							 | 
						|||
| 
								 | 
							
								      list_node(l,node->prev)->next=node->next;
							 | 
						|||
| 
								 | 
							
								      list_node(l,node->next)->prev=node->prev;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    node->next=-1;
							 | 
						|||
| 
								 | 
							
								    node->prev=-1;
							 | 
						|||
| 
								 | 
							
								    if(l->del) l->del(node->data);
							 | 
						|||
| 
								 | 
							
								    l->used--;
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(l);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 获取指定index的数据,随后删除
							 | 
						|||
| 
								 | 
							
								// 返回数据的临时指针
							 | 
						|||
| 
								 | 
							
								// 对于存在动态指针的对象,由于take之后会自动删除,take操作会出现野指针
							 | 
						|||
| 
								 | 
							
								// 建议使用list_get + list_remove的方式代替list_take
							 | 
						|||
| 
								 | 
							
								void *list_take(list_def *l,int index)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  void *p;
							 | 
						|||
| 
								 | 
							
								  p=list_get(l,index);
							 | 
						|||
| 
								 | 
							
								  void *t=tmalloc(l->block_size);
							 | 
						|||
| 
								 | 
							
								  param_check(t);
							 | 
						|||
| 
								 | 
							
								  memcpy(t,p,l->block_size);
							 | 
						|||
| 
								 | 
							
								  list_remove(l,index);
							 | 
						|||
| 
								 | 
							
								  return t;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 清空
							 | 
						|||
| 
								 | 
							
								void list_clear(list_def *l)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(l);
							 | 
						|||
| 
								 | 
							
								  while(l->used>0)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    list_remove(l,0);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_exit_mutex(l);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								int list_length(list_def *l)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  return l->used;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 在指定位置插入
							 | 
						|||
| 
								 | 
							
								// index为节点插入之后所在的位置
							 | 
						|||
| 
								 | 
							
								list_def *_list_insert(list_def **l,void *data,int index)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  param_check(*l);
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(*l);
							 | 
						|||
| 
								 | 
							
								  if(index<0) index=(*l)->used+index+1;
							 | 
						|||
| 
								 | 
							
								  if((index>=0&&index<=(*l)->used)==0){
							 | 
						|||
| 
								 | 
							
								    list_exit_mutex(*l);
							 | 
						|||
| 
								 | 
							
								    return *l;
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_def *r=*l;
							 | 
						|||
| 
								 | 
							
								  if((*l)->used>=(*l)->all)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    r=list_expend(*l);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_node_def *node;
							 | 
						|||
| 
								 | 
							
								  int phy_index;
							 | 
						|||
| 
								 | 
							
								  node=list_unused_node(r,&phy_index);
							 | 
						|||
| 
								 | 
							
								  param_check(node);
							 | 
						|||
| 
								 | 
							
								  memcpy(node->data,data,r->block_size);
							 | 
						|||
| 
								 | 
							
								  if(r->head==-1&&r->tail==-1)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    r->head=phy_index;
							 | 
						|||
| 
								 | 
							
								    r->tail=phy_index;
							 | 
						|||
| 
								 | 
							
								    node->next=phy_index;
							 | 
						|||
| 
								 | 
							
								    node->prev=phy_index;
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  else if(r->head!=-1&&r->tail!=-1)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    list_node_def *n;
							 | 
						|||
| 
								 | 
							
								    int n_phy_index;
							 | 
						|||
| 
								 | 
							
								    if(index<r->used)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								      n=list_used_node(r,index);
							 | 
						|||
| 
								 | 
							
								      n_phy_index=list_phy_index(r,n);
							 | 
						|||
| 
								 | 
							
								      list_node(r,n->prev)->next=phy_index;
							 | 
						|||
| 
								 | 
							
								      node->prev=n->prev;
							 | 
						|||
| 
								 | 
							
								      node->next=n_phy_index;
							 | 
						|||
| 
								 | 
							
								      n->prev=phy_index;
							 | 
						|||
| 
								 | 
							
								      if(index==0)
							 | 
						|||
| 
								 | 
							
								      {
							 | 
						|||
| 
								 | 
							
								        r->head=phy_index;
							 | 
						|||
| 
								 | 
							
								      }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    else
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								      node->prev=r->tail;
							 | 
						|||
| 
								 | 
							
								      node->next=list_node(r,r->tail)->next;
							 | 
						|||
| 
								 | 
							
								      list_node(r,r->tail)->next=phy_index;
							 | 
						|||
| 
								 | 
							
								      r->tail=index;
							 | 
						|||
| 
								 | 
							
								      list_node(r,r->head)->prev=phy_index;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  else
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    param_check(0);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  r->used++;
							 | 
						|||
| 
								 | 
							
								  *l=r;
							 | 
						|||
| 
								 | 
							
								  list_exit_mutex(*l);
							 | 
						|||
| 
								 | 
							
								  return r;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								void list_sort(list_def *l)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(l);
							 | 
						|||
| 
								 | 
							
								  if(l->sub){
							 | 
						|||
| 
								 | 
							
								    _list_sort(l,l->sub);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  else{
							 | 
						|||
| 
								 | 
							
								    DBG_WARN("obj->sub fun is null.");
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_exit_mutex(l);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 在列表内返回1,不在返回0
							 | 
						|||
| 
								 | 
							
								int list_contains(list_def *l,void *d)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(l);
							 | 
						|||
| 
								 | 
							
								  if(l->sub)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    for(int i=0;i<list_length(l);i++)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								      if(l->sub(list_get(l,i),d)==0){
							 | 
						|||
| 
								 | 
							
								        list_exit_mutex(l);
							 | 
						|||
| 
								 | 
							
								        return 1;
							 | 
						|||
| 
								 | 
							
								      }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  else{
							 | 
						|||
| 
								 | 
							
								    DBG_WARN("obj->sub fun is null.");
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_exit_mutex(l);
							 | 
						|||
| 
								 | 
							
								  return 0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 交换两个位置
							 | 
						|||
| 
								 | 
							
								void list_swap(list_def *l,int index_a,int index_b)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(l);
							 | 
						|||
| 
								 | 
							
								  void *a_=list_get(l,index_a);
							 | 
						|||
| 
								 | 
							
								  void *b_=list_get(l,index_b);
							 | 
						|||
| 
								 | 
							
								  void *t_=0;
							 | 
						|||
| 
								 | 
							
								  if(a_&&b_)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    t_=calloc(1,sizeof(l->block_size4));
							 | 
						|||
| 
								 | 
							
								    cpy4byte(t_,a_,l->block_size4/4);
							 | 
						|||
| 
								 | 
							
								    cpy4byte(a_,b_,l->block_size4/4);
							 | 
						|||
| 
								 | 
							
								    cpy4byte(b_,t_,l->block_size4/4);
							 | 
						|||
| 
								 | 
							
								    free(t_);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_exit_mutex(l);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 向后循环移动
							 | 
						|||
| 
								 | 
							
								void list_shift(list_def *l)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(l);
							 | 
						|||
| 
								 | 
							
								  if(l->used>0){
							 | 
						|||
| 
								 | 
							
								    l->head=list_node(l,l->head)->next;
							 | 
						|||
| 
								 | 
							
								    l->tail=list_node(l,l->tail)->next;
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  list_exit_mutex(l);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 输出打印字符串
							 | 
						|||
| 
								 | 
							
								char *list_string(list_def *l)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  param_check(l);
							 | 
						|||
| 
								 | 
							
								  list_enter_mutex(l);
							 | 
						|||
| 
								 | 
							
								  array_def *d=arr_creat();
							 | 
						|||
| 
								 | 
							
								  param_check(d);
							 | 
						|||
| 
								 | 
							
								  int len=0;
							 | 
						|||
| 
								 | 
							
								  char *s=0;
							 | 
						|||
| 
								 | 
							
								  arr_append(d,'(');
							 | 
						|||
| 
								 | 
							
								  if(l->str)
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    for(int i=0;i<list_length(l);i++)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								      s=l->str(list_get(l,i));
							 | 
						|||
| 
								 | 
							
								      len=strlen(s);
							 | 
						|||
| 
								 | 
							
								      arr_appends(d,s,len);
							 | 
						|||
| 
								 | 
							
								      free(s);
							 | 
						|||
| 
								 | 
							
								      arr_append(d,',');
							 | 
						|||
| 
								 | 
							
								      arr_append(d,' ');
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  arr_append(d,')');
							 | 
						|||
| 
								 | 
							
								  len=arr_length(d);
							 | 
						|||
| 
								 | 
							
								  s=malloc(len+1);
							 | 
						|||
| 
								 | 
							
								  param_check(s);
							 | 
						|||
| 
								 | 
							
								  memcpy(s,arr_data(d),len);
							 | 
						|||
| 
								 | 
							
								  arr_delete(d);
							 | 
						|||
| 
								 | 
							
								  s[len]=0;
							 | 
						|||
| 
								 | 
							
								  list_exit_mutex(l);
							 | 
						|||
| 
								 | 
							
								  return s;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// int sub函数
							 | 
						|||
| 
								 | 
							
								int _list_int_sub(void *a,void *b)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  return *(int *)a-*(int *)b;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// int 打印函数
							 | 
						|||
| 
								 | 
							
								char *_list_int_str(void *a)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  char *s=malloc(20);
							 | 
						|||
| 
								 | 
							
								  param_check(s);
							 | 
						|||
| 
								 | 
							
								  sprintf(s,"%d",*(int *)a);
							 | 
						|||
| 
								 | 
							
								  return s;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// str sub函数
							 | 
						|||
| 
								 | 
							
								int _list_str_sub(void *a,void *b)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  char *a_=*(char **)a;
							 | 
						|||
| 
								 | 
							
								  char *b_=*(char **)b;
							 | 
						|||
| 
								 | 
							
								  return strcmp(a_,b_);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// str删除函数
							 | 
						|||
| 
								 | 
							
								int _list_str_del(void *d)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  char **c=d;
							 | 
						|||
| 
								 | 
							
								  if(*c) free(*c);
							 | 
						|||
| 
								 | 
							
								  return 0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// str 打印函数
							 | 
						|||
| 
								 | 
							
								char *_list_str_str(void *a)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  char *a_=*(char **)a;
							 | 
						|||
| 
								 | 
							
								  int len=strlen(a_);
							 | 
						|||
| 
								 | 
							
								  char *s=malloc(len+1);
							 | 
						|||
| 
								 | 
							
								  param_check(s);
							 | 
						|||
| 
								 | 
							
								  memcpy(s,a_,len+1);
							 | 
						|||
| 
								 | 
							
								  return s;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 延迟删除,不需要修改指针
							 | 
						|||
| 
								 | 
							
								void _list_delete_later(list_def *l)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  _list_delete(&l);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 |