int hassign(struct object *o, handle_t h) { int rc; if (h > HTABSIZE / sizeof(handle_t)) return -EBADF; while (htabsize <= h) { rc = expand_htab(); if (rc < 0) return rc; } if (!HUSED(htab[h])) { // Not allocated, remove from freelist rc = remove_from_freelist(h); if (rc < 0) return rc; } else { // Handle already allocated, free handle struct object *oo = HOBJ(htab[h]); if (HPROT(htab[h])) return -EACCES; if (--oo->handle_count == 0) { rc = close_object(oo); if (oo->lock_count == 0) destroy_object(oo); if (rc < 0) return rc; } } // Assign handle to object htab[h] = (handle_t) o; o->handle_count++; return 0; }
handle_t halloc(struct object *o) { handle_t h; int rc; // Expand handle table if full if (hfreelist == HEND) { rc = expand_htab(); if (rc < 0) return rc; } h = hfreelist; hfreelist = htab[h]; htab[h] = (handle_t) o; o->handle_count++; return h; }
static void hash_entry(ADDR caller, ADDR callee, char *caller_name, char *callee_name) { unsigned *pchain = h_tab.chain; int y; int i = h_tab.nchain; /* the hash uses caller and callee address only, this will cause */ /* duplication in the string table when either one of them is */ /* different. I am ignoring that for now */ int hash = ((caller + callee) & 0x0FFFFFFFF) % h_tab.size; /* printf("caller %x callee %x hash %d\n",caller, callee, hash); */ if ((y = h_tab.phash[hash]) == UNDEF) { if (h_tab.nchain == h_tab.nsym) { expand_htab(); pchain = h_tab.chain; } pchain[i] = UNDEF; counts_array[i].count = 1; counts_array[i].caller = caller; counts_array[i].callee = callee; counts_array[i].caller_name_idx = enter_str(caller_name); counts_array[i].callee_name_idx = enter_str(callee_name); h_tab.phash[hash] = h_tab.nchain++; num_counts++; /* printf("not found and new\n"); */ return; } while (y != UNDEF) { if (counts_array[y].caller == caller && counts_array[y].callee == callee) { counts_array[y].count++; /* printf("found and count %d\n", counts_array[y].count); */ return; } hash = y; y = pchain[y]; } /* not found */ pchain[hash] = h_tab.nchain; if (i == h_tab.nsym) { expand_htab(); pchain = h_tab.chain; } /* printf("not found and old hash\n"); */ pchain[i] = UNDEF; counts_array[i].caller = caller; counts_array[i].callee = callee; counts_array[i].caller_name_idx = enter_str(caller_name); counts_array[i].callee_name_idx = enter_str(callee_name); counts_array[i].count = 1; h_tab.nchain++; num_counts++; return; }