示例#1
0
void tmp_gc(void) {
#if ENABLE_FastMemAlloc
    if (tmp_pool_pos + tmp_alloc_size >= tmp_pool_avr) {
        tmp_pool_avr = tmp_pool_pos + tmp_alloc_size;
    }
    else if (tmp_pool_avr > POOL_SIZE / 0x10) {
        tmp_pool_avr -= POOL_SIZE / 0x10000;
    }
    if (tmp_pool_max < tmp_pool_avr && tmp_pool_max < POOL_SIZE) {
        if (tmp_pool_max < POOL_SIZE / 0x10) tmp_pool_max = POOL_SIZE / 0x10;
        while (tmp_pool_max < tmp_pool_avr) tmp_pool_max *= 2;
        if (tmp_pool_max > POOL_SIZE) tmp_pool_max = POOL_SIZE;
        tmp_pool = (char *)loc_realloc(tmp_pool, tmp_pool_max);
    }
    else if (tmp_pool_avr < tmp_pool_max / 4 && tmp_pool_max > POOL_SIZE / 0x10) {
        tmp_pool_max /= 2;
        tmp_pool = (char *)loc_realloc(tmp_pool, tmp_pool_max);
    }
    tmp_pool_pos = sizeof(LINK);
#endif
    while (!list_is_empty(&tmp_alloc_list)) {
        LINK * l = tmp_alloc_list.next;
        list_remove(l);
        loc_free(l);
    }
    tmp_alloc_size = 0;
}
示例#2
0
static void list_add(Symbol * sym) {
    if (list_cnt >= list_max) {
        list_max = list_max == 0 ? 32 : list_max * 2;
        list_buf = (Symbol **)loc_realloc(list_buf, sizeof(Symbol *) * list_max);
    }
    list_buf[list_cnt++] = sym;
}
示例#3
0
void * tmp_realloc(void * ptr, size_t size) {
    if (ptr == NULL) return tmp_alloc(size);
    assert(is_dispatch_thread());
    assert(tmp_gc_posted);
#if ENABLE_FastMemAlloc
    {
        void * p;
        size_t m = *((size_t *)ptr - 1);
        if (m >= size) return ptr;
        if ((char *)ptr >= tmp_pool && (char *)ptr <= tmp_pool + tmp_pool_max) {
            size_t pos = tmp_pool_pos - m;
            if (ptr == tmp_pool + pos && pos + size <= tmp_pool_max) {
                tmp_pool_pos = pos + size;
                *((size_t *)ptr - 1) = size;
                return ptr;
            }
        }
        p = tmp_alloc(size);
        if (m > size) m = size;
        return memcpy(p, ptr, m);
    }
#else
    {
        LINK * l = (LINK *)ptr - 1;
        list_remove(l);
        l = (LINK *)loc_realloc(l, sizeof(LINK) + size);
        list_add_last(l, &tmp_alloc_list);
        return l + 1;
    }
#endif
}
static void add_state(CompUnit * Unit, LineNumbersState * state) {
    if (Unit->mStatesCnt >= Unit->mStatesMax) {
        Unit->mStatesMax = Unit->mStatesMax == 0 ? 128 : Unit->mStatesMax * 2;
        Unit->mStates = (LineNumbersState *)loc_realloc(Unit->mStates, sizeof(LineNumbersState) * Unit->mStatesMax);
    }
    Unit->mStates[Unit->mStatesCnt++] = *state;
}
示例#5
0
static void realloc_msg_buf(void) {
    assert(is_dispatch_thread());
    if (msg_buf_max <= msg_buf_len + 128 || msg_buf_max > msg_buf_len + 2048) {
        msg_buf_max = msg_buf_len + 256;
        msg_buf = (char *)loc_realloc(msg_buf, msg_buf_max);
    }
}
示例#6
0
文件: peer.c 项目: pkdevbox/tcf.agent
void peer_server_addprop(PeerServer * s, const char * name, const char * value) {
    unsigned i;

    assert(!s->listed);
    if (strcmp(name, "ID") == 0) {
        loc_free(name);
        s->id = value;
        return;
    }
    for (i = 0; i < s->ind; i++) {
        if (strcmp(s->list[i].name, name) == 0) {
            loc_free(name);
            loc_free(s->list[i].value);
            s->list[i].value = value;
            return;
        }
    }
    if (s->ind == s->max) {
        s->max *= 2;
        s->list = (PeerServerList *)loc_realloc(s->list, s->max * sizeof *s->list);
    }
    s->list[s->ind].name = name;
    s->list[s->ind].value = value;
    s->ind++;
}
static void add_dir(CompUnit * Unit, char * Name) {
    if (Unit->mDirsCnt >= Unit->mDirsMax) {
        Unit->mDirsMax = Unit->mDirsMax == 0 ? 16 : Unit->mDirsMax * 2;
        Unit->mDirs = (char **)loc_realloc(Unit->mDirs, sizeof(char *) * Unit->mDirsMax);
    }
    Unit->mDirs[Unit->mDirsCnt++] = Name;
}
示例#8
0
文件: cache.c 项目: eswartz/emul
void cache_wait(AbstractCache * cache) {
#else
void cache_wait_dbg(const char * file, int line, AbstractCache * cache) {
#endif
    assert(is_dispatch_thread());
    assert(client_exited == 0);
    if (current_client.client != NULL && cache_miss_cnt == 0) {
        if (cache->wait_list_cnt >= cache->wait_list_max) {
            cache->wait_list_max += 8;
            cache->wait_list_buf = (WaitingCacheClient *)loc_realloc(cache->wait_list_buf, cache->wait_list_max * sizeof(WaitingCacheClient));
        }
        if (current_client.args != NULL && !current_client.args_copy) {
            void * mem = loc_alloc(current_client.args_size);
            memcpy(mem, current_client.args, current_client.args_size);
            current_client.args = mem;
            current_client.args_copy = 1;
        }
#ifndef NDEBUG
        current_client.file = file;
        current_client.line = line;
#endif
        if (cache->wait_list_cnt == 0) list_add_last(&cache->link, &cache_list);
        cache->wait_list_buf[cache->wait_list_cnt++] = current_client;
        channel_lock(current_client.channel);
    }
#ifndef NDEBUG
    else if (current_client.client == NULL) {
        trace(LOG_ALWAYS, "cache_wait(): illegal cache access at %s:%d", file, line);
    }
#endif
    cache_miss_cnt++;
    exception(ERR_CACHE_MISS);
}
static void add_file(CompUnit * Unit, FileInfo * File) {
    if (Unit->mFilesCnt >= Unit->mFilesMax) {
        Unit->mFilesMax = Unit->mFilesMax == 0 ? 16 : Unit->mFilesMax * 2;
        Unit->mFiles = (FileInfo *)loc_realloc(Unit->mFiles, sizeof(FileInfo) * Unit->mFilesMax);
    }
    if (File->mDir == NULL) File->mDir = Unit->mDir;
    Unit->mFiles[Unit->mFilesCnt++] = *File;
}
示例#10
0
文件: cache.c 项目: eclipse/tcf.agent
void add_cache_transaction_listener(CacheTransactionListener * l) {
    if (listeners_cnt >= listeners_max) {
        listeners_max += 8;
        listeners = (CacheTransactionListener **)loc_realloc(listeners,
            sizeof(CacheTransactionListener *) * listeners_max);
    }
    listeners[listeners_cnt++] = l;
}
示例#11
0
static StackFrameRegisters * get_regs_stack_item(int n) {
    while (n >= regs_stack_max) {
        int max = regs_stack_max;
        regs_stack_max = regs_stack_max == 0 ? 8 : regs_stack_max * 2;
        regs_stack = (StackFrameRegisters *)loc_realloc(regs_stack, sizeof(StackFrameRegisters) * regs_stack_max);
        memset(regs_stack + max, 0, sizeof(StackFrameRegisters) * (regs_stack_max - max));
    }
    return regs_stack + n;
}
示例#12
0
void add_registers_event_listener(RegistersEventListener * listener, void * args) {
    if (listener_cnt >= listener_max) {
        listener_max += 8;
        listeners = (Listener *)loc_realloc(listeners, listener_max * sizeof(Listener));
    }
    listeners[listener_cnt].func = listener;
    listeners[listener_cnt].args = args;
    listener_cnt++;
}
示例#13
0
static void add_command_sequence(StackFrameRegisterLocation ** ptr, RegisterDefinition * reg) {
    StackFrameRegisterLocation * seq = *ptr;
    if (seq == NULL || seq->cmds_max < trace_cmds_cnt) {
        *ptr = seq = (StackFrameRegisterLocation *)loc_realloc(seq, sizeof(StackFrameRegisterLocation) + (trace_cmds_cnt - 1) * sizeof(LocationExpressionCommand));
        seq->cmds_max = trace_cmds_cnt;
    }
    seq->reg = reg;
    seq->cmds_cnt = trace_cmds_cnt;
    memcpy(seq->cmds, trace_cmds, trace_cmds_cnt * sizeof(LocationExpressionCommand));
}
示例#14
0
文件: json.c 项目: eswartz/emul
static void realloc_buf(void) {
    if (buf == NULL) {
        buf_size = 0x1000;
        buf = (char *)loc_alloc(buf_size);
    }
    else {
        buf_size *= 2;
        buf = (char *)loc_realloc(buf, buf_size);
    }
}
示例#15
0
static LocationExpressionCommand * add_command(int op) {
    LocationExpressionCommand * cmd = NULL;
    if (trace_cmds_cnt >= trace_cmds_max) {
        trace_cmds_max += 16;
        trace_cmds = (LocationExpressionCommand *)loc_realloc(trace_cmds, trace_cmds_max * sizeof(LocationExpressionCommand));
    }
    cmd = trace_cmds + trace_cmds_cnt++;
    memset(cmd, 0, sizeof(*cmd));
    cmd->cmd = op;
    return cmd;
}
示例#16
0
static void read_location(InputStream * inp, void * args) {
    Location * loc = NULL;
    if (buf_pos >= buf_len) {
        buf_len = buf_len == 0 ? 0x10 : buf_len * 2;
        buf = (Location *)loc_realloc(buf, buf_len * sizeof(Location));
    }
    loc_pos = 0;
    loc = buf + buf_pos++;
    memset(loc, 0, sizeof(Location));
    json_read_array(inp, read_location_element, loc);
}
示例#17
0
文件: cache.c 项目: eclipse/tcf.agent
static void run_cache_client(int retry) {
    Trap trap;
    unsigned i;
    unsigned id = current_client.id;
    void * args_copy = NULL;

    assert(id != 0);
    current_cache = NULL;
    cache_miss_cnt = 0;
    def_channel = NULL;
    if (current_client.args_copy) args_copy = current_client.args;
    for (i = 0; i < listeners_cnt; i++) listeners[i](retry ? CTLE_RETRY : CTLE_START);
    if (set_trap(&trap)) {
        current_client.client(current_client.args);
        clear_trap(&trap);
        assert(current_client.id == 0);
        assert(cache_miss_cnt == 0);
    }
    else if (id != current_client.id) {
        trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error));
        assert(current_client.id == 0);
        assert(cache_miss_cnt == 0);
    }
    else {
        if (get_error_code(trap.error) != ERR_CACHE_MISS || cache_miss_cnt == 0 || current_cache == NULL) {
            trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error));
            for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_COMMIT);
        }
        else {
            AbstractCache * cache = current_cache;
            if (cache->wait_list_cnt >= cache->wait_list_max) {
                cache->wait_list_max += 8;
                cache->wait_list_buf = (WaitingCacheClient *)loc_realloc(cache->wait_list_buf, cache->wait_list_max * sizeof(WaitingCacheClient));
            }
            if (current_client.args != NULL && !current_client.args_copy) {
                void * mem = loc_alloc(current_client.args_size);
                memcpy(mem, current_client.args, current_client.args_size);
                current_client.args = mem;
                current_client.args_copy = 1;
            }
            if (cache->wait_list_cnt == 0) list_add_last(&cache->link, &cache_list);
            if (current_client.channel != NULL) channel_lock_with_msg(current_client.channel, channel_lock_msg);
            cache->wait_list_buf[cache->wait_list_cnt++] = current_client;
            for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_ABORT);
            args_copy = NULL;
        }
        memset(&current_client, 0, sizeof(current_client));
        current_cache = NULL;
        cache_miss_cnt = 0;
        def_channel = NULL;
    }
    if (args_copy != NULL) loc_free(args_copy);
}
示例#18
0
文件: peer.c 项目: pkdevbox/tcf.agent
void peer_server_add_listener(peer_server_listener fnp, void * arg) {
    if (listeners_max == 0) {
        listeners_max = 4;
        listeners = (PeersListener *)loc_alloc(listeners_max * sizeof(PeersListener));
    }
    else if (listeners_cnt == listeners_max) {
        listeners_max *= 2;
        listeners = (PeersListener *)loc_realloc(listeners, listeners_max * sizeof(PeersListener));
    }
    listeners[listeners_cnt].fnp = fnp;
    listeners[listeners_cnt].arg = arg;
    listeners_cnt++;
}
static void command_write(char * token, Channel * c) {
    char id[256];
    OpenFileInfo * h = NULL;
    int64_t offset;
    unsigned long len = 0;
    JsonReadBinaryState state;

    static size_t buf_size = 0;
    static char * buf = NULL;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    offset = json_read_int64(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);

    json_read_binary_start(&state, &c->inp);

    h = find_open_file_info(id);
    for (;;) {
        int rd;
        if (buf_size < len + BUF_SIZE) {
            buf_size += BUF_SIZE;
            buf = loc_realloc(buf, buf_size);
        }
        rd = json_read_binary_data(&state, buf + len, buf_size - len);
        if (rd == 0) break;
        len += rd;
    }
    json_read_binary_end(&state);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    if (h == NULL) {
        reply_write(token, &c->out, EBADF);
    }
    else {
        IORequest * req = create_io_request(token, h, REQ_WRITE);
        if (offset < 0) {
            req->info.type = AsyncReqWrite;
        }
        else {
            req->info.type = AsyncReqSeekWrite;
            req->info.u.fio.offset = (off_t)offset;
        }
        req->info.u.fio.fd = h->file;
        req->info.u.fio.bufp = loc_alloc(len);
        req->info.u.fio.bufsz = len;
        memcpy(req->info.u.fio.bufp, buf, len);
        post_io_requst(h);
    }
}
示例#20
0
static void add_map_region(MemoryMap * map, void * addr, int size, unsigned flags, char * file, char * sect) {
    MemoryRegion * r = NULL;
    if (map->region_cnt >= map->region_max) {
        map->region_max += 8;
        map->regions = (MemoryRegion *)loc_realloc(map->regions, sizeof(MemoryRegion) * map->region_max);
    }
    r = map->regions + map->region_cnt++;
    memset(r, 0, sizeof(MemoryRegion));
    r->addr = (ContextAddress)addr;
    r->size = (ContextAddress)size;
    r->flags = flags;
    if (file != NULL) r->file_name = loc_strdup(file);
    if (sect != NULL) r->sect_name = loc_strdup(sect);
}
示例#21
0
void add_disassembler(Context * ctx, const char * isa, Disassembler disassembler) {
    DisassemblerInfo * i = NULL;
    ContextExtensionDS * ext = EXT(ctx);
    assert(ctx == context_get_group(ctx, CONTEXT_GROUP_CPU));
    if ((i = find_disassembler_info(ctx, isa)) == NULL) {
        if (ext->disassemblers_cnt >= ext->disassemblers_max) {
            ext->disassemblers_max += 8;
            ext->disassemblers = (DisassemblerInfo *)loc_realloc(ext->disassemblers,
                sizeof(DisassemblerInfo) * ext->disassemblers_max);
        }
        i = ext->disassemblers + ext->disassemblers_cnt++;
        i->isa = loc_strdup(isa);
    }
    i->disassembler = disassembler;
}
示例#22
0
static void command_get_cache_client(void * x) {
    GetArgs * args = (GetArgs *)x;
    Channel * c  = cache_channel();
    Trap trap;

    bbf_pos = 0;
    if (set_trap(&trap)) {
        int frame = 0;
        Context * ctx = NULL;
        RegisterDefinition * reg_def = NULL;

        if (id2register(args->id, &ctx, &frame, &reg_def) < 0) exception(errno);
        if (ctx->exited) exception(ERR_ALREADY_EXITED);
        if ((ctx->reg_access & REG_ACCESS_RD_STOP) != 0) {
            check_all_stopped(ctx);
        }
        if ((ctx->reg_access & REG_ACCESS_RD_RUNNING) == 0) {
            if (!ctx->stopped && context_has_state(ctx))
                str_exception(ERR_IS_RUNNING, "Cannot read register if not stopped");
        }
        if (reg_def->size > bbf_len) {
            bbf_len += 0x100 + reg_def->size;
            bbf = (uint8_t *)loc_realloc(bbf, bbf_len);
        }

        bbf_pos = reg_def->size;
        memset(bbf, 0, reg_def->size);
        if (frame < 0 || is_top_frame(ctx, frame)) {
            if (context_read_reg(ctx, reg_def, 0, reg_def->size, bbf) < 0) exception(errno);
        }
        else {
            StackFrame * info = NULL;
            if (get_frame_info(ctx, frame, &info) < 0) exception(errno);
            if (read_reg_bytes(info, reg_def, 0, reg_def->size, bbf) < 0) exception(errno);
        }

        clear_trap(&trap);
    }

    cache_exit();

    write_stringz(&c->out, "R");
    write_stringz(&c->out, args->token);
    write_errno(&c->out, trap.error);
    json_write_binary(&c->out, bbf, bbf_pos);
    write_stream(&c->out, 0);
    write_stream(&c->out, MARKER_EOM);
}
示例#23
0
int get_symbol_children(const Symbol * sym, Symbol *** children, int * count) {

    static const DWORD FINDCHILDREN_BUF_SIZE = 64;
    static TI_FINDCHILDREN_PARAMS * params = NULL;
    static Symbol ** buf = NULL;
    static unsigned buf_len = 0;

    DWORD cnt = 0;
    Symbol type = *sym;
    DWORD tag = 0;

    assert(sym->magic == SYMBOL_MAGIC);
    if (sym->base || sym->info) {
        *children = NULL;
        *count = 0;
        return 0;
    }
    if (get_type_tag(&type, &tag)) return -1;
    if (get_type_info(&type, TI_GET_CHILDRENCOUNT, &cnt) < 0) return -1;
    if (params == NULL) params = (TI_FINDCHILDREN_PARAMS *)loc_alloc(
        sizeof(TI_FINDCHILDREN_PARAMS) + (FINDCHILDREN_BUF_SIZE - 1) * sizeof(ULONG));

    if (buf_len < cnt) {
        buf = (Symbol **)loc_realloc(buf, sizeof(Symbol *) * cnt);
        buf_len = cnt;
    }
    params->Start = 0;
    while (params->Start < cnt) {
        DWORD i = cnt - (DWORD)params->Start;
        params->Count = i > FINDCHILDREN_BUF_SIZE ? FINDCHILDREN_BUF_SIZE : i;
        if (get_type_info(&type, TI_FINDCHILDREN, params) < 0) return -1;
        for (i = 0; params->Start < cnt; i++) {
            DWORD dword = 0;
            Symbol * x = alloc_symbol();
            *x = *sym;
            x->index = params->ChildId[i];
            if (get_type_info(x, TI_GET_SYMTAG, &dword) < 0) return -1;
            tag2symclass(x, dword);
            buf[params->Start++] = x;
        }
    }

    *children = buf;
    *count = cnt;
    return 0;
}
示例#24
0
文件: plugins.c 项目: eswartz/emul
int plugin_add_function(const char * name, void * function) {
    size_t i;

    if (!name || !function) return -EINVAL;

    /* Check if the function name already exists */
    for (i = 0; i < function_entry_count; ++i)
        if (!strcmp(name, function_entries[i].name))
            return -EEXIST;

    function_entries = (struct function_entry *) loc_realloc(function_entries,
            ++function_entry_count * sizeof(struct function_entry));

    function_entries[function_entry_count-1].function = function;
    function_entries[function_entry_count-1].name = loc_strdup(name);
    return 0;
}
static CompUnit * find_comp_unit(U8_T ID) {
    unsigned i;
    CompUnit * Unit;

    for (i = 0; i < sCache->mCompUnitsCnt; i++) {
        Unit = sCache->mCompUnits[i];
        if (Unit->mID == ID) return Unit;
    }
    if (sCache->mCompUnitsCnt >= sCompUnitsMax) {
        sCompUnitsMax = sCompUnitsMax == 0 ? 16 : sCompUnitsMax * 2;
        sCache->mCompUnits = loc_realloc(sCache->mCompUnits, sizeof(CompUnit *) * sCompUnitsMax);
    }
    Unit = loc_alloc_zero(sizeof(CompUnit));
    Unit->mID = ID;
    sCache->mCompUnits[sCache->mCompUnitsCnt++] = Unit;
    return Unit;
}
示例#26
0
void str_fmt_exception(int error, const char * fmt, ...) {
    va_list vaList;
    char * buf = NULL;
    size_t len = 100;
    int n;

    while (1) {
        buf = (char *)loc_realloc(buf, len);
        va_start(vaList, fmt);
        n = vsnprintf(buf, len, fmt, vaList);
        va_end(vaList);
        if (n < (int)len) break;
        len = n + 1;
    }
    error = set_errno(error, buf);
    loc_free(buf);
    exception(error);
}
示例#27
0
文件: cache.c 项目: eclipse/tcf.agent
void cache_notify_later(AbstractCache * cache) {
    unsigned cnt = cache->wait_list_cnt;
    unsigned max = cache->wait_list_max;
    WaitingCacheClient * buf = cache->wait_list_buf;

    assert(is_dispatch_thread());
    if (cnt == 0) return;
    list_remove(&cache->link);
    cache->wait_list_buf = NULL;
    cache->wait_list_cnt = 0;
    cache->wait_list_max = 0;
    if (max <= cnt) {
        max = cnt + 1;
        buf = (WaitingCacheClient *)loc_realloc(buf, max * sizeof(WaitingCacheClient));
    }
    memset(buf + cnt, 0, sizeof(WaitingCacheClient));
    post_event(cache_notify_event, buf);
}
示例#28
0
文件: cache.c 项目: eclipse/tcf.agent
void cache_notify(AbstractCache * cache) {
    unsigned i;
    unsigned cnt = cache->wait_list_cnt;

    assert(is_dispatch_thread());
    if (cnt == 0) return;
    list_remove(&cache->link);
    cache->wait_list_cnt = 0;
    if (wait_list_max < cnt) {
        wait_list_max = cnt;
        wait_list_buf = (WaitingCacheClient *)loc_realloc(wait_list_buf, cnt * sizeof(WaitingCacheClient));
    }
    memcpy(wait_list_buf, cache->wait_list_buf, cnt * sizeof(WaitingCacheClient));
    for (i = 0; i < cnt; i++) {
        current_client = wait_list_buf[i];
        run_cache_client(1);
        if (wait_list_buf[i].channel != NULL) channel_unlock_with_msg(wait_list_buf[i].channel, channel_lock_msg);
    }
}
示例#29
0
void add_reset(Context * ctx, const char * type, const char * desc, ContextReset * reset) {
    ContextExtensionRS * ext = EXT(ctx);
    ResetInfo * ri;

    ri = find_reset(ctx, type);
    if (ri == NULL) {
        if (ext->resets_cnt >= ext->resets_max) {
            ext->resets_max += 4;
            ext->resets = (ResetInfo *)loc_realloc(ext->resets, sizeof(ResetInfo) * ext->resets_max);
        }
        ri = ext->resets + ext->resets_cnt++;
        ri->type = loc_strdup(type);
    }
    else {
        loc_free(ri->desc);
    }
    ri->desc = loc_strdup(desc);
    ri->reset = reset;
}
示例#30
0
void sigset_set(SigSet * set, unsigned bit, int value) {
    unsigned n = search(set, bit);
    assert(bit > 0 || (bit == 0 && value == 0));
    assert(n <= set->cnt);
    if (value) {
        if (n < set->cnt && set->buf[n] == bit) return;
        if (set->cnt >= set->max) {
            set->max += 8;
            set->buf = (unsigned *)loc_realloc(set->buf, sizeof(unsigned) * set->max);
        }
        memmove(set->buf + n + 1, set->buf + n, sizeof(unsigned) * (set->cnt - n));
        set->buf[n] = bit;
        set->cnt++;
    }
    else {
        if (n >= set->cnt || set->buf[n] != bit) return;
        memmove(set->buf + n, set->buf + n + 1, sizeof(unsigned) * (set->cnt - n - 1));
        set->cnt--;
    }
}