void cop_touch_pool(mapped_memory_pool_t pool) { mapped_memory_pbic_root *p; memory_block_t *mapped_range; volatile char *memory; uint64_t length; char i = 0; droot t = create_dec(); p = (mapped_memory_pbic_root *) pool; errno = 0; mapped_range = (memory_block_t *) dec_pop(&(p->memory_block_list)); for (; mapped_range;) { length = 0; for (memory = mapped_range->base_address; length < mapped_range->length;) { i = *memory; *memory = i; memory += 4096; length += 4096; } dec_push(t, mapped_range); mapped_range = (memory_block_t *) dec_pop(&(p->memory_block_list)); } mapped_range = (memory_block_t *) dec_pop(t); for (; mapped_range;) { dec_push(&(p->memory_block_list), mapped_range); mapped_range = (memory_block_t *) dec_pop(t); } }
void cop_remap_pool(mapped_memory_pool_t pool) { mapped_memory_pbic_root *p; memory_block_t *mapped_range; volatile char *memory; uint64_t length; char i = 0; int retv; droot t = create_dec(); p = (mapped_memory_pbic_root *) pool; errno = 0; if (COP_CTX_FD(&cop_pbic_info_array[p->PBICtype].ctx) != -1) { mapped_range = (memory_block_t *) dec_pop(&(p->memory_block_list)); for (; mapped_range;) { length = 0; for (memory = (char *)mapped_range->base_address; length < mapped_range->length;) { i = *memory; *memory = i; memory += 4096; length += 4096; } errno = 0; retv = cop_pbic_map( &(cop_pbic_info_array[p->PBICtype].ctx), (void *)mapped_range->base_address, mapped_range->length, mapped_range->flags); if (errno) { fprintf(stderr, "child fork pbic_map fail %d\n", errno); exit(errno); } dec_push(t, mapped_range); mapped_range = (memory_block_t *) dec_pop(&(p->memory_block_list)); } mapped_range = (memory_block_t *) dec_pop(t); for (; mapped_range;) { dec_push(&(p->memory_block_list), mapped_range); mapped_range = (memory_block_t *) dec_pop(t); } } }
int cop_setup_pbic(mapped_memory_pool_t p, const void *address, size_t length) { mapped_memory_pbic_root *mpr = (mapped_memory_pbic_root *) p; int retv; memory_block_t *n = malloc(sizeof(memory_block_t)); n->base_address = (void *)address; n->length = length; retv = cop_pbic_map(&(cop_pbic_info_array[mpr->PBICtype].ctx), address, length, 0); if (errno) { fprintf(stderr, "cop_setup_pbic map fail retv %d\n", errno); // if we're here it's sort of a game over situation errno = 0; free(n); return -1; } #ifdef REENTRANT_ON sem_wait(&(mpr->memory_block_lock)); #endif dec_push(&(mpr->memory_block_list), n); #ifdef REENTRANT_ON sem_post(&(mpr->memory_block_lock)); #endif return 0; }
void cop_seedMappedMemoryBranch(MappedMemoryBranch b, unsigned int align, unsigned long stride, unsigned long size , unsigned long totalsize, char *address, unsigned long number) { // setup 128, 512, 4096, 64 and 1M & other lists int i; MappedMemoryNode n; int whichList; // alloc enough space for MappedMemoryNodes char *ptrNodeSpace=malloc (number*(sizeof (MappedMemoryNode_dec))); whichList=sizeToBucket(size); #ifdef REENTRANT_ON sem_wait(&(b->bitBucketLocks[whichList])); #endif for (i=0; i<number; i++) { n=(MappedMemoryNode)ptrNodeSpace; n->address=(cop_info_t)address; n->size=size; n->left=n->right=n->parent=NULL; n->alignment=align; dec_push((b->bitBucket[whichList]),n); ptrNodeSpace+= sizeof (MappedMemoryNode_dec); address+=stride; } #ifdef REENTRANT_ON sem_post(&(b->bitBucketLocks[whichList])); #endif }
void cop_init_rx_pbic(mapped_memory_pbic_root * mpr, unsigned long newBlockSize, unsigned long rx_size, int rx_bolt) { memory_block_t *mapped_range; int i, rc; mpr->avail_cops = (1 << COP_XML) | (1 << COP_REGX); mpr->PBICtype = COP_PBIC_RX; mpr->crb_cache = malloc(sizeof(struct dec_root) * 15); for (i = 0; i < 15; i++) { //verbose_print("%d: plain %p amper %p\n", i, mpr->crb_cache[i], &(mpr->crb_cache[i])); dec_init(&(mpr->crb_cache[i])); } dec_init(&(mpr->DDE_cache)); dec_init(&(mpr->memory_block_list)); #ifdef REENTRANT_ON sem_init(&(mpr->mnode_root_lock), 0, 1); sem_init(&(mpr->memory_block_lock), 0, 1); #endif errno = 0; mpr->Tree = cop_MMTree_create(newBlockSize); mapped_range = malloc(sizeof(memory_block_t)); if ((rc = posix_memalign((void **)&(mapped_range->base_address), (512 * 1024 * 1024), rx_size))) fprintf(stderr, "posix_memalign failed, %s\n", strerror(rc)); mapped_range->length = rx_size; mpr->bolted = rx_bolt; if (mpr->bolted) mapped_range->flags = COP_MAP_BOLT | COP_MAP_MLOCK; else mapped_range->flags = 0; cop_MMTree_insertmappedblock(mpr->Tree, mapped_range); dec_push(&(mpr->memory_block_list), mapped_range); // initial map and touching of pages to force // creation of the PTEs cop_remap_pool(mpr); }
mapped_memory_pool_t cop_create_pool_by_type(unsigned long initialSize, unsigned long PBICtype, int bolted) { mapped_memory_pbic_root *mpr; memory_block_t *mapped_range; int rc; mpr = malloc(sizeof(mapped_memory_pbic_root)); #ifdef REENTRANT_ON sem_init(&(mpr->memory_block_lock), 0, 1); sem_init(&(mpr->mnode_root_lock), 0, 1); #endif mpr->bolted = bolted; if (PBICtype == COP_PBIC_CC) { mpr->avail_cops = (1 << COP_DECOMP) | (1 << COP_RNG) | (1 << COP_ASYM_CRYPTO) | (1 << COP_SYM_CRYPTO) | (1 << COP_ASYNC_DATA_MOVER); } else if (PBICtype == COP_PBIC_RX) { mpr->avail_cops = (1 << COP_XML) | (1 << COP_REGX); } else return NULL; mpr->Tree = cop_MMTree_create(4096); mapped_range = malloc(sizeof(memory_block_t)); if (rc = posix_memalign((void **)&(mapped_range->base_address), (64 * 1024), 16*1024*1024)) fprintf(stderr, "posix_memalign failed, %s\n", strerror(rc)); if (mpr->bolted) mapped_range->flags = COP_MAP_BOLT; else mapped_range->flags = 0; mapped_range->length = 16 * 1024 * 1024; dec_push(&(mpr->memory_block_list), mapped_range); // initial map and touching of pages to force // creation of the PTEs cop_remap_pool(mpr); }
void cop_init_cc_pbic(mapped_memory_pbic_root * mpr, unsigned long newBlockSize, unsigned long cc_size, int cc_bolt) { memory_block_t *mapped_range; int i, rc; mpr->avail_cops = (1 << COP_DECOMP) | (1 << COP_RNG) | (1 << COP_ASYM_CRYPTO) | (1 << COP_SYM_CRYPTO) | (1 << COP_ASYNC_DATA_MOVER); mpr->PBICtype = COP_PBIC_CC; mpr->crb_cache = malloc(sizeof(struct dec_root) * 15); for (i = 0; i < 15; i++) { //verbose_print("%d: plain %p amper %p\n", i, mpr->crb_cache[i], &(mpr->crb_cache[i])); dec_init(&(mpr->crb_cache[i])); } dec_init(&(mpr->DDE_cache)); dec_init(&(mpr->memory_block_list)); #ifdef REENTRANT_ON sem_init(&(mpr->mnode_root_lock), 0, 1); sem_init(&(mpr->memory_block_lock), 0, 1); #endif errno = 0; mpr->Tree = cop_MMTree_create(newBlockSize); mapped_range = malloc(sizeof(memory_block_t)); if ((rc = posix_memalign((void **)&(mapped_range->base_address), (64 * 1024), cc_size))) fprintf(stderr, "posix_memalign failed, %s\n", strerror(rc)); mapped_range->length = cc_size; mpr->bolted = cc_bolt; if (mpr->bolted) mapped_range->flags = COP_MAP_BOLT | COP_MAP_MLOCK; else mapped_range->flags = 0; cop_MMTree_insertmappedblock(mpr->Tree, mapped_range); dec_push(&(mpr->memory_block_list), mapped_range); cop_remap_pool(mpr); }
ERL_NIF_TERM decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { Decoder* d; jiffy_st* st = (jiffy_st*) enif_priv_data(env); ErlNifBinary bin; ERL_NIF_TERM objs; ERL_NIF_TERM curr; ERL_NIF_TERM val = argv[2]; ERL_NIF_TERM trailer; ERL_NIF_TERM ret; size_t bytes_read = 0; if(argc != 5) { return enif_make_badarg(env); } else if(!enif_inspect_binary(env, argv[0], &bin)) { return enif_make_badarg(env); } else if(!enif_get_resource(env, argv[1], st->res_dec, (void**) &d)) { return enif_make_badarg(env); } else if(!enif_is_list(env, argv[3])) { return enif_make_badarg(env); } else if(!enif_is_list(env, argv[4])) { return enif_make_badarg(env); } dec_init(d, env, argv[0], &bin); objs = argv[3]; curr = argv[4]; while(d->i < bin.size) { if(should_yield(env, &bytes_read, d->bytes_per_red)) { return enif_make_tuple5( env, st->atom_iter, argv[1], val, objs, curr ); } bytes_read += 1; switch(dec_curr(d)) { case st_value: switch(d->p[d->i]) { case ' ': case '\n': case '\r': case '\t': d->i++; break; case 'n': if(d->i + 3 >= d->len) { ret = dec_error(d, "invalid_literal"); goto done; } if(memcmp(&(d->p[d->i]), "null", 4) != 0) { ret = dec_error(d, "invalid_literal"); goto done; } val = d->null_term; dec_pop(d, st_value); d->i += 4; break; case 't': if(d->i + 3 >= d->len) { ret = dec_error(d, "invalid_literal"); goto done; } if(memcmp(&(d->p[d->i]), "true", 4) != 0) { ret = dec_error(d, "invalid_literal"); goto done; } val = d->atoms->atom_true; dec_pop(d, st_value); d->i += 4; break; case 'f': if(d->i + 4 >= bin.size) { ret = dec_error(d, "invalid_literal"); goto done; } if(memcmp(&(d->p[d->i]), "false", 5) != 0) { ret = dec_error(d, "invalid_literal"); goto done; } val = d->atoms->atom_false; dec_pop(d, st_value); d->i += 5; break; case '\"': if(!dec_string(d, &val)) { ret = dec_error(d, "invalid_string"); goto done; } dec_pop(d, st_value); break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(!dec_number(d, &val)) { ret = dec_error(d, "invalid_number"); goto done; } dec_pop(d, st_value); break; case '{': dec_push(d, st_object); dec_push(d, st_key); objs = enif_make_list_cell(env, curr, objs); curr = enif_make_list(env, 0); d->i++; break; case '[': dec_push(d, st_array); dec_push(d, st_value); objs = enif_make_list_cell(env, curr, objs); curr = enif_make_list(env, 0); d->i++; break; case ']': if(!enif_is_empty_list(env, curr)) { ret = dec_error(d, "invalid_json"); goto done; } dec_pop(d, st_value); if(dec_curr(d) != st_array) { ret = dec_error(d, "invalid_json"); goto done; } dec_pop(d, st_array); dec_pop(d, st_value); val = curr; // curr is [] if(!enif_get_list_cell(env, objs, &curr, &objs)) { ret = dec_error(d, "internal_error"); goto done; } d->i++; break; default: ret = dec_error(d, "invalid_json"); goto done; } if(dec_top(d) == 0) { dec_push(d, st_done); } else if(dec_curr(d) != st_value && dec_curr(d) != st_key) { dec_push(d, st_comma); curr = enif_make_list_cell(env, val, curr); } break; case st_key: switch(d->p[d->i]) { case ' ': case '\n': case '\r': case '\t': d->i++; break; case '\"': if(!dec_string(d, &val)) { ret = dec_error(d, "invalid_string"); goto done; } dec_pop(d, st_key); dec_push(d, st_colon); curr = enif_make_list_cell(env, val, curr); break; case '}': if(!enif_is_empty_list(env, curr)) { ret = dec_error(d, "invalid_json"); goto done; } dec_pop(d, st_key); dec_pop(d, st_object); dec_pop(d, st_value); val = make_empty_object(env, d->return_maps); if(!enif_get_list_cell(env, objs, &curr, &objs)) { ret = dec_error(d, "internal_error"); goto done; } if(dec_top(d) == 0) { dec_push(d, st_done); } else { dec_push(d, st_comma); curr = enif_make_list_cell(env, val, curr); } d->i++; break; default: ret = dec_error(d, "invalid_json"); goto done; } break; case st_colon: switch(d->p[d->i]) { case ' ': case '\n': case '\r': case '\t': d->i++; break; case ':': dec_pop(d, st_colon); dec_push(d, st_value); d->i++; break; default: ret = dec_error(d, "invalid_json"); goto done; } break; case st_comma: switch(d->p[d->i]) { case ' ': case '\n': case '\r': case '\t': d->i++; break; case ',': dec_pop(d, st_comma); switch(dec_curr(d)) { case st_object: dec_push(d, st_key); break; case st_array: dec_push(d, st_value); break; default: ret = dec_error(d, "internal_error"); goto done; } d->i++; break; case '}': dec_pop(d, st_comma); if(dec_curr(d) != st_object) { ret = dec_error(d, "invalid_json"); goto done; } dec_pop(d, st_object); dec_pop(d, st_value); if(!make_object(env, curr, &val, d->return_maps, d->dedupe_keys)) { ret = dec_error(d, "internal_object_error"); goto done; } if(!enif_get_list_cell(env, objs, &curr, &objs)) { ret = dec_error(d, "internal_error"); goto done; } if(dec_top(d) > 0) { dec_push(d, st_comma); curr = enif_make_list_cell(env, val, curr); } else { dec_push(d, st_done); } d->i++; break; case ']': dec_pop(d, st_comma); if(dec_curr(d) != st_array) { ret = dec_error(d, "invalid_json"); goto done; } dec_pop(d, st_array); dec_pop(d, st_value); val = make_array(env, curr); if(!enif_get_list_cell(env, objs, &curr, &objs)) { ret = dec_error(d, "internal_error"); goto done; } if(dec_top(d) > 0) { dec_push(d, st_comma); curr = enif_make_list_cell(env, val, curr); } else { dec_push(d, st_done); } d->i++; break; default: ret = dec_error(d, "invalid_json"); goto done; } break; case st_done: switch(d->p[d->i]) { case ' ': case '\n': case '\r': case '\t': d->i++; break; default: goto decode_done; } break; default: ret = dec_error(d, "invalid_internal_state"); goto done; } } decode_done: if(d->i < bin.size && d->return_trailer) { trailer = enif_make_sub_binary(env, argv[0], d->i, bin.size - d->i); val = enif_make_tuple3(env, d->atoms->atom_has_trailer, val, trailer); } else if(d->i < bin.size) { ret = dec_error(d, "invalid_trailing_data"); goto done; } if(dec_curr(d) != st_done) { ret = dec_error(d, "truncated_json"); } else if(d->is_partial) { ret = enif_make_tuple2(env, d->atoms->atom_partial, val); } else { ret = val; } done: return ret; }