예제 #1
0
static uint32_t get_next_id(void)
{
    uint64_t id = 0;
    char* lock_record = NULL;
    char* record = NULL;

    // Find a valid ID for our next semaphore

    // This lock makes sure that we don't
    // have concurrent access to sem.ids
    errval_t err = oct_lock("sem.lock", &lock_record);
    assert(err_is_ok(err));

    err = oct_get(&record, "sem.ids { current_id: _ }");
    if (err_is_ok(err)) {
        err = oct_read(record, "_ { current_id: %d }", &id);
        assert(err_is_ok(err));
    }
    else if (err_no(err) == OCT_ERR_NO_RECORD) {
        err = oct_set("sem.ids { current_id: 0 }");
        assert(err_is_ok(err));
    }
    else {
        assert(!"Should not happen.");
    }

    id += 1;

    err = oct_set("sem.ids { current_id: %lu }", id);
    assert(err_is_ok(err));

    err = oct_unlock(lock_record);
    free(lock_record);
    free(record);
    assert(err_is_ok(err));

    return id;
}
예제 #2
0
/**
 * \brief Non-blocking name service lookup
 *
 * \param iface Name of interface for which to query name server
 * \param retiref Returns pointer to IREF on success
 */
errval_t nameservice_lookup(const char *iface, iref_t *retiref)
{
    errval_t err;

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    if (r == NULL) {
        return LIB_ERR_NAMESERVICE_NOT_BOUND;
    }

    char* record = NULL;
    octopus_trigger_id_t tid;
    errval_t error_code;
    err = r->vtbl.get(r, iface, NOP_TRIGGER, &record, &tid, &error_code);
    if (err_is_fail(err)) {
        goto out;
    }
    err = error_code;
    if (err_is_fail(err)) {
        if (err_no(err) == OCT_ERR_NO_RECORD) {
            err = err_push(err, LIB_ERR_NAMESERVICE_UNKNOWN_NAME);
        }
        goto out;
    }

    uint64_t iref_number = 0;
    err = oct_read(record, "_ { iref: %d }", &iref_number);
    if (err_is_fail(err) || iref_number == 0) {
        err = err_push(err, LIB_ERR_NAMESERVICE_INVALID_NAME);
        goto out;
    }
    if (retiref != NULL) {
        *retiref = iref_number;
    }

out:
    free(record);
    return err;
}
예제 #3
0
static void cpu_change_event(octopus_mode_t mode, char* record, void* state)
{
    if (mode & OCT_ON_SET) {
        KALUGA_DEBUG("CPU found: %s\n", record);
        assert(my_core_id == 0); // TODO(gz): why?

        uint64_t barrelfish_id, arch_id, enabled = 0;
        errval_t err = oct_read(record, "_ { barrelfish_id: %d, apic_id: %d, enabled: %d }",
                                &barrelfish_id, &arch_id, &enabled);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "Cannot read record.");
            assert(!"Illformed core record received");
            goto out;
        }

        struct module_info* mi = find_module("corectrl");
        if (mi != NULL) {
            err = mi->start_function(0, mi, record);
            if (err_is_fail(err)) {
                printf("Boot driver not found. Do not boot discovered CPU %"PRIu64".\n",
                       barrelfish_id);
                goto out;
            }
            assert(err_is_ok(err));
        }

    }
    if (mode & OCT_ON_DEL) {
        KALUGA_DEBUG("CPU removed: %s\n", record);
        assert(!"NYI");
    }

out:
    assert(!(mode & OCT_REMOVED));
    free(record);
}
예제 #4
0
errval_t start_networking(coreid_t core,
                          struct module_info* driver,
                          char* record)
{
    assert(driver != NULL);
    errval_t err = SYS_ERR_OK;

    uint64_t vendor_id, device_id, bus, dev, fun;

    /* check if we are using the supplied pci address of eth0 */
    if (eth0.bus != 0xff || eth0.device != 0xff || eth0.function != 0xff) {
        err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }",
                            &bus, &dev, &fun, &vendor_id, &device_id);
        assert(err_is_ok(err));

        if ((eth0.bus != (uint8_t)bus)
             | (eth0.device != (uint8_t)dev)
             | (eth0.function != (uint8_t)fun)) {
            KALUGA_DEBUG("start_networking: skipping card %" PRIu64 ":% "PRIu64 ":% "
                         PRIu64"\n", bus, dev, fun);
            return KALUGA_ERR_DRIVER_NOT_AUTO;
        }
    }

    if (is_started(driver)) {
        return KALUGA_ERR_DRIVER_ALREADY_STARTED;
    }

    if (!is_auto_driver(driver)) {
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    struct module_info* netd = find_module("netd");
    if (netd == NULL || !is_auto_driver(netd)) {
        KALUGA_DEBUG("netd not found or not declared as auto.");
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    struct module_info* ngd_mng = find_module("NGD_mng");
    if (ngd_mng == NULL || !is_auto_driver(ngd_mng)) {
        KALUGA_DEBUG("NGD_mng not found or not declared as auto.");
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    err = default_start_function(core, driver, record);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "Spawning %s failed.", driver->path);
        return err;
    }

    // XXX: Manually add cardname (overwrite first (auto) argument)
    // +Weird convention, e1000n binary but cardname=e1000
    char* cardname = strcmp(driver->binary, "e1000n") == 0 ? "e1000" : driver->binary;

    size_t name_len = strlen("cardname=") + strlen(cardname) + 1;
    char* card_argument = malloc(name_len);
    sprintf(card_argument, "cardname=%s", cardname);
    printf("############# starting network with arguments %s\n", card_argument);

    // Spawn netd and ngd_mng
    netd->argv[0] = card_argument;
    err = spawn_program(core, netd->path, netd->argv, environ, 0, get_did_ptr(netd));

    ngd_mng->argv[0] = card_argument;
    err = spawn_program(core, ngd_mng->path, ngd_mng->argv, environ, 0,
                        get_did_ptr(ngd_mng));

    free(card_argument);
    return err;
}
예제 #5
0
/**
 * \brief Leave a barrier. Blocks until all involved parties have
 * called oct_barrier_leave().
 *
 * Client deletes its barrier record. In case the client
 * was the last one we delete the special record which
 * wakes up all other clients.
 *
 * \param barrier_record Clients own record as provided by
 * oct_barrier_enter.
 */
errval_t oct_barrier_leave(const char* barrier_record)
{
    errval_t exist_err;
    errval_t err;
    char* rec_name = NULL;
    char* barrier_name = NULL;
    char* record = NULL;
    char** names = NULL;
    size_t remaining_barriers = 0;
    uint64_t mode = 0;
    uint64_t state = 0;
    uint64_t fn = 0;
    octopus_trigger_id_t tid;
    octopus_trigger_t t = oct_mktrigger(SYS_ERR_OK, octopus_BINDING_RPC,
            OCT_ON_DEL, NULL, NULL);

    //debug_printf("leaving: %s\n", barrier_record);
    err = oct_read(barrier_record, "%s { barrier: %s }", &rec_name,
            &barrier_name);
    if (err_is_ok(err)) {
        err = oct_del(rec_name);
        if (err_is_fail(err)) {
            goto out;
        }

        err = oct_get_names(&names, &remaining_barriers, "_ { barrier: '%s' }",
                barrier_name);
        oct_free_names(names, remaining_barriers);

        //debug_printf("remaining barriers is: %lu\n", remaining_barriers);

        if (err_is_ok(err)) {
            struct octopus_thc_client_binding_t* cl = oct_get_thc_client();
            err = cl->call_seq.exists(cl, barrier_name, t, &tid, &exist_err);
            if (err_is_fail(err)) {
                goto out;
            }
            err = exist_err;

            if (err_is_ok(err)) {
                // Wait until everyone has left the barrier
                err = cl->recv.trigger(cl, &tid, &fn, &mode, &record, &state);
                assert(mode & OCT_REMOVED);
            }
            else if (err_no(err) == OCT_ERR_NO_RECORD) {
                // barrier already deleted
                err = SYS_ERR_OK;
            }
        }
        else if (err_no(err) == OCT_ERR_NO_RECORD) {
            // We are the last one to leave the barrier,
            // wake-up all others
            err = oct_del("%s", barrier_name);
        }
        else {
            // Just return the error
        }
    }

out:
    free(record);
    free(rec_name);
    free(barrier_name);
    return err;
}
예제 #6
0
errval_t start_boot_driver(coreid_t where, struct module_info* mi,
                           char* record)
{
    assert(mi != NULL);
    errval_t err = SYS_ERR_OK;

    if (!is_auto_driver(mi)) {
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    // Construct additional command line arguments containing pci-id.
    // We need one extra entry for the new argument.
    uint64_t barrelfish_id, apic_id, cpu_type;
    char **argv = mi->argv;
    bool cleanup = false;
    char barrelfish_id_s[10];
    size_t argc = mi->argc;

    KALUGA_DEBUG("Starting corectrl for %s\n", record);
    err = oct_read(record, "_ { apic_id: %d, barrelfish_id: %d, type: %d }",
                   &apic_id, &barrelfish_id, &cpu_type);
    if (err_is_ok(err)) {
        skb_add_fact("corename(%"PRIu64", %s, apic(%"PRIu64")).",
                     barrelfish_id, cpu_type_to_archstr(cpu_type), apic_id);
        if (barrelfish_id == my_core_id) {
            return SYS_ERR_OK;
        }

        argv = malloc((argc+5) * sizeof(char *));
        memcpy(argv, mi->argv, argc * sizeof(char *));
        snprintf(barrelfish_id_s, 10, "%"PRIu64"", barrelfish_id);

        argv[argc] = "boot";
        argc += 1;
        argv[argc] = barrelfish_id_s;
        argc += 1;
        // Copy kernel args over to new core
        struct module_info* cpu_module = find_module("cpu");
        if (cpu_module != NULL && strlen(cpu_module->args) > 1) {
            KALUGA_DEBUG("%s:%s:%d: Boot with cpu arg %s and barrelfish_id_s=%s\n",
                         __FILE__, __FUNCTION__, __LINE__, cpu_module->args, barrelfish_id_s);
            argv[argc] = "-a";
            argc += 1;
            argv[argc] = cpu_module->args;
            argc += 1;
        }
        argv[argc] = NULL;

        cleanup = true;
    }
    else {
        DEBUG_ERR(err, "Malformed CPU record?");
        return err;
    }

    struct capref task_cap_kernel;
    task_cap_kernel.cnode = cnode_task;
    task_cap_kernel.slot = TASKCN_SLOT_KERNELCAP;

#ifdef KALUGA_SERVICE_DEBUG
    struct capability info;
    err = debug_cap_identify(task_cap_kernel, &info);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Can not identify the capability.");
    }
    char buffer[1024];
    debug_print_cap(buffer, 1024, &info);
    KALUGA_DEBUG("%s:%d: capability=%s\n", __FILE__, __LINE__, buffer);
#endif

    struct capref inheritcn_cap;
    err = alloc_inheritcn_with_caps(&inheritcn_cap,
                                    NULL_CAP, NULL_CAP, task_cap_kernel);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "alloc_inheritcn_with_caps failed.");
    }

    err = spawn_program_with_caps(where, mi->path, argv,
                                  environ, inheritcn_cap,
                                  NULL_CAP, SPAWN_FLAGS_NEW_DOMAIN,
                                  &mi->did[0]);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "Spawning %s failed.", mi->path);
    }

    if (cleanup) {
        free(argv);
    }

    return err;
}
예제 #7
0
void gen_oct(MESH *m, char *filename)
{
	// place each point into the oct-tree
	OctTree *tree = oct_new(100000, 500000);
	int depth = 6;
	float total = (float)(B_EDGE-1) / (float)B_EDGE;
	
	for(int i=0; i<m->nv; i++)
	{
		F3MULS(m->v[i], m->v[i], total);
		int leaf = oct_leaf(tree, &m->v[i], depth);
		ListInt2 *tmp = malloc(sizeof(ListInt2));
		tmp->x = i;
		tmp->y = tree->brick[leaf].nv;
		tmp->next = tree->brick[leaf].v;
		tree->brick[leaf].v = tmp;
		tree->brick[leaf].nv++;
	}
	depth++;

	printf("TreeBlock/Brick = (%d %d)\n",
			tree->blockcount, tree->brickcount);

//	tree->brickcount ++;
	unsigned int buf_size = 16*B_CUBE;
	float4 (*bricktex)[B_EDGE][B_EDGE] = malloc(buf_size);
	memset(bricktex, 0, buf_size);
	int3 index;
	int3 itmp;
	int id, idt;
	ListInt2 *tmp;


	printf("Generating Voxel bricks.\n");
	int lastbrickcount = tree->brickcount;
	for(int i=0; i<lastbrickcount; i++)
	{
//		printf("Brick #%d. %d\n", i, tree->brick[i].nv);
		tmp = tree->brick[i].v;
		if(tmp)
		for(int j=0; j<tree->brick[i].nv && tmp; j++) //while(tmp)
		{
			index.x = ((int)(m->v[tmp->x].x * (7<<depth)) % (B_SIZE-1))+1;
			index.y = ((int)(m->v[tmp->x].y * (7<<depth)) % (B_SIZE-1))+1;
			index.z = ((int)(m->v[tmp->x].z * (7<<depth)) % (B_SIZE-1))+1;
			id = i;
			itmp.x = id % B_COUNT;
			idt = (id-itmp.x) / B_COUNT;
			itmp.y = idt % B_COUNT;
			itmp.z = (idt-itmp.y) / B_COUNT;
			F3MULS(itmp, itmp, (B_SIZE));
			F3ADD(index, index, itmp);
			F3COPY(bricktex[index.z][index.y][index.x], m->n[tmp->x]);
			bricktex[index.z][index.y][index.x].w = 1.0f;
			tmp = tmp->next;
		}

	}

	printf("Copy neighbour voxels.\n");
	for(int i=1; i<tree->brickcount; i++)
	{
		float size = tree->location[i].w;
		int3 d,s;
		d.x = i % B_COUNT;
		idt = (i-d.x) / B_COUNT;
		d.y = idt % B_COUNT;
		d.z = (idt-d.y) / B_COUNT;
		F3MULS(d, d, B_SIZE);

		int src;
		float3 pos;

		F3COPY(pos, tree->location[i]);
		pos.x += size*1.5;
		pos.y += size * 0.5;
		pos.z += size * 0.5;
		src = oct_read(tree, &pos);
		if(src)
		{
			s.x = src % B_COUNT;
			idt = (src-s.x) / B_COUNT;
			s.y = idt % B_COUNT;
			s.z = (idt-s.y) / B_COUNT;
			F3MULS(s, s, B_SIZE);

			for(int x=0; x<B_SIZE; x++)
			for(int y=0; y<B_SIZE; y++)
			{
		bricktex[s.z+x][s.y+y][s.x] = bricktex[d.z+x][d.y+y][d.x+7];
			}
		}

		F3COPY(pos, tree->location[i]);
		pos.x += size*0.5;
		pos.y += size*1.5;
		pos.z += size*0.5;
		src = oct_read(tree, &pos);
		if(src)
		{
			s.x = src % B_COUNT;
			idt = (src-s.x) / B_COUNT;
			s.y = idt % B_COUNT;
			s.z = (idt-s.y) / B_COUNT;
			F3MULS(s, s, B_SIZE);

			for(int x=1; x<B_SIZE; x++)
			for(int y=1; y<B_SIZE; y++)
			{
		bricktex[s.z+x][s.y][s.x+y] = bricktex[d.z+x][d.y+7][d.x+y];
			}
		}

		F3COPY(pos, tree->location[i]);
		pos.x += size*0.5;
		pos.y += size*0.5;
		pos.z += size*1.5;
		src = oct_read(tree, &pos);
		if(src)
		{
			s.x = src % B_COUNT;
			idt = (src-s.x) / B_COUNT;
			s.y = idt % B_COUNT;
			s.z = (idt-s.y) / B_COUNT;
			F3MULS(s, s, B_SIZE);

			for(int x=1; x<B_SIZE; x++)
			for(int y=1; y<B_SIZE; y++)
			{
			bricktex[s.z][s.y+x][s.x+y] = bricktex[d.z+7][d.y+x][d.x+y];
			}
		}


		F3COPY(pos, tree->location[i]);
		pos.x += size*1.5;
		pos.y += size*1.5;
		pos.z += size*0.5;
		src = oct_read(tree, &pos);
		if(src)
		{
			s.x = src % B_COUNT;
			idt = (src-s.x) / B_COUNT;
			s.y = idt % B_COUNT;
			s.z = (idt-s.y) / B_COUNT;
			F3MULS(s, s, B_SIZE);

			for(int x=1; x<B_SIZE; x++)
			{
			bricktex[s.z+x][s.y][s.x] = bricktex[d.z+x][d.y+7][d.x+7];
			}
		}


		F3COPY(pos, tree->location[i]);
		pos.x += size*1.5;
		pos.y += size*0.5;
		pos.z += size*1.5;
		src = oct_read(tree, &pos);
		if(src)
		{
			s.x = src % B_COUNT;
			idt = (src-s.x) / B_COUNT;
			s.y = idt % B_COUNT;
			s.z = (idt-s.y) / B_COUNT;
			F3MULS(s, s, B_SIZE);

			for(int x=1; x<B_SIZE; x++)
			{
			bricktex[s.z][s.y+x][s.x] = bricktex[d.z+7][d.y+x][d.x+7];
			}
		}

		F3COPY(pos, tree->location[i]);
		pos.x += size*0.5;
		pos.y += size*1.5;
		pos.z += size*1.5;
		src = oct_read(tree, &pos);
		if(src)
		{
			s.x = src % B_COUNT;
			idt = (src-s.x) / B_COUNT;
			s.y = idt % B_COUNT;
			s.z = (idt-s.y) / B_COUNT;
			F3MULS(s, s, B_SIZE);

			for(int x=1; x<B_SIZE; x++)
			{
			bricktex[s.z][s.y][s.x+x] = bricktex[d.z+7][d.y+7][d.x+x];
			}
		}

		F3COPY(pos, tree->location[i]);
		pos.x += size*1.5;
		pos.y += size*1.5;
		pos.z += size*1.5;
		src = oct_read(tree, &pos);
		if(src)
		{
			s.x = src % B_COUNT;
			idt = (src-s.x) / B_COUNT;
			s.y = idt % B_COUNT;
			s.z = (idt-s.y) / B_COUNT;
			F3MULS(s, s, B_SIZE);

			bricktex[s.z][s.y][s.x] = bricktex[d.z+7][d.y+7][d.x+7];
		}

	}
	printf("TreeBlock/Brick = (%d %d)\n",
			tree->blockcount, tree->brickcount);
	printf("Walking the normals.\n");
	for(int i=1; i<tree->brickcount; i++)
	{
		

	}

	printf("Writing \"%s\".\n", filename);
	FILE *fptr = fopen(filename, "wb");
	int zero = 0;
	fwrite("VOCT", 4, 1, fptr);
	fwrite(&tree->blockcount, 4, 1, fptr);
	fwrite(&tree->brickcount, 4, 1, fptr);
	fwrite(&zero, 4, 1, fptr);
	fwrite(tree->block, tree->blockcount, sizeof(OctBlock), fptr);

	z_stream strm = { .zalloc=Z_NULL, .zfree=Z_NULL, .opaque=Z_NULL };
	int ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
	if(ret != Z_OK)
	{
		printf("deflateInit() failed.\n");
		return;
	}
#define CHUNK (256 * 1024)
	unsigned char in[CHUNK];
	unsigned char out[CHUNK];
	int row = sizeof(float4)*B_SIZE;

	int have, inoff = 0;
	for(int i=0; i<tree->brickcount; i++)
	{
		int3 boff;
		int itmp = i % B_COUNT;
		boff.x = itmp;
		itmp = (i-boff.x) / B_COUNT;
		boff.y = itmp % B_COUNT;
		boff.z = (itmp-boff.y) / B_COUNT;
		F3MULS(boff, boff, B_SIZE);
		for(int z=0; z < B_SIZE; z++)
		for(int y=0; y < B_SIZE; y++)
		{
			memcpy(in+inoff, &bricktex[boff.z+z][boff.y+y][boff.x], row);
			inoff += row;
			if(inoff+row > CHUNK)
			{
				strm.next_in = in;
				strm.avail_in = inoff;
				do{
					strm.avail_out = CHUNK;
					strm.next_out = out;
					ret = deflate(&strm, Z_NO_FLUSH);
//					assert(ret != Z_STREAM_ERROR);
					have = CHUNK - strm.avail_out;
					fwrite(out, have, 1, fptr);
				} while (strm.avail_out == 0);
//				assert(strm.avail_in == 0);
				inoff = 0;
			}
//		fwrite(&bricktex[boff.z+z][boff.y+y][boff.x],
//				sizeof(float4)*B_SIZE, 1, fptr);
		}
	}
	strm.next_in = in;
	strm.avail_in = inoff;
	do{
		strm.avail_out = CHUNK;
		strm.next_out = out;
		ret = deflate(&strm, Z_FINISH);
//		assert(ret != Z_STREAM_ERROR);
		have = CHUNK - strm.avail_out;
		fwrite(out, have, 1, fptr);
	} while (strm.avail_out == 0);
//	assert(strm.avail_in == 0);
	deflateEnd(&strm);

//	fwrite(bricktex, 16*B_CUBE, 1, fptr);
//	fwrite(bricktex[B_EDGE], 16*B_CUBE, 1, fptr);
	fclose(fptr);
}
예제 #8
0
/**
 * \brief executes a lookup query on octopus to obtain the symbol
 *
 * \param binary    name of the binary to query
 * \param idx       index of the symbol to query
 * \param ret_name  returns the name of the symbol
 * \param ret_addr  returns the address of the symbol
 *
 * \return
 */
errval_t spawn_symval_lookup(const char *binary,
                             uint32_t idx,
                             char **ret_name,
                             genvaddr_t *ret_addr)
{
    errval_t err;

    size_t len;

    len = snprintf(NULL, 0, "%s.omp.%"PRIu32, binary, idx);
    char *omp_entry = malloc(len+1);
    if (omp_entry == NULL) {
        return LIB_ERR_MALLOC_FAIL;
    }
    snprintf(omp_entry, len+1, "%s.omp.%"PRIu32, binary, idx);

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    if (r == NULL) {
        return LIB_ERR_NAMESERVICE_NOT_BOUND;
    }

    // transform to lower case
    for (int i = 0; i < len; ++i) {
        if (omp_entry[i] >= 'A' && omp_entry[i] <= 'Z') {
            omp_entry[i] -= ('A' - 'a');
        }
    }

    char* record = NULL;
    octopus_trigger_id_t tid;
    errval_t error_code;
    err = r->vtbl.get(r, omp_entry, NOP_TRIGGER,
                      &record, &tid, &error_code);
    if (err_is_fail(err)) {
        goto out;
    }
    err = error_code;
    if (err_is_fail(err)) {
        if (err_no(err) == OCT_ERR_NO_RECORD) {
            err = err_push(err, LIB_ERR_NAMESERVICE_UNKNOWN_NAME);
        }
        goto out;
    }

    uint64_t addr = 0;
    char *symname = NULL;
    err = oct_read(record, "_ { sym: %s, addr: %d }", &symname, &addr);
    if (err_is_fail(err) || symname == NULL) {
        err = err_push(err, LIB_ERR_NAMESERVICE_INVALID_NAME);
        goto out;
    }
    if (ret_addr != NULL) {
        *ret_addr = addr;
    }
    if (ret_name != NULL) {
        *ret_name = strdup(symname);
    }

    out: free(record);
    free(omp_entry);
    return err;
}