bool find_next_marked_object(gc_mark_table_iterator* itr, os_pointer* obj, os_word* obj_len) { long obj_start = 0; long obj_len_words = 0; while(!find_next_run(&itr->bit_itr, &obj_start, &obj_len_words)) { gc_page* page = page_for_pointer(itr->heap, itr->current_point); gc_page* next_page = next_queued_page(itr->queue, page); if(!next_page) return false; itr->current_point = pointer_for_page(itr->heap, next_page); begin_bit_run_iteration_on_page(itr->heap, itr->table, &itr->bit_itr, itr->current_point, itr->final_point); } *obj = itr->heap->heap_memory + words_to_bytes(obj_start); *obj_len = words_to_bytes(obj_len_words); return true; }
const char* test_bit_table() { gc_bit_table table; initialize_bit_table(&table, 1023); if(table.bit_count != 1023) return "initialize failed"; set_bit(&table, 67); if(table.bits[1] != 0x8) return "set bit 1 failed"; set_bit(&table, 68); if(table.bits[1] != 0x18) return "set bit 2 failed"; clear_bit(&table, 67); if(table.bits[1] != 0x10) return "clear bit 1 failed"; set_bit(&table, 64); set_bit(&table, 63); if(table.bits[0] != 9223372036854775808UL || table.bits[1] != 0x11) { return "set bit 3 failed"; } if(!is_bit_set(&table, 63)) return "get bit 1 failed"; if(!is_bit_set(&table, 64)) return "get bit 2 failed"; if(!is_bit_set(&table, 68)) return "get bit 3 failed"; if(find_first_set_bit(&table, 0, 1023) != 63) return "find first set bit 1 failed"; if(find_first_set_bit(&table, 64, 1023) != 64) return "find first set bit 2 failed"; if(find_first_set_bit(&table, 65, 1023) != 68) return "find first set bit 3 failed"; set_bit(&table, 73); // at this point, 63, 64, 68, and 73 are set long start_table[] = {63, 68}; long len_table[] = {2, 6}; gc_bit_run_iterator itr; begin_run_iteration(&table, &itr, 0, 100); long start = 0; long len = 0; long idx = 0; while(find_next_run(&itr, &start, &len)) { if((start != start_table[idx]) || (len != len_table[idx])) return "run iteration 1 failed"; ++idx; } for(int i = 256; i < 768; ++i) set_bit(&table, i); clear_run(&table, 320, 128); clear_run(&table, 450, 200); for(int i = 256; i < 768; ++i) { if(i >= 256 && i < 320 && !is_bit_set(&table, i)) return "clear run 1 failed"; if(i >= 320 && i < 448 && is_bit_set(&table, i)) return "clear run 1 failed"; if(i >= 448 && i < 450 && !is_bit_set(&table, i)) return "clear run 1 failed"; if(i >= 450 && i < 650 && is_bit_set(&table, i)) return "clear run 2 failed"; if(i >= 650 && !is_bit_set(&table, i)) return "clear run 2 failed"; } finalize_bit_table(&table); return "passed"; }
static bool list_nextvol(UAContext *ua, int ndays) { JOBRES *job; JCR *jcr; USTORERES store; RUNRES *run; utime_t runtime; bool found = false; MEDIA_DBR mr; POOL_DBR pr; int i = find_arg_with_value(ua, "job"); if (i <= 0) { if ((job = select_job_resource(ua)) == NULL) { return false; } } else { job = (JOBRES *)GetResWithName(R_JOB, ua->argv[i]); if (!job) { Jmsg(ua->jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]); if ((job = select_job_resource(ua)) == NULL) { return false; } } } jcr = new_jcr(sizeof(JCR), dird_free_jcr); for (run=NULL; (run = find_next_run(run, job, runtime, ndays)); ) { if (!complete_jcr_for_job(jcr, job, run->pool)) { found = false; goto get_out; } if (!jcr->jr.PoolId) { ua->error_msg(_("Could not find Pool for Job %s\n"), job->name()); continue; } memset(&pr, 0, sizeof(pr)); pr.PoolId = jcr->jr.PoolId; if (!db_get_pool_record(jcr, jcr->db, &pr)) { bstrncpy(pr.Name, "*UnknownPool*", sizeof(pr.Name)); } mr.PoolId = jcr->jr.PoolId; get_job_storage(&store, job, run); set_storageid_in_mr(store.store, &mr); /* no need to set ScratchPoolId, since we use fnv_no_create_vol */ if (!find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_prune)) { ua->error_msg(_("Could not find next Volume for Job %s (Pool=%s, Level=%s).\n"), job->name(), pr.Name, level_to_str(run->level)); } else { ua->send_msg( _("The next Volume to be used by Job \"%s\" (Pool=%s, Level=%s) will be %s\n"), job->name(), pr.Name, level_to_str(run->level), mr.VolumeName); found = true; } } get_out: if (jcr->db) { db_sql_close_pooled_connection(jcr, jcr->db); jcr->db = NULL; } free_jcr(jcr); if (!found) { ua->error_msg(_("Could not find next Volume for Job %s.\n"), job->hdr.name); return false; } return true; }