static void* do_alloc_large(size_t len) { node_t** ppn = &heap->index[MEM_SIZ_LARGE]; ALIGN4096(len); void* mem = sys_alloc(NULL, len); while (*ppn) { if ((*ppn)->next && ((*ppn)->next->addr > mem)) { node_t* tmp = get_free_node(); tmp->next = (*ppn)->next; tmp->addr = mem; tmp->len = len; tmp->stat = MEM_STAT_USED; (*ppn)->next = tmp; return mem; } ppn = &(*ppn)->next; } *ppn = get_free_node(); (*ppn)->addr = mem; (*ppn)->len = len; (*ppn)->next = NULL; (*ppn)->stat = MEM_STAT_USED; return mem; }
int split_insert (PBTREE btree, int node_idx, PBTREE_ELEMENT element) { int i; int split_point; int new_node_idx; BTREE_ELEMENT upward_element; // split_insert should only be called if node is full if (btree->nodes[node_idx].element_count != BTREE_MAX_ELEMENTS-1) return 0; vector_insert_for_split (btree, node_idx, element); split_point = btree->nodes[node_idx].element_count/2; if (2*split_point < btree->nodes[node_idx].element_count) // perform the "ceiling function" split_point++; // new node receives the rightmost half of elements in *this node new_node_idx = get_free_node(btree); if (!BTREE_IS_VALID_NODE_IDX(new_node_idx)) return 0; memcpy(&upward_element, &btree->nodes[node_idx].elements[split_point], sizeof(BTREE_ELEMENT)); insert_zeroth_subtree (btree, new_node_idx, upward_element.subtree_node_idx); upward_element.subtree_node_idx = new_node_idx; // element that gets added to the parent of this node for (i=1; i<btree->nodes[node_idx].element_count-split_point; i++) vector_insert(btree, new_node_idx, &btree->nodes[node_idx].elements[split_point+i]); btree->nodes[new_node_idx].element_count = btree->nodes[node_idx].element_count-split_point; btree->nodes[node_idx].element_count = split_point; btree->nodes[new_node_idx].parent_node_idx = btree->nodes[node_idx].parent_node_idx; // now insert the new node into the parent, splitting it if necessary if (BTREE_IS_VALID_NODE_IDX(btree->nodes[node_idx].parent_node_idx) && vector_insert(btree, btree->nodes[node_idx].parent_node_idx, &upward_element)) return 1; else if (BTREE_IS_VALID_NODE_IDX(btree->nodes[node_idx].parent_node_idx) && split_insert(btree, btree->nodes[node_idx].parent_node_idx, &upward_element)) return 1; else if (!BTREE_IS_VALID_NODE_IDX(btree->nodes[node_idx].parent_node_idx)) { // this node was the root int new_root = get_free_node(btree); insert_zeroth_subtree(btree, new_root, node_idx); btree->nodes[node_idx].parent_node_idx = new_root; btree->nodes[new_node_idx].parent_node_idx = new_root; vector_insert (btree, new_root, &upward_element); btree->root_node_idx = new_root; btree->nodes[new_root].parent_node_idx = BTREE_INVALID_NODE_IDX; } return 1; }
/*------------------------------------------------------------ 函数原型: int ndis_tty_write(struct tty_struct * tty, int from_user, const unsigned char * buf, int count) 描述: ndis_tty_write函数是ndistty驱动所定义的tty驱动的最重要的操作 方法之一。当用户进程用open方法打开设备文件结点时,tty核心 会调用我们注册的tty驱动的方法集中的 ndis_tty_write 函数,来 完成把用户空间的数据传入内核。在ndis_tty_write中会把用户输入 的消息包装成为了一个NDIS消息,然后向USB底层发送。 输入: struct tty_struct * tty 系统传入的指向tty_struct的指针 int from_user 指示操作是在用户空间还是在内核空间。 const unsigned char * buf 指向用户空间的输入数据缓冲区。 int count 要输入的数据字节数。 输出: 无 返回值: 在USB底层成功传输的字节数减去NDIS消息头的长度。 -------------------------------------------------------------*/ static int ndis_tty_write(struct tty_struct * tty, const unsigned char * buf, int count) { int ret = 0; unsigned short num = 0; int nMsgLen = 0; PNDIS_NODE pNode = NULL; /*printk(KERN_ALERT "ndis_tty_write is running\n");*/ /* < DTS2011011305021: gkf34687 2011-03-02 DEL>*/ num = tty->index; pNode = get_free_node(); if (NULL == pNode) { printk("%s-can not get free node, no mem here !!\n", __FUNCTION__); return -ENOMEM; } if (0 == connect_stat) { return_node_to_free(pNode); return -ENODEV; } memcpy((MEG_ROW(pNode->row_num)), buf, count); nMsgLen = ((unsigned short)((unsigned int)count - 1)); //printk("%s - count = %d\n", __FUNCTION__, nMsgLen + 1); ret = write_control_ndis_msg(pNode, nMsgLen + 1); return ret; }
/*------------------------------------------------------------ 函数原型: void handle_response_available(void) 描述: handle_response_available是进行NDIS消息解析处理的关键函数, 在中断通道返馈有命令通告后,handle_response_available发 起从USB控制通道读入NDIS消息返馈。在成功读取了消息返馈以 后,根据消息返馈中的Client Id,进行判别消息该进行那种处 理方式。目前,本工程中采用的算法时:广播消息转入广播处理; Client Id为0则转入CTL类消息处理;是WDS Client Id的把消息 体送入WDS用户进程空间;是其他用户进程的Client Id则把消息 送入其他用户进程空间。 输入: 无。 输出: 根据不同的Client Id转入不同的处理中。 返回值: 无。 -------------------------------------------------------------*/ static void handle_response_available(void) { PNDIS_NODE pNode = NULL; /* <DTS2013010602637 implement haisi NDIS ipv6 dial up and improve ndis dialup z00185914 20130106 BEGIN */ int i = 0; //printk("%s-handle %d response msg !!\n", __FUNCTION__, i); do { pNode = get_free_node(); if (NULL == pNode) { printk("%s-can not get free node, no mem here !!\n", __FUNCTION__); return; } /* < DTS2013011706280 improve NDIS dial up slowly z00185914 20130119 BEGIN */ if (read_control_ndis_msg(pNode, MSG_COLUMN) < MSG_COLUMN)// all read out /* DTS2013011706280 improve NDIS dial up slowly z00185914 20130119 END> */ { break; } i++; } while(1); if (i > 1)printk("%s-handle %d response msg !!\n", __FUNCTION__, i); NDIS_DEBUG_MSG("%s-handle %d response msg !!\n", __FUNCTION__, i); /* DTS2013010602637 implement haisi NDIS ipv6 dial up and improve ndis dialup z00185914 20130106 END> */ }
int relayer_addjob(int fd1, int fd2, int flags) { int ret; pthread_once(&once_control, relayer_init); if (init_ret != 0) return E_REL_INIT; if ((ret = get_free_node()) == -1) return E_REL_FULL; add_job_to_arr(fd1, fd2, ret); pthread_kill(relayer_pthd, SIGPOLL); return ret; }
static void expand_heap(size_t i) { void* mem = sys_alloc(NULL, 4096); node_t** ppn = &heap->index[i]; while (*ppn) { if ((*ppn)->addr > mem) { break; } ppn = &(*ppn)->next; } node_t* tmp = get_free_node(); tmp->addr = mem; tmp->len = 4096; tmp->next = *ppn; tmp->stat = MEM_STAT_FREE; *ppn = tmp; }
/***************************************************************************** 函 数 名 : clean_dummy_msg 功能描述 : 清理控制端点中无效的消息 输入参数 : void 输出参数 : 无 返 回 值 : static void 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2012年6月7日 作 者 : w00211169 修改内容 : 新生成函数 *****************************************************************************/ static void clean_dummy_msg(void) { PNDIS_NODE pNode = NULL; int i = 0; for (i = 0; i <20; i++) { pNode = get_free_node(); if (NULL == pNode) { printk("%s-can not get free node, no mem here !!\n", __FUNCTION__); return; } if (read_control_ndis_msg(pNode, MSG_COLUMN) <= 0) { break; } } NDIS_DEBUG_MSG("%s-clean %d dummy msg !!\n", __FUNCTION__, i); }
int btree_insert (PBTREE btree, PBTREE_ELEMENT element) { int last_visited_node_idx; if (!BTREE_IS_VALID_NODE_IDX(btree->root_node_idx)) { int node_idx = get_free_node(btree); if (!BTREE_IS_VALID_NODE_IDX(node_idx)) return 0; else { set_root(btree, node_idx); insert_zeroth_subtree (btree, node_idx, BTREE_INVALID_NODE_IDX); } } last_visited_node_idx = btree->root_node_idx; if (btree_search_ex(btree, &last_visited_node_idx, element->key)) // element already in tree return 0; if (vector_insert(btree, last_visited_node_idx, element)) return 1; return split_insert(btree, last_visited_node_idx, element); }
int tex_cache_getid(int imgid,int* cacheid) { KeyType key = imgid; RbtStatus status; NodeType *p; int ret = 0; if ((p = rbtFind(rb,key)) != NULL) { *cacheid = ((tex_node_p)(p->val.node))->texid; ret = 1; } else { ValType val; val.stuff = imgid; val.node = get_free_node(); key = imgid; status = rbtInsert(rb,key, val); if (status) { printf("fail: status = %d\n", status); } *cacheid = ((tex_node_p)(val.node))->texid; } return ret; }
void myfree(void* addr) { size_t i = MEM_SIZ_LARGE; node_t* prev = NULL; node_t* pn = NULL; if (addr_find(addr, &prev, &pn, &i)) { if (i != MEM_SIZ_LARGE) { node_t* free = get_free_node(); node_t* used = get_free_node(); used->len = pn->len - ((size_t)addr - (size_t)pn->addr) - indsiz[i]; pn->len = (size_t)addr - (size_t)pn->addr; used->next = pn->next; free->next = used; pn->next = free; free->addr = addr; free->len = indsiz[i]; free->stat = MEM_STAT_FREE; used->addr = (void*)((size_t)free->addr + indsiz[i]); used->stat = MEM_STAT_USED; if (pn->len == 0) { if (prev) { prev->next = pn->next; pn->next = heap->free_node; heap->free_node = pn; } else { heap->index[i] = pn->next; pn->next = heap->free_node; heap->free_node = pn; } } if (used->len == 0) { free->next = used->next; used->next = heap->free_node; heap->free_node = used; } merge(heap->index[i]); } else if(prev) { prev->next = pn->next; sys_free(pn->addr, pn->len); pn->next = heap->free_node; heap->free_node = pn; } else { heap->index[MEM_SIZ_LARGE] = pn->next; sys_free(pn->addr, pn->len); pn->next = heap->free_node; heap->free_node = pn; } } else { fprintf(stderr, "illegal free: %16zx\n", addr); } }
static void* do_alloc(size_t i) { node_t* pn = heap->index[i]; node_t* prev = NULL; while (pn) { if (pn->stat == MEM_STAT_FREE) { if (prev) { void* ret = pn->addr; node_t* newNode = get_free_node(); prev->next = newNode; newNode->addr = ret; newNode->stat = MEM_STAT_USED; newNode->len = indsiz[i]; newNode->next = pn; pn->addr = (void*)((size_t)pn->addr + indsiz[i]); pn->len -= indsiz[i]; if (pn->len == 0) { newNode->next = pn->next; pn->next = heap->free_node; heap->free_node = pn; merge(prev); } return ret; } else { node_t* tmp = get_free_node(); tmp->addr = pn->addr; tmp->len = indsiz[i]; tmp->next = pn; tmp->stat = MEM_STAT_USED; pn->addr = (void*)((size_t)pn->addr + indsiz[i]); pn->len -= indsiz[i]; heap->index[i] = tmp; if (pn->len == 0) { tmp->next = pn->next; pn->next = heap->free_node; heap->free_node = pn; merge(tmp); } return tmp->addr; } } else if (pn->next) { prev = pn; pn = pn->next; } else { expand_heap(i); return do_alloc(i); } } expand_heap(i); return do_alloc(i); }