/* * Add-Tail Item */ int sflist_add_tail ( SF_LIST* s, NODE_DATA ndata ) { SF_LNODE * q; if (!s->head) { q = s->tail = s->head = (SF_LNODE *) s_alloc (sizeof (SF_LNODE)); if(!q)return -1; q->ndata = (NODE_DATA)ndata; q->next = 0; q->prev = 0; } else { q = (SF_LNODE *) s_alloc (sizeof (SF_LNODE)); if(!q)return -1; q->ndata = ndata; q->next = 0; q->prev = s->tail; s->tail->next = q; s->tail = q; } s->count++; return 0; }
/* * * Create a new hash table * * nrows : number of rows in hash table, primes are best. * > 0 => we use the nearest prime internally * < 0 => we use the magnitude as nrows. * keysize : > 0 => bytes in each key, keys are binary bytes, * all keys are the same size. * ==0 => keys are strings and are null terminated, * allowing random key lengths. * userkeys : > 0 => indicates user owns the key data * and we should not allocate or free space for it, * nor should we attempt to free the user key. We just * save the pointer to the key. * ==0 => we should copy the keys and manage them internally * userfree : routine to free users data, null if we should not * free user data in sfghash_delete(). The routine * should be of the form 'void userfree(void * userdata)', * 'free' works for simple allocations. */ SFGHASH * sfghash_new( int nrows, int keysize, int userkeys, void (*userfree)(void*p) ) { int i; SFGHASH * h; if( nrows > 0 ) /* make sure we have a prime number */ { nrows = sf_nearest_prime( nrows ); } else /* use the magnitude or nrows as is */ { nrows = -nrows; } h = (SFGHASH*)s_alloc( sizeof(SFGHASH) ); if( !h ) return 0; memset( h, 0, sizeof(SFGHASH) ); h->sfhashfcn = sfhashfcn_new( nrows ); if( !h->sfhashfcn ) { free(h); return 0; } h->table = (SFGHASH_NODE**) s_alloc( sizeof(SFGHASH_NODE*) * nrows ); if( !h->table ) { free(h->sfhashfcn); free(h); return 0; } for( i=0; i<nrows; i++ ) { h->table[i] = 0; } h->userkey = userkeys; h->keysize = keysize; h->nrows = nrows; h->count = 0; h->userfree = userfree; h->crow = 0; // findfirst/next current row h->cnode = 0; // findfirst/next current node ptr return h; }
/* * NEW */ SF_LIST * sflist_new(void) { SF_LIST * s; s = (SF_LIST*)s_alloc( sizeof(SF_LIST) ); if( s )sflist_init( s ); return s; }
Private void copy( char * data, short int bytes, STRING_CHUNK ** head, STRING_CHUNK ** tail) { STRING_CHUNK * str; short int actual; str = s_alloc(bytes, &actual); if (*head == NULL) /* First chunk */ { *head = str; *tail = str; str->ref_ct = 1; str->string_len = 0; } else { (*tail)->next = str; *tail = str; } memcpy(str->data, data, bytes); str->bytes = bytes; (*head)->string_len += bytes; }
/* * Add-before Item */ int sflist_add_before ( SF_LIST* s, SF_LNODE * lnode, NODE_DATA ndata ) { SF_LNODE * q; if( !lnode ) return 0; /* Add to head of list */ if( s->head == lnode ) { return sflist_add_head ( s, ndata ); } else { q = (SF_LNODE *) s_alloc ( sizeof (SF_LNODE) ); if( !q ) { return -1; } q->ndata = (NODE_DATA)ndata; q->next = lnode; q->prev = lnode->prev; lnode->prev->next = q; lnode->prev = q; } s->count++; return 0; }
/* Set up a write stream that just keeps track of the position. */ int s_alloc_position_stream(stream ** ps, gs_memory_t * mem) { stream *s = *ps = s_alloc(mem, "s_alloc_position_stream"); if (s == 0) return_error(gs_error_VMerror); swrite_position_only(s); return 0; }
int main(int argc, char *argv[]) { setbuf(stdout,NULL); stress_test(1 << 2); struct s_arena *arena = new_arena(); for(int i = 0;i < 10; i++) { struct s_cache *sc = new_cache(arena,i,0); print_cache(sc); } struct s_cache *sc1 = new_cache(arena,7,4); struct s_cache *sc2 = new_cache(arena,1,3); printf("Alloc1: %p\n", s_alloc(saved_gc, sc1)); printf("Alloc1: %p\n", s_alloc(saved_gc, sc1)); printf("Alloc1: %p\n", s_alloc(saved_gc, sc1)); printf("Alloc2: %p\n", s_alloc(saved_gc, sc2)); printf("Alloc2: %p\n", s_alloc(saved_gc, sc2)); printf("Alloc2: %p\n", s_alloc(saved_gc, sc2)); print_cache(sc1); print_cache(sc2); return 0; }
T_OBJECT T_create( ) { register T_OBJECT T; T = (T_OBJECT) Salloc( sizeof(struct T_desc) ); T-> Type = T_Object; T-> T_n = 0; T-> T_lname = 0; T-> T_lhash = 1; T-> T_name = 0; T-> T_hash = s_alloc( 1 ); T-> T_hash[ 0 ] = MAXSHORT; return( T ); }
STRING_CHUNK * copy_string( STRING_CHUNK * tail, /* Last chunk, may be null */ STRING_CHUNK ** head, /* Ptr to head of string chunk chain */ char * src, /* Ptr to data to append */ short int len, /* Length of data to append */ short int * chunk_size) /* Desired (in), actual (out) chunk size */ { STRING_CHUNK * str_hdr; /* Ptr to current string chunk */ short int space; /* Bytes remaining in current chunk */ short int bytes_to_move; if (tail == NULL) space = 0; else { str_hdr = tail; space = str_hdr->alloc_size - str_hdr->bytes; } while (len > 0) { /* Allocate new chunk if the current one is full */ if (space == 0) { str_hdr = s_alloc((long)*chunk_size, &space); *chunk_size = space * 2; if (tail == NULL) /* First chunk */ { *head = str_hdr; } else /* Appending subsequent chunk */ { tail->next = str_hdr; } tail = str_hdr; } /* Copy what will fit into current chunk */ bytes_to_move = min(space, len); memcpy(str_hdr->data + str_hdr->bytes, src, bytes_to_move); src += bytes_to_move; len -= bytes_to_move; space -= bytes_to_move; str_hdr->bytes += bytes_to_move; } return tail; }
global String newnstring(const char *s, int n) { Ident *np, **p; p = &table[hash((const Byte *)s, n)]; for (np = *p; np != NULL; np = np->link) if (strncmp(np->text, s, n) == 0 && np->text[n] == '\0') return np->text; np = (Ident *)s_alloc((Natural)SizeIdent(n)); np->link = *p; *p = np; np->text[n] = '\0'; return strncpy(np->text, s, n); }
stream * s_SHA256E_make_stream(gs_memory_t *mem, byte *digest, int digest_size) { stream *s = s_alloc(mem, "s_SHA256E_make_stream"); stream_state *ss = s_alloc_state(mem, s_SHA256E_template.stype, "s_SHA256E_make_stream"); if (ss == NULL || s == NULL) goto err; ss->templat = &s_SHA256E_template; if (s_init_filter(s, ss, digest, digest_size, NULL) < 0) goto err; s->strm = s; return s; err: gs_free_object(mem, ss, "s_SHA256E_make_stream"); gs_free_object(mem, s, "s_SHA256E_make_stream"); return NULL; }
/* worry about cleaning up if a later step in opening the stream fails. */ stream * file_alloc_stream(gs_memory_t * mem, client_name_t cname) { stream *s; s = s_alloc(mem, cname); if (s == 0) return 0; s_init_ids(s); s->is_temp = 0; /* not a temp stream */ s->foreign = 0; /* * Disable the stream now (in case we can't open the file, * or a filter init procedure fails) so that `restore' won't * crash when it tries to close open files. */ s_disable(s); s->prev = 0; s->next = 0; return s; }
stream * s_MD5C_make_stream(gs_memory_t *mem, stream *strm) { stream *s = s_alloc(mem, "s_MD5E_make_stream"); stream_state *ss = s_alloc_state(mem, s_MD5E_template.stype, "s_MD5E_make_stream"); int buffer_size = 1024; byte *buffer = gs_alloc_bytes(mem, buffer_size, "s_MD5E_make_stream(buffer)"); if (ss == NULL || s == NULL || buffer == NULL) goto err; ss->templat = &s_MD5C_template; if (s_init_filter(s, ss, buffer, buffer_size, NULL) < 0) goto err; s->strm = strm; s->close_strm = true; return s; err: gs_free_object(mem, ss, "s_MD5E_make_stream"); gs_free_object(mem, s, "s_MD5E_make_stream"); gs_free_object(mem, buffer, "s_MD5E_make_stream"); return NULL; }
void stress_test(int n) { jhc_alloc_init(); struct s_arena *arena = new_arena(); struct s_cache *caches[NUM_CACHES]; void *ptrs[n]; memset(ptrs,0,n*sizeof(void *)); for(int i = 0; i < NUM_CACHES; i++) caches[i] = new_cache(arena,sizeof(void *)*(i + 1), 0); for(int i = 0; i < FACTOR * n; i++) { int wp = rand() % n; if (ptrs[wp]) { //s_free(ptrs[wp]); //free(ptrs[wp]); ptrs[wp] = NULL; } else { ptrs[wp] = s_alloc(saved_gc, caches[rand() % NUM_CACHES]); //ptrs[wp] = malloc((rand() % NUM_CACHES) * sizeof(uintptr_t)); } } }
void op_timedate() { char s[20+1]; long int timenow; short int hour; short int min; short int sec; STRING_CHUNK * p; long int n; short int i; timenow = local_time() + date_adjustment; /* Form time of day values */ n = timenow % 86400L; hour = (short int)(n / 3600); n = n % 3600; min = (short int)(n / 60); sec = (short int)(n % 60); /* Build result string */ sprintf(s, "%02d:%02d:%02d %s", (int)hour, (int)min, (int)sec, day_to_ddmmmyyyy((timenow / 86400L) + 732)); UpperCaseString(s); InitDescr(e_stack, STRING); p = e_stack->data.str.saddr = s_alloc(20L, &i); p->string_len = 20; p->bytes = 20; p->ref_ct = 1; memcpy(p->data, s, 20); e_stack++; }
/* * Add a key + data pair * --------------------- * * key + data should both be non-zero, although data can be zero * * t - hash table * key - users key data (should be unique in this table) * may be ascii strings or fixed size binary keys * data - users data pointer * * returns SF_HASH_NOMEM: alloc error * SF_HASH_INTABLE : key already in table (t->cnode points to the node) * SF_OK: added a node for this key + data pair * * Notes: * If the key node already exists, then t->cnode points to it on return, * this allows you to do something with the node - like add the data to a * linked list of data items held by the node, or track a counter, or whatever. * */ int sfghash_add( SFGHASH * t, void * key, void * data ) { unsigned hashkey; int klen; int index; SFGHASH_NODE *hnode; /* * Get proper Key Size */ if( t->keysize > 0 ) { klen = t->keysize; } else { /* need the null byte for strcmp() in sfghash_find() */ klen = strlen( (char*)key ) + 1; } hashkey = t->sfhashfcn->hash_fcn( t->sfhashfcn, (unsigned char*) key, klen ); index = hashkey % t->nrows; /* * Uniqueness: * Check 1st to see if the key is already in the table * Just bail if it is. */ for( hnode=t->table[index]; hnode; hnode=hnode->next ) { if( t->keysize > 0 ) { if( !t->sfhashfcn->keycmp_fcn(hnode->key,key,klen) ) { t->cnode = hnode; /* save pointer to the node */ return SFGHASH_INTABLE; /* found it */ } } else { if( !strcmp((const char *)hnode->key,(const char*)key) ) { t->cnode = hnode; /* save pointer to the node */ return SFGHASH_INTABLE; /* found it */ } } } /* * Create new node */ hnode = (SFGHASH_NODE*)s_alloc(sizeof(SFGHASH_NODE)); if( !hnode ) return SFGHASH_NOMEM; /* Add the Key */ if( t->userkey ) { /* Use the Users key */ hnode->key = key; } else { /* Create new key */ hnode->key = s_alloc( klen ); if( !hnode->key ) { free(hnode); return SFGHASH_NOMEM; } /* Copy key */ memcpy(hnode->key,key,klen); } /* Add The Node */ if( t->table[index] ) /* add the node to the existing list */ { hnode->prev = 0; // insert node as head node hnode->next=t->table[index]; hnode->data=data; t->table[index]->prev = hnode; t->table[index] = hnode; } else /* 1st node in this list */ { hnode->prev=0; hnode->next=0; hnode->data=data; t->table[index] = hnode; } t->count++; return SFGHASH_OK; }
/* Open the output file and stream. */ int gdev_vector_open_file_options(gx_device_vector * vdev, uint strmbuf_size, int open_options) { bool binary = !(open_options & VECTOR_OPEN_FILE_ASCII); int code = -1; /* (only for testing, never returned) */ cmm_dev_profile_t *icc_struct; /* Open the file as seekable or sequential, as requested. */ if (!(open_options & VECTOR_OPEN_FILE_SEQUENTIAL)) { /* Try to open as seekable. */ code = gx_device_open_output_file((gx_device *)vdev, vdev->fname, binary, true, &vdev->file); } if (code < 0 && (open_options & (VECTOR_OPEN_FILE_SEQUENTIAL | VECTOR_OPEN_FILE_SEQUENTIAL_OK))) { /* Try to open as sequential. */ code = gx_device_open_output_file((gx_device *)vdev, vdev->fname, binary, false, &vdev->file); } if ((code >= 0) && (dev_proc(vdev, get_profile) != NULL)) { code = dev_proc(vdev, get_profile)((gx_device *)vdev, &icc_struct); } if (code < 0) return code; if ((vdev->strmbuf = gs_alloc_bytes(vdev->v_memory, strmbuf_size, "vector_open(strmbuf)")) == 0 || (vdev->strm = s_alloc(vdev->v_memory, "vector_open(strm)")) == 0 || ((open_options & VECTOR_OPEN_FILE_BBOX) && (vdev->bbox_device = gs_alloc_struct_immovable(vdev->v_memory, gx_device_bbox, &st_device_bbox, "vector_open(bbox_device)")) == 0) ) { if (vdev->bbox_device) gs_free_object(vdev->v_memory, vdev->bbox_device, "vector_open(bbox_device)"); vdev->bbox_device = 0; if (vdev->strm) gs_free_object(vdev->v_memory, vdev->strm, "vector_open(strm)"); vdev->strm = 0; if (vdev->strmbuf) gs_free_object(vdev->v_memory, vdev->strmbuf, "vector_open(strmbuf)"); vdev->strmbuf = 0; gx_device_close_output_file((gx_device *)vdev, vdev->fname, vdev->file); vdev->file = 0; return_error(gs_error_VMerror); } vdev->strmbuf_size = strmbuf_size; swrite_file(vdev->strm, vdev->file, vdev->strmbuf, strmbuf_size); vdev->open_options = open_options; /* * We don't want finalization to close the file, but we do want it * to flush the stream buffer. */ vdev->strm->procs.close = vdev->strm->procs.flush; if (vdev->bbox_device) { gx_device_bbox_init(vdev->bbox_device, NULL, vdev->v_memory); rc_increment(vdev->bbox_device); vdev->bbox_device->icc_struct = icc_struct; rc_increment(vdev->bbox_device->icc_struct); gx_device_set_resolution((gx_device *) vdev->bbox_device, vdev->HWResolution[0], vdev->HWResolution[1]); /* Do the right thing about upright vs. inverted. */ /* (This is dangerous in general, since the procedure */ /* might reference non-standard elements.) */ set_dev_proc(vdev->bbox_device, get_initial_matrix, dev_proc(vdev, get_initial_matrix)); (*dev_proc(vdev->bbox_device, open_device)) ((gx_device *) vdev->bbox_device); } return 0; }
Private void rep(bool compatible) { /* Stack: |=============================|=============================| | BEFORE | AFTER | |=============================|=============================| top | Replacement string | | |-----------------------------|-----------------------------| | Subvalue number | | |-----------------------------|-----------------------------| | Value number | | |-----------------------------|-----------------------------| | Field number | | |-----------------------------|-----------------------------| | ADDR to string to update | | |=============================|=============================| */ DESCRIPTOR * descr; /* Position descriptors */ long int field; long int value; long int subvalue; DESCRIPTOR * str_descr; /* String to update */ STRING_CHUNK * str_first_chunk; STRING_CHUNK * str_hdr; STRING_CHUNK * str_prev; short int chunk_size; STRING_CHUNK * new_str_hdr; /* For copying replaced chunk */ DESCRIPTOR * rep_descr; /* Replacement string */ STRING_CHUNK * rep_str_hdr; long int rep_len; /* Length of inserted data */ long int s_len; /* New length of result string */ DESCRIPTOR result_descr; /* Result string */ bool add_fm; rep_descr = e_stack - 1; k_get_string(rep_descr); rep_str_hdr = rep_descr->data.str.saddr; descr = e_stack - 2; GetInt(descr); subvalue = descr->data.value; descr = e_stack - 3; GetInt(descr); value = descr->data.value; descr = e_stack - 4; GetInt(descr); field = descr->data.value; str_descr = e_stack - 5; while (str_descr->type == ADDR) str_descr = str_descr->data.d_addr; k_get_string(str_descr); /* Optimised path for the S<-1, 0, 0> case with a reference count of one */ if ((field < 0) && (value == 0) && (subvalue == 0)) { str_hdr = str_descr->data.str.saddr; if (str_hdr == NULL) { /* Appending a field to a null string. Make the updated string a reference to the replacement string. */ if (rep_str_hdr != NULL) rep_str_hdr->ref_ct++; str_descr->data.str.saddr = rep_str_hdr; goto exit_op_rep; } /* Examine the string we are to update. If this has a reference count of one, we can optimise the action by simply appending to the string without copying it. */ if (str_hdr->ref_ct == 1) { /* Ensure we do not leave a remove pointer active */ str_descr->flags &= ~DF_REMOVE; /* Find the final chunk of the string */ str_first_chunk = str_hdr; str_prev = NULL; while(str_hdr->next != NULL) { str_prev = str_hdr; str_hdr = str_hdr->next; } /* We need to take into account the program's append mode. For compatible style, if the last character of the existing string is a field mark (i.e. the string ends with a null field), we do not add a further field mark. */ /* 0407 Rearranged code so that mark length is only added if we will be adding the mark. */ add_fm = !compatible || (str_hdr->data[str_hdr->bytes-1] != FIELD_MARK); if (rep_str_hdr == NULL) rep_len = add_fm; else rep_len = rep_str_hdr->string_len + add_fm; /* Update the total string length */ s_len = str_first_chunk->string_len + rep_len; str_first_chunk->string_len = s_len; if (str_hdr->alloc_size >= s_len) { /* The entire result will fit in the allocated size of the target string. Append the new data. */ if (add_fm) str_hdr->data[str_hdr->bytes++] = FIELD_MARK; while(rep_str_hdr != NULL) { memcpy(str_hdr->data + str_hdr->bytes, rep_str_hdr->data, rep_str_hdr->bytes); str_hdr->bytes += rep_str_hdr->bytes; rep_str_hdr = rep_str_hdr->next; } goto exit_op_rep; } /* If this chunk is less than maximum size, replace it by a new chunk. */ if (str_hdr->bytes < MAX_STRING_CHUNK_SIZE) { /* Replace final chunk */ rep_len += str_hdr->bytes; new_str_hdr = s_alloc(rep_len, &chunk_size); /* Copy old data and rechain chunks, freeing old one */ memcpy(new_str_hdr->data, str_hdr->data, str_hdr->bytes); new_str_hdr->bytes = str_hdr->bytes; if (str_prev == NULL) /* First chunk */ { new_str_hdr->string_len = str_hdr->string_len; new_str_hdr->ref_ct = 1; str_descr->data.str.saddr = new_str_hdr; } else { str_prev->next = new_str_hdr; } s_free(str_hdr); str_hdr = new_str_hdr; } else { chunk_size = (short int)min(rep_len, MAX_STRING_CHUNK_SIZE); } /* Append field mark and new data */ if (add_fm) { str_hdr = copy_string(str_hdr, &(str_descr->data.str.saddr), FIELD_MARK_STRING, 1, &chunk_size); } while(rep_str_hdr != NULL) { str_hdr = copy_string(str_hdr, &(str_descr->data.str.saddr), rep_str_hdr->data, rep_str_hdr->bytes, &chunk_size); rep_str_hdr = rep_str_hdr->next; } goto exit_op_rep; } } rdi(str_descr, field, value, subvalue, DYN_REPLACE, rep_descr, &result_descr, compatible); k_release(str_descr); InitDescr(str_descr, STRING); str_descr->data.str.saddr = result_descr.data.str.saddr; exit_op_rep: k_dismiss(); k_pop(4); /* subvalue, value and field positions and ADDR to target */ }