Obj_t *alloc_obj(Nursery_t *nursery, word size) { assert(((word)nursery - (word)nurseries) % sizeof(nursery) == 0, "Bad nursery pointer"); if (size > BLOCK_SIZE) { // The object is kind of big; allocate a group for it. word blocks = (size + BLOCK_SIZE - 1) >> BLOCK_SIZE_LG; assert(blocks * BLOCK_SIZE >= size, "Not getting enough blocks for given size."); Blockinfo_t *block = alloc_group(blocks); block->link = generations[0].large; generations[0].large = block; return (Obj_t *)block->start; }
struct group *add_group(struct database *db, char *name, int *existed) { struct group *g, **gprev = &db->groups; for (g = *gprev; g; gprev = &g->next, g = g->next) if (g->name && !strcmp(g->name, name)) break; if (existed) *existed = (g != NULL); if (!g) { g = alloc_group(xstrdup(name)); g->next = *gprev; *gprev = g; } db->dirty = 1; return g; }
void init_nurseries(int num_threads) { guard(num_threads <= MAX_GC_THREADS, "Number of threads exceeds MAX_GC_THREADS"); for (int i = 0; i < num_threads; i++) { Nursery_t *nursery = &nurseries[i]; Blockinfo_t *free = NULL; for (int j = 0; j < NURSERY_BLOCKS; j++) { Blockinfo_t *block = alloc_group(1); assert(block != NULL, "Got bad block"); assert(block->start != NULL, "block has bad start"); block->link = free; block->gen = &generations[0]; free = block; } nursery->blocks = free; nursery->alloc_block = free; nursery->alloc_block->free_ptr = nursery->alloc_block->start; assert(nursery->alloc_block->free_ptr != NULL, "Bad free pointer"); } }
static void increment_node_freq(LHALH1Decoder *decoder, uint16_t node_index) { Node *node, *other; node = &decoder->nodes[node_index]; other = &decoder->nodes[node_index - 1]; ++node->freq; // If the node is part of a group containing other nodes, it // must leave the group. if (node_index < NUM_TREE_NODES - 1 && node->group == decoder->nodes[node_index + 1].group) { // Next node in the group now becomes the leader. ++decoder->group_leader[node->group]; // The node must now either join the group to its // left, or start a new group. if (node->freq == other->freq) { node->group = other->group; } else { node->group = alloc_group(decoder); decoder->group_leader[node->group] = node_index; } } else { // The node is in a group of its own (single-node // group). It might need to join the group of the // node on its left if it has the same frequency. if (node->freq == other->freq) { free_group(decoder, node->group); node->group = other->group; } } }
static void reconstruct_tree(LHALH1Decoder *decoder) { Node *leaf; unsigned int child; unsigned int freq; unsigned int group; int i; // Gather all leaf nodes at the start of the table. leaf = decoder->nodes; for (i = 0; i < NUM_TREE_NODES; ++i) { if (decoder->nodes[i].leaf) { leaf->leaf = 1; leaf->child_index = decoder->nodes[i].child_index; // Frequency of the nodes in the new tree is halved, // this acts as a running average each time the // tree is reconstructed. leaf->freq = (uint16_t) (decoder->nodes[i].freq + 1) / 2; ++leaf; } } // The leaf nodes are now all at the start of the table. Now // reconstruct the tree, starting from the end of the table and // working backwards, inserting branch nodes between the leaf // nodes. Each branch node inherits the sum of the frequencies // of its children, and must be placed to maintain the ordering // within the table by decreasing frequency. leaf = &decoder->nodes[NUM_CODES - 1]; child = NUM_TREE_NODES - 1; i = NUM_TREE_NODES - 1; while (i >= 0) { // Before we can add a new branch node, we need at least // two nodes to use as children. If we don't have this // then we need to copy some from the leaves. while ((int) child - i < 2) { decoder->nodes[i] = *leaf; decoder->leaf_nodes[leaf->child_index] = (uint16_t) i; --i; --leaf; } // Now that we have at least two nodes to take as children // of the new branch node, we can calculate the branch // node's frequency. freq = (unsigned int) (decoder->nodes[child].freq + decoder->nodes[child - 1].freq); // Now copy more leaf nodes until the correct place to // insert the new branch node presents itself. while (leaf >= decoder->nodes && freq >= leaf->freq) { decoder->nodes[i] = *leaf; decoder->leaf_nodes[leaf->child_index] = (uint16_t) i; --i; --leaf; } // The new branch node can now be inserted. decoder->nodes[i].leaf = 0; decoder->nodes[i].freq = (uint16_t) freq; decoder->nodes[i].child_index = (uint16_t) child; decoder->nodes[child].parent = (uint16_t) i; decoder->nodes[child - 1].parent = (uint16_t) i; --i; // Process the next pair of children. child -= 2; } // Reconstruct the group data. Start by resetting group data. init_groups(decoder); // Assign a group to the first node. group = alloc_group(decoder); decoder->nodes[0].group = (uint16_t) group; decoder->group_leader[group] = 0; // Assign a group number to each node, nodes having the same // group if the have the same frequency, and allocating new // groups when a new frequency is found. for (i = 1; i < NUM_TREE_NODES; ++i) { if (decoder->nodes[i].freq == decoder->nodes[i - 1].freq) { decoder->nodes[i].group = decoder->nodes[i - 1].group; } else { group = alloc_group(decoder); decoder->nodes[i].group = (uint16_t) group; // First node with a particular frequency is leader. decoder->group_leader[group] = (uint16_t) i; } } }
static void init_tree(LHALH1Decoder *decoder) { unsigned int i, child; int node_index; uint16_t leaf_group; Node *node; // Leaf nodes are placed at the end of the table. Start by // initializing these, and working backwards. node_index = NUM_TREE_NODES - 1; leaf_group = alloc_group(decoder); for (i = 0; i < NUM_CODES; ++i) { node = &decoder->nodes[node_index]; node->leaf = 1; node->child_index = (unsigned short) i; node->freq = 1; node->group = leaf_group; decoder->group_leader[leaf_group] = (uint16_t) node_index; decoder->leaf_nodes[i] = (uint16_t) node_index; --node_index; } // Now build up the intermediate nodes, up to the root. Each // node gets two nodes as children. child = NUM_TREE_NODES - 1; while (node_index >= 0) { node = &decoder->nodes[node_index]; node->leaf = 0; // Set child pointer and update the parent pointers of the // children. node->child_index = child; decoder->nodes[child].parent = (uint16_t) node_index; decoder->nodes[child - 1].parent = (uint16_t) node_index; // The node's frequency is equal to the sum of the frequencies // of its children. node->freq = (uint16_t) (decoder->nodes[child].freq + decoder->nodes[child - 1].freq); // Is the frequency the same as the last node we processed? // if so, we are in the same group. If not, we must // allocate a new group. Either way, this node is now the // leader of its group. if (node->freq == decoder->nodes[node_index + 1].freq) { node->group = decoder->nodes[node_index + 1].group; } else { node->group = alloc_group(decoder); } decoder->group_leader[node->group] = (uint16_t) node_index; // Process next node. --node_index; child -= 2; } }
static int read_db(struct database *db) { char *line = NULL; size_t linesz = 0; struct group *group = NULL, **pgroup = &db->groups; int linenr = 0; while (getline(&line, &linesz, db->fh) > 0) { char *s; s = strchr(line, '#'); if (s) { struct group *cmt; DB_NEW(cmt); *pgroup = cmt; pgroup = &cmt->next; cmt->comment = xstrdup(s + 1); *s = 0; } s = cleanline(line); linenr++; if (!s) continue; if (*s == '[') { int n; char *name; ++s; n = strcspn(s, "]"); if (s[n] == 0) goto parse_error; name = xalloc(n + 1); memcpy(name, s, n); group = alloc_group(name); *pgroup = group; pgroup = &group->next; } else { char *p; if (!group) goto parse_error; p = s + strcspn(s, ":"); if (*p != ':') goto parse_error; *p++ = 0; if (*p == ' ') p++; else goto parse_error; change_entry(db, group, line, p); } } if (ferror(db->fh)) { DBerror("IO error while reading database %s: %s\n", db->fn, strerror(errno)); goto error; } free(line); return 0; parse_error: DBerror("Parse error in database %s at line %d\n", db->fn, linenr); error: free(line); return -1; }
/* * Initialize a console, if console is associated with with a * new group, intialize the group. */ static int alloc_cons_with_group(vntsd_t *vntsdp, vcc_console_t *consp, vntsd_group_t **new_groupp) { vntsd_group_t *groupp = NULL; int rv; *new_groupp = NULL; /* match group by tcp port */ (void) mutex_lock(&vntsdp->lock); groupp = vntsd_que_find(vntsdp->grouppq, (compare_func_t)grp_by_tcp, (void *)&(consp->tcp_port)); (void) mutex_unlock(&vntsdp->lock); if (groupp != NULL) { /* group with same tcp port found */ if (strcmp(groupp->group_name, consp->group_name)) { /* conflict group name */ vntsd_log(VNTSD_ERR_VCC_GRP_NAME, "group name is different from existing group"); return (VNTSD_ERR_VCC_CTRL_DATA); } } else { /* new group */ groupp = alloc_group(vntsdp, consp->group_name, consp->tcp_port); if (groupp == NULL) { return (VNTSD_ERR_NO_MEM); } assert(groupp->conspq == NULL); /* queue group to vntsdp */ (void) mutex_lock(&vntsdp->lock); rv = vntsd_que_append(&vntsdp->grouppq, groupp); (void) mutex_unlock(&vntsdp->lock); if (rv != VNTSD_SUCCESS) { return (rv); } *new_groupp = groupp; } /* intialize console */ if (alloc_cons(groupp, consp) == NULL) { /* no memory */ if (new_groupp != NULL) { /* clean up new group */ (void) cond_destroy(&groupp->cvp); (void) mutex_destroy(&groupp->lock); free(groupp); } return (VNTSD_ERR_NO_MEM); } return (VNTSD_SUCCESS); }