예제 #1
0
static int mips_sys_brk_impl(struct mips_ctx_t *ctx)
{
	struct mips_regs_t *regs = ctx->regs;
	struct mem_t *mem = ctx->mem;

	unsigned int old_heap_break;
	unsigned int new_heap_break;
	unsigned int size;

	unsigned int old_heap_break_aligned;
	unsigned int new_heap_break_aligned;

	/* Arguments */
	new_heap_break = regs->regs_R[4];
	old_heap_break = mem->heap_break;
	mips_sys_debug("  newbrk=0x%x (previous brk was 0x%x)\n",
		new_heap_break, old_heap_break);

	/* Align */
	new_heap_break_aligned = ROUND_UP(new_heap_break, MEM_PAGE_SIZE);
	old_heap_break_aligned = ROUND_UP(old_heap_break, MEM_PAGE_SIZE);

	/* If argument is zero, the system call is used to
	 * obtain the current top of the heap. */
	if (!new_heap_break)
		return old_heap_break;

	/* If the heap is increased: if some page in the way is
	 * allocated, do nothing and return old heap top. Otherwise,
	 * allocate pages and return new heap top. */
	if (new_heap_break > old_heap_break)
	{
		size = new_heap_break_aligned - old_heap_break_aligned;
		if (size)
		{
			if (mem_map_space(mem, old_heap_break_aligned, size) != old_heap_break_aligned)
				fatal("%s: out of memory", __FUNCTION__);
			mem_map(mem, old_heap_break_aligned, size,
				mem_access_read | mem_access_write);
		}
		mem->heap_break = new_heap_break;
		mips_sys_debug("  heap grows %u bytes\n", new_heap_break - old_heap_break);
		return new_heap_break;
	}

	/* Always allow to shrink the heap. */
	if (new_heap_break < old_heap_break)
	{
		size = old_heap_break_aligned - new_heap_break_aligned;
		if (size)
			mem_unmap(mem, new_heap_break_aligned, size);
		mem->heap_break = new_heap_break;
		mips_sys_debug("  heap shrinks %u bytes\n", old_heap_break - new_heap_break);
		return new_heap_break;
	}

	/* Heap stays the same */
	return 0;
}
예제 #2
0
/* Load sections from an ELF file */
void X86ContextLoadELFSections(X86Context *self, struct elf_file_t *elf_file)
{
	struct mem_t *mem = self->mem;
	struct x86_loader_t *loader = self->loader;

	struct elf_section_t *section;
	int i;

	enum mem_access_t perm;
	char flags_str[200];

	x86_loader_debug("\nLoading ELF sections\n");
	loader->bottom = 0xffffffff;
	for (i = 0; i < list_count(elf_file->section_list); i++)
	{
		section = list_get(elf_file->section_list, i);

		perm = mem_access_init | mem_access_read;
		str_map_flags(&elf_section_flags_map, section->header->sh_flags,
				flags_str, sizeof(flags_str));
		x86_loader_debug("  section %d: name='%s', offset=0x%x, "
				"addr=0x%x, size=%u, flags=%s\n",
				i, section->name, section->header->sh_offset,
				section->header->sh_addr, section->header->sh_size, flags_str);

		/* Process section */
		if (section->header->sh_flags & SHF_ALLOC)
		{
			/* Permissions */
			if (section->header->sh_flags & SHF_WRITE)
				perm |= mem_access_write;
			if (section->header->sh_flags & SHF_EXECINSTR)
				perm |= mem_access_exec;

			/* Load section */
			mem_map(mem, section->header->sh_addr, section->header->sh_size, perm);
			mem->heap_break = MAX(mem->heap_break, section->header->sh_addr
				+ section->header->sh_size);
			loader->bottom = MIN(loader->bottom, section->header->sh_addr);

			/* If section type is SHT_NOBITS (sh_type=8), initialize to 0.
			 * Otherwise, copy section contents from ELF file. */
			if (section->header->sh_type == 8)
			{
				void *ptr;

				ptr = xcalloc(1, section->header->sh_size);
				mem_access(mem, section->header->sh_addr,
						section->header->sh_size,
						ptr, mem_access_init);
				free(ptr);
			} else {
				mem_access(mem, section->header->sh_addr,
						section->header->sh_size,
						section->buffer.ptr, mem_access_init);
			}
		}
	}
}
예제 #3
0
파일: uc.c 프로젝트: charlieyqin/unicorn
UNICORN_EXPORT
uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms)
{
    uc_err res;

    if (uc->mem_redirect) {
        address = uc->mem_redirect(address);
    }

    res = mem_map_check(uc, address, size, perms);
    if (res)
        return res;

    return mem_map(uc, address, size, perms, uc->memory_map(uc, address, size, perms));
}
예제 #4
0
파일: uc.c 프로젝트: charlieyqin/unicorn
UNICORN_EXPORT
uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, uint32_t perms, void *ptr)
{
    uc_err res;

    if (ptr == NULL)
        return UC_ERR_ARG;

    if (uc->mem_redirect) {
        address = uc->mem_redirect(address);
    }

    res = mem_map_check(uc, address, size, perms);
    if (res)
        return res;

    return mem_map(uc, address, size, UC_PROT_ALL, uc->memory_map_ptr(uc, address, size, perms, ptr));
}
예제 #5
0
파일: trs_memory.c 프로젝트: apuder/TRS-80
void mem_init()
{
    if (trs_model <= 3) {
	rom = &memory[ROM_START];
	video = &memory[VIDEO_START];
	trs_video_size = 1024;
    } else {
	rom = rom_4;
	video = video_4;
	trs_video_size = MAX_VIDEO_SIZE;
    }
    mem_map(0);
    mem_bank(0);
    mem_video_page(0);
    if (trs_model == 5) {
	z80_out(0x9C, 1);
    }
}
예제 #6
0
파일: mem_process.c 프로젝트: AbhiramiP/ltp
int main(int argc, char **argv)
{
	int ret;
	char ch;

	process_options(argc, argv);

	ret = mkfifo(STATUS_PIPE, 0666);

	if (ret == -1 && errno != EEXIST)
		errx(1, "Error creating named pipe");

	do {
		ch = action();

		if (ch == 'm')
			mem_map();
	} while (ch != 'x');

	remove(STATUS_PIPE);

	return 0;
}
예제 #7
0
static int mips_sys_mmap(struct mips_ctx_t *ctx, unsigned int addr, unsigned int len,
	int prot, int flags, int guest_fd, int offset)
{
	struct mem_t *mem = ctx->mem;

	unsigned int len_aligned;

	int perm;
	int host_fd;

	struct mips_file_desc_t *desc;

	/* Check that protection flags match in guest and host */
	assert(PROT_READ == 1);
	assert(PROT_WRITE == 2);
	assert(PROT_EXEC == 4);

	/* Check that mapping flags match */
	assert(MAP_SHARED == 0x01);
	assert(MAP_PRIVATE == 0x02);
	assert(MAP_FIXED == 0x10);
	assert(MAP_ANONYMOUS == 0x20);

	/* Translate file descriptor */
	desc = mips_file_desc_table_entry_get(ctx->file_desc_table, guest_fd);
	host_fd = desc ? desc->host_fd : -1;
	if (guest_fd > 0 && host_fd < 0)
		fatal("%s: invalid guest descriptor", __FUNCTION__);

	/* Permissions */
	perm = mem_access_init;
	perm |= prot & PROT_READ ? mem_access_read : 0;
	perm |= prot & PROT_WRITE ? mem_access_write : 0;
	perm |= prot & PROT_EXEC ? mem_access_exec : 0;

	/* Flag MAP_ANONYMOUS.
	 * If it is set, the 'fd' parameter is ignored. */
	if (flags & MAP_ANONYMOUS)
		host_fd = -1;

	/* 'addr' and 'offset' must be aligned to page size boundaries.
	 * 'len' is rounded up to page boundary. */
	if (offset & ~MEM_PAGE_MASK)
		fatal("%s: unaligned offset", __FUNCTION__);
	if (addr & ~MEM_PAGE_MASK)
		fatal("%s: unaligned address", __FUNCTION__);
	len_aligned = ROUND_UP(len, MEM_PAGE_SIZE);

	/* Find region for allocation */
	if (flags & MAP_FIXED)
	{
		/* If MAP_FIXED is set, the 'addr' parameter must be obeyed, and is not just a
		 * hint for a possible base address of the allocated range. */
		if (!addr)
			fatal("%s: no start specified for fixed mapping", __FUNCTION__);

		/* Any allocated page in the range specified by 'addr' and 'len'
		 * must be discarded. */
		mem_unmap(mem, addr, len_aligned);
	}
	else
	{
		if (!addr || mem_map_space_down(mem, addr, len_aligned) != addr)
			addr = SYS_MMAP_BASE_ADDRESS;
		addr = mem_map_space_down(mem, addr, len_aligned);
		if (addr == -1)
			fatal("%s: out of guest memory", __FUNCTION__);
	}

	/* Allocation of memory */
	mem_map(mem, addr, len_aligned, perm);

	/* Host mapping */
	if (host_fd >= 0)
	{
		char buf[MEM_PAGE_SIZE];

		unsigned int last_pos;
		unsigned int curr_addr;

		int size;
		int count;

		/* Save previous position */
		last_pos = lseek(host_fd, 0, SEEK_CUR);
		lseek(host_fd, offset, SEEK_SET);

		/* Read pages */
		assert(len_aligned % MEM_PAGE_SIZE == 0);
		assert(addr % MEM_PAGE_SIZE == 0);
		curr_addr = addr;
		for (size = len_aligned; size > 0; size -= MEM_PAGE_SIZE)
		{
			memset(buf, 0, MEM_PAGE_SIZE);
			count = read(host_fd, buf, MEM_PAGE_SIZE);
			if (count)
				mem_access(mem, curr_addr, MEM_PAGE_SIZE, buf, mem_access_init);
			curr_addr += MEM_PAGE_SIZE;
		}

		/* Return file to last position */
		lseek(host_fd, last_pos, SEEK_SET);
	}

	/* Return mapped address */
	return addr;
}
예제 #8
0
void X86ContextLoadStack(X86Context *self)
{
	struct x86_loader_t *loader = self->loader;
	struct mem_t *mem = self->mem;
	unsigned int sp, argc, argvp, envp;
	unsigned int zero = 0;
	char *str;
	int i;

	/* Allocate stack */
	loader->stack_base = X86_LOADER_STACK_BASE;
	loader->stack_size = X86_LOADER_STACK_SIZE;
	loader->stack_top = X86_LOADER_STACK_BASE - X86_LOADER_STACK_SIZE;
	mem_map(mem, loader->stack_top, loader->stack_size, mem_access_read | mem_access_write);
	x86_loader_debug("mapping region for stack from 0x%x to 0x%x\n",
		loader->stack_top, loader->stack_base - 1);
	
	/* Load arguments and environment variables */
	loader->environ_base = X86_LOADER_STACK_BASE - X86_LOADER_MAX_ENVIRON;
	sp = loader->environ_base;
	argc = linked_list_count(loader->args);
	x86_loader_debug("  saved 'argc=%d' at 0x%x\n", argc, sp);
	mem_write(mem, sp, 4, &argc);
	sp += 4;
	argvp = sp;
	sp = sp + (argc + 1) * 4;

	/* Save space for environ and null */
	envp = sp;
	sp += linked_list_count(loader->env) * 4 + 4;

	/* Load here the auxiliary vector */
	sp += X86ContextLoadAV(self, sp);

	/* Write arguments into stack */
	x86_loader_debug("\nArguments:\n");
	for (i = 0; i < argc; i++)
	{
		linked_list_goto(loader->args, i);
		str = linked_list_get(loader->args);
		mem_write(mem, argvp + i * 4, 4, &sp);
		mem_write_string(mem, sp, str);
		x86_loader_debug("  argument %d at 0x%x: '%s'\n", i, sp, str);
		sp += strlen(str) + 1;
	}
	mem_write(mem, argvp + i * 4, 4, &zero);

	/* Write environment variables */
	x86_loader_debug("\nEnvironment variables:\n");
	for (i = 0; i < linked_list_count(loader->env); i++)
	{
		linked_list_goto(loader->env, i);
		str = linked_list_get(loader->env);
		mem_write(mem, envp + i * 4, 4, &sp);
		mem_write_string(mem, sp, str);
		x86_loader_debug("  env var %d at 0x%x: '%s'\n", i, sp, str);
		sp += strlen(str) + 1;
	}
	mem_write(mem, envp + i * 4, 4, &zero);

	/* Random bytes */
	loader->at_random_addr = sp;
	for (i = 0; i < 16; i++)
	{
		unsigned char c = random();
		mem_write(mem, sp, 1, &c);
		sp++;
	}
	mem_write(mem, loader->at_random_addr_holder, 4, &loader->at_random_addr);

	/* Check that we didn't overflow */
	if (sp > X86_LOADER_STACK_BASE)
		fatal("%s: initial stack overflow, increment LD_MAX_ENVIRON",
			__FUNCTION__);
}
예제 #9
0
/* Load program headers table */
void X86ContextLoadProgramHeaders(X86Context *self)
{
	struct x86_loader_t *loader = self->loader;
	struct mem_t *mem = self->mem;

	struct elf_file_t *elf_file = loader->elf_file;
	struct elf_program_header_t *program_header;

	uint32_t phdt_base;
	uint32_t phdt_size;
	uint32_t phdr_count;
	uint32_t phdr_size;

	char str[MAX_STRING_SIZE];
	int i;

	/* Load program header table from ELF */
	x86_loader_debug("\nLoading program headers\n");
	phdr_count = elf_file->header->e_phnum;
	phdr_size = elf_file->header->e_phentsize;
	phdt_size = phdr_count * phdr_size;
	assert(phdr_count == list_count(elf_file->program_header_list));
	
	/* Program header PT_PHDR, specifying location and size of the program header table itself. */
	/* Search for program header PT_PHDR, specifying location and size of the program header table.
	 * If none found, choose loader->bottom - phdt_size. */
	phdt_base = loader->bottom - phdt_size;
	for (i = 0; i < list_count(elf_file->program_header_list); i++)
	{
		program_header = list_get(elf_file->program_header_list, i);
		if (program_header->header->p_type == PT_PHDR)
			phdt_base = program_header->header->p_vaddr;
	}
	x86_loader_debug("  virtual address for program header table: 0x%x\n", phdt_base);

	/* Load program headers */
	mem_map(mem, phdt_base, phdt_size, mem_access_init | mem_access_read);
	for (i = 0; i < list_count(elf_file->program_header_list); i++)
	{
		/* Load program header */
		program_header = list_get(elf_file->program_header_list, i);
		mem_access(mem, phdt_base + i * phdr_size, phdr_size,
			program_header->header, mem_access_init);

		/* Debug */
		str_map_value_buf(&elf_program_header_type_map, program_header->header->p_type,
			str, sizeof(str));
		x86_loader_debug("  header loaded at 0x%x\n", phdt_base + i * phdr_size);
		x86_loader_debug("    type=%s, offset=0x%x, vaddr=0x%x, paddr=0x%x\n",
			str, program_header->header->p_offset,
			program_header->header->p_vaddr,
			program_header->header->p_paddr);
		x86_loader_debug("    filesz=%d, memsz=%d, flags=%d, align=%d\n",
			program_header->header->p_filesz,
			program_header->header->p_memsz,
			program_header->header->p_flags,
			program_header->header->p_align);

		/* Program interpreter */
		if (program_header->header->p_type == 3)
		{
			mem_read_string(mem, program_header->header->p_vaddr, sizeof(str), str);
			loader->interp = str_set(NULL, str);
		}
	}

	/* Free buffer and save pointers */
	loader->phdt_base = phdt_base;
	loader->phdr_count = phdr_count;
}
예제 #10
0
파일: config.c 프로젝트: juliatuttle/tmips
int config_parse_args(config_t *cfg, int argc, char *argv[])
{
    int i;
    int saw_dump_file = 0;

    if (argc < 2) {
        debug_printf(CONFIG, WARNING,
                "Processors tend to be unhappy with nothing on their bus.\n"
                "(Run \"%s --help\" for more info.)\n", argv[0]);
    }

    for (i = 1; i < argc; ) {
        if (!strcmp(argv[i], "--region") || !strcmp(argv[i], "-r")) {
            uint32_t base, size;
            char *end;

            if (argc - i < 4) {
                debug_print(CONFIG, FATAL,
                        "--region: expected <base> <size> <readmemh-file>\n");
                return 1;
            }
            base = strtoul(argv[i + 1], &end, 16);
            if (*end != '\0') {
                debug_printf(CONFIG, FATAL,
                        "--region: invalid base \"%s\"\n", argv[i + 1]);
                return 1;
            }
            size = strtoul(argv[i + 2], &end, 16);
            if (*end != '\0') {
                debug_printf(CONFIG, FATAL,
                        "--region: invalid size \"%s\"\n", argv[i + 2]);
                return 1;
            }
            if (do_region(cfg->mem, base, size, argv[i + 3])) {
                return 1;
            }
            i += 4;
        } else if (!strcmp(argv[i], "--pc") || !strcmp(argv[i], "-p")) {
            uint32_t pc;
            char *end;

            if (argc - i < 2) {
                debug_print(CONFIG, FATAL, "--pc: expected <initial-pc>\n");
                return 1;
            }
            pc = strtoul(argv[i + 1], &end, 16);
            if (*end != '\0') {
                debug_printf(CONFIG, FATAL,
                        "--pc: invalid pc \"%s\"\n", argv[i + 1]);
                return 1;
            }
            cfg->pc = pc;
            i += 2;
        } else if (!strcmp(argv[i], "--dump") || !strcmp(argv[i], "-d")) {
            if (argc - i < 1) {
                debug_print(CONFIG, FATAL, "--dump: expected <dump-file>\n");
                return 1;
            }
            if (saw_dump_file) {
                debug_print(CONFIG, FATAL,
                        "--dump: may not be specified multiple times\n");
                return 1;
            }
            cfg->dump_file = fopen(argv[i + 1], "w");
            if (!cfg->dump_file) {
                debug_printf(CONFIG, FATAL,
                        "%s: %s\n", argv[i + 1], strerror(errno));
                return 1;
            }
            saw_dump_file = 1;
            i += 2;
        } else if (!strcmp(argv[i], "--console") || !strcmp(argv[i], "-c")) {
            uint32_t addr;
            char *end;

            if (argc - i < 2) {
                debug_print(CONFIG, FATAL, "--console: expected <addr>\n");
                return 1;
            }
            addr = strtoul(argv[i + 1], &end, 16);
            if (*end != '\0') {
                debug_printf(CONFIG, FATAL,
                        "--console: invalid addr \"%s\"\n", argv[i + 1]);
                return 1;
            }
            mem_map(cfg->mem, addr, serial_create(0, 1));
            i += 2;
        } else if (!strcmp(argv[i], "--filter") || !strcmp(argv[i], "-f")) {
            if (argc - i < 2) {
                debug_print(CONFIG, FATAL, "--filter: expected <filter>\n");
                return 1;
            }
            cfg->filter = filter_find(argv[i + 1]);
            if (!cfg->filter) {
                debug_printf(CONFIG, FATAL,
                        "--filter: unknown filter \"%s\"\n", argv[i + 1]);
                return 1;
            }
            i += 2;
        } else if (!strncmp(argv[i], "--filter=", 9)) {
            cfg->filter = filter_find(argv[i] + 9);
            if (!cfg->filter) {
                debug_printf(CONFIG, FATAL,
                        "--filter: unknown filter \"%s\"\n", argv[i] + 9);
                return 1;
            }
            i += 1;
        } else if (!strcmp(argv[i], "--step") || !strcmp(argv[i], "-s")) {
            cfg->step = 1;
            i += 1;
        } else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
            usage(argv[0]);
            return 1;
        } else if (!strcmp(argv[i], "--quiet") || !strcmp(argv[i], "-q")) {
            if (cfg->debug > 0) {
                debug_set_level(--cfg->debug);
            }
            i += 1;
        } else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v")) {
            if (cfg->debug < NUM_DEBUG_LEVELS - 1) {
                debug_set_level(++cfg->debug);
            }
            i += 1;
        } else if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-V")) {
            version();
            return 1;
        } else {
            debug_printf(CONFIG, FATAL, "Invalid argument \"%s\"\n", argv[i]);
            return 1;
        }
    }

    return 0;
}
예제 #11
0
파일: config.c 프로젝트: juliatuttle/tmips
static int do_region(mem_t *mem, uint32_t base, uint32_t size, char *file)
{
    mem_map(mem, base, ram_create(size));
    return readmemh_load(mem, base, file);
}
예제 #12
0
static int component_select(struct ompi_win_t *win, void **base, size_t size, int disp_unit,
                            struct ompi_communicator_t *comm, struct opal_info_t *info,
                            int flavor, int *model) {
    ompi_osc_ucx_module_t *module = NULL;
    char *name = NULL;
    long values[2];
    int ret = OMPI_SUCCESS;
    ucs_status_t status;
    int i, comm_size = ompi_comm_size(comm);
    int is_eps_ready;
    bool eps_created = false, worker_created = false;
    ucp_address_t *my_addr = NULL;
    size_t my_addr_len;
    char *recv_buf = NULL;
    void *rkey_buffer = NULL, *state_rkey_buffer = NULL;
    size_t rkey_buffer_size, state_rkey_buffer_size;
    void *state_base = NULL;
    void * my_info = NULL;
    size_t my_info_len;
    int disps[comm_size];
    int rkey_sizes[comm_size];

    /* the osc/sm component is the exclusive provider for support for
     * shared memory windows */
    if (flavor == MPI_WIN_FLAVOR_SHARED) {
        return OMPI_ERR_NOT_SUPPORTED;
    }

    /* if UCP worker has never been initialized before, init it first */
    if (mca_osc_ucx_component.ucp_worker == NULL) {
        ucp_worker_params_t worker_params;
        ucp_worker_attr_t worker_attr;

        memset(&worker_params, 0, sizeof(ucp_worker_h));
        worker_params.field_mask = UCP_WORKER_PARAM_FIELD_THREAD_MODE;
        worker_params.thread_mode = (mca_osc_ucx_component.enable_mpi_threads == true)
                                    ? UCS_THREAD_MODE_MULTI : UCS_THREAD_MODE_SINGLE;
        status = ucp_worker_create(mca_osc_ucx_component.ucp_context, &worker_params,
                                   &(mca_osc_ucx_component.ucp_worker));
        if (UCS_OK != status) {
            opal_output_verbose(1, ompi_osc_base_framework.framework_output,
                                "%s:%d: ucp_worker_create failed: %d\n",
                                __FILE__, __LINE__, status);
            ret = OMPI_ERROR;
            goto error;
        }

        /* query UCP worker attributes */
        worker_attr.field_mask = UCP_WORKER_ATTR_FIELD_THREAD_MODE;
        status = ucp_worker_query(mca_osc_ucx_component.ucp_worker, &worker_attr);
        if (UCS_OK != status) {
            opal_output_verbose(1, ompi_osc_base_framework.framework_output,
                                "%s:%d: ucp_worker_query failed: %d\n",
                                __FILE__, __LINE__, status);
            ret = OMPI_ERROR;
            goto error;
        }

        if (mca_osc_ucx_component.enable_mpi_threads == true &&
            worker_attr.thread_mode != UCS_THREAD_MODE_MULTI) {
            opal_output_verbose(1, ompi_osc_base_framework.framework_output,
                                "%s:%d: ucx does not support multithreading\n",
                                __FILE__, __LINE__);
            ret = OMPI_ERROR;
            goto error;
        }

        worker_created = true;
    }

    /* create module structure */
    module = (ompi_osc_ucx_module_t *)calloc(1, sizeof(ompi_osc_ucx_module_t));
    if (module == NULL) {
        ret = OMPI_ERR_TEMP_OUT_OF_RESOURCE;
        goto error;
    }

    /* fill in the function pointer part */
    memcpy(module, &ompi_osc_ucx_module_template, sizeof(ompi_osc_base_module_t));

    ret = ompi_comm_dup(comm, &module->comm);
    if (ret != OMPI_SUCCESS) {
        goto error;
    }

    asprintf(&name, "ucx window %d", ompi_comm_get_cid(module->comm));
    ompi_win_set_name(win, name);
    free(name);

    /* share everyone's displacement units. Only do an allgather if
       strictly necessary, since it requires O(p) state. */
    values[0] = disp_unit;
    values[1] = -disp_unit;

    ret = module->comm->c_coll->coll_allreduce(MPI_IN_PLACE, values, 2, MPI_LONG,
                                               MPI_MIN, module->comm,
                                               module->comm->c_coll->coll_allreduce_module);
    if (OMPI_SUCCESS != ret) {
        goto error;
    }

    if (values[0] == -values[1]) { /* everyone has the same disp_unit, we do not need O(p) space */
        module->disp_unit = disp_unit;
    } else { /* different disp_unit sizes, allocate O(p) space to store them */
        module->disp_unit = -1;
        module->disp_units = calloc(comm_size, sizeof(int));
        if (module->disp_units == NULL) {
            ret = OMPI_ERR_TEMP_OUT_OF_RESOURCE;
            goto error;
        }

        ret = module->comm->c_coll->coll_allgather(&disp_unit, 1, MPI_INT,
                                                   module->disp_units, 1, MPI_INT,
                                                   module->comm,
                                                   module->comm->c_coll->coll_allgather_module);
        if (OMPI_SUCCESS != ret) {
            goto error;
        }
    }

    /* exchange endpoints if necessary */
    is_eps_ready = 1;
    for (i = 0; i < comm_size; i++) {
        if (OSC_UCX_GET_EP(module->comm, i) == NULL) {
            is_eps_ready = 0;
            break;
        }
    }

    ret = module->comm->c_coll->coll_allreduce(MPI_IN_PLACE, &is_eps_ready, 1, MPI_INT,
                                               MPI_LAND,
                                               module->comm,
                                               module->comm->c_coll->coll_allreduce_module);
    if (OMPI_SUCCESS != ret) {
        goto error;
    }

    if (!is_eps_ready) {
        status = ucp_worker_get_address(mca_osc_ucx_component.ucp_worker,
                                        &my_addr, &my_addr_len);
        if (status != UCS_OK) {
            opal_output_verbose(1, ompi_osc_base_framework.framework_output,
                                "%s:%d: ucp_worker_get_address failed: %d\n",
                                __FILE__, __LINE__, status);
            ret = OMPI_ERROR;
            goto error;
        }

        ret = allgather_len_and_info(my_addr, (int)my_addr_len,
                                     &recv_buf, disps, module->comm);
        if (ret != OMPI_SUCCESS) {
            goto error;
        }

        for (i = 0; i < comm_size; i++) {
            if (OSC_UCX_GET_EP(module->comm, i) == NULL) {
                ucp_ep_params_t ep_params;
                ucp_ep_h ep;
                memset(&ep_params, 0, sizeof(ucp_ep_params_t));
                ep_params.field_mask = UCP_EP_PARAM_FIELD_REMOTE_ADDRESS;
                ep_params.address = (ucp_address_t *)&(recv_buf[disps[i]]);
                status = ucp_ep_create(mca_osc_ucx_component.ucp_worker, &ep_params, &ep);
                if (status != UCS_OK) {
                    opal_output_verbose(1, ompi_osc_base_framework.framework_output,
                                        "%s:%d: ucp_ep_create failed: %d\n",
                                        __FILE__, __LINE__, status);
                    ret = OMPI_ERROR;
                    goto error;
                }

                ompi_comm_peer_lookup(module->comm, i)->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_UCX] = ep;
            }
        }

        ucp_worker_release_address(mca_osc_ucx_component.ucp_worker, my_addr);
        my_addr = NULL;
        free(recv_buf);
        recv_buf = NULL;

        eps_created = true;
    }

    ret = mem_map(base, size, &(module->memh), module, flavor);
    if (ret != OMPI_SUCCESS) {
        goto error;
    }

    state_base = (void *)&(module->state);
    ret = mem_map(&state_base, sizeof(ompi_osc_ucx_state_t), &(module->state_memh),
                  module, MPI_WIN_FLAVOR_CREATE);
    if (ret != OMPI_SUCCESS) {
        goto error;
    }

    module->win_info_array = calloc(comm_size, sizeof(ompi_osc_ucx_win_info_t));
    if (module->win_info_array == NULL) {
        ret = OMPI_ERR_TEMP_OUT_OF_RESOURCE;
        goto error;
    }

    module->state_info_array = calloc(comm_size, sizeof(ompi_osc_ucx_win_info_t));
    if (module->state_info_array == NULL) {
        ret = OMPI_ERR_TEMP_OUT_OF_RESOURCE;
        goto error;
    }

    status = ucp_rkey_pack(mca_osc_ucx_component.ucp_context, module->memh,
                           &rkey_buffer, &rkey_buffer_size);
    if (status != UCS_OK) {
        opal_output_verbose(1, ompi_osc_base_framework.framework_output,
                            "%s:%d: ucp_rkey_pack failed: %d\n",
                            __FILE__, __LINE__, status);
        ret = OMPI_ERROR;
        goto error;
    }

    status = ucp_rkey_pack(mca_osc_ucx_component.ucp_context, module->state_memh,
                           &state_rkey_buffer, &state_rkey_buffer_size);
    if (status != UCS_OK) {
        opal_output_verbose(1, ompi_osc_base_framework.framework_output,
                            "%s:%d: ucp_rkey_pack failed: %d\n",
                            __FILE__, __LINE__, status);
        ret = OMPI_ERROR;
        goto error;
    }

    my_info_len = 2 * sizeof(uint64_t) + rkey_buffer_size + state_rkey_buffer_size;
    my_info = malloc(my_info_len);
    if (my_info == NULL) {
        ret = OMPI_ERR_TEMP_OUT_OF_RESOURCE;
        goto error;
    }

    memcpy(my_info, base, sizeof(uint64_t));
    memcpy((void *)((char *)my_info + sizeof(uint64_t)), &state_base, sizeof(uint64_t));
    memcpy((void *)((char *)my_info + 2 * sizeof(uint64_t)), rkey_buffer, rkey_buffer_size);
    memcpy((void *)((char *)my_info + 2 * sizeof(uint64_t) + rkey_buffer_size),
           state_rkey_buffer, state_rkey_buffer_size);

    ret = allgather_len_and_info(my_info, (int)my_info_len, &recv_buf, disps, module->comm);
    if (ret != OMPI_SUCCESS) {
        goto error;
    }

    ret = comm->c_coll->coll_allgather((void *)&rkey_buffer_size, 1, MPI_INT,
                                       rkey_sizes, 1, MPI_INT, comm,
                                       comm->c_coll->coll_allgather_module);
    if (OMPI_SUCCESS != ret) {
        goto error;
    }

    for (i = 0; i < comm_size; i++) {
        ucp_ep_h ep = OSC_UCX_GET_EP(module->comm, i);
        assert(ep != NULL);

        memcpy(&(module->win_info_array[i]).addr, &recv_buf[disps[i]], sizeof(uint64_t));
        memcpy(&(module->state_info_array[i]).addr, &recv_buf[disps[i] + sizeof(uint64_t)], 
               sizeof(uint64_t));

        status = ucp_ep_rkey_unpack(ep, &(recv_buf[disps[i] + 2 * sizeof(uint64_t)]),
                                    &((module->win_info_array[i]).rkey));
        if (status != UCS_OK) {
            opal_output_verbose(1, ompi_osc_base_framework.framework_output,
                                "%s:%d: ucp_ep_rkey_unpack failed: %d\n",
                                __FILE__, __LINE__, status);
            ret = OMPI_ERROR;
            goto error;
        }

        status = ucp_ep_rkey_unpack(ep, &(recv_buf[disps[i] + 2 * sizeof(uint64_t) + rkey_sizes[i]]),
                                    &((module->state_info_array[i]).rkey));
        if (status != UCS_OK) {
            opal_output_verbose(1, ompi_osc_base_framework.framework_output,
                                "%s:%d: ucp_ep_rkey_unpack failed: %d\n",
                                __FILE__, __LINE__, status);
            ret = OMPI_ERROR;
            goto error;
        }
    }

    free(my_info);
    free(recv_buf);

    ucp_rkey_buffer_release(rkey_buffer);
    ucp_rkey_buffer_release(state_rkey_buffer);

    module->state.lock = TARGET_LOCK_UNLOCKED;
    module->state.post_index = 0;
    memset((void *)module->state.post_state, 0, sizeof(uint64_t) * OMPI_OSC_UCX_POST_PEER_MAX);
    module->state.complete_count = 0;
    module->state.req_flag = 0;
    module->state.acc_lock = TARGET_LOCK_UNLOCKED;
    module->epoch_type.access = NONE_EPOCH;
    module->epoch_type.exposure = NONE_EPOCH;
    module->lock_count = 0;
    module->post_count = 0;
    module->start_group = NULL;
    module->post_group = NULL;
    OBJ_CONSTRUCT(&module->outstanding_locks, opal_hash_table_t);
    OBJ_CONSTRUCT(&module->pending_posts, opal_list_t);
    module->global_ops_num = 0;
    module->per_target_ops_nums = calloc(comm_size, sizeof(int));
    module->start_grp_ranks = NULL;
    module->lock_all_is_nocheck = false;

    ret = opal_hash_table_init(&module->outstanding_locks, comm_size);
    if (ret != OPAL_SUCCESS) {
        goto error;
    }

    win->w_osc_module = &module->super;

    /* sync with everyone */

    ret = module->comm->c_coll->coll_barrier(module->comm,
                                             module->comm->c_coll->coll_barrier_module);
    if (ret != OMPI_SUCCESS) {
        goto error;
    }

    return ret;

 error:
    if (my_addr) ucp_worker_release_address(mca_osc_ucx_component.ucp_worker, my_addr);
    if (recv_buf) free(recv_buf);
    if (my_info) free(my_info);
    for (i = 0; i < comm_size; i++) {
        if ((module->win_info_array[i]).rkey != NULL) {
            ucp_rkey_destroy((module->win_info_array[i]).rkey);
        }
        if ((module->state_info_array[i]).rkey != NULL) {
            ucp_rkey_destroy((module->state_info_array[i]).rkey);
        }
    }
    if (rkey_buffer) ucp_rkey_buffer_release(rkey_buffer);
    if (state_rkey_buffer) ucp_rkey_buffer_release(state_rkey_buffer);
    if (module->win_info_array) free(module->win_info_array);
    if (module->state_info_array) free(module->state_info_array);
    if (module->disp_units) free(module->disp_units);
    if (module->comm) ompi_comm_free(&module->comm);
    if (module->per_target_ops_nums) free(module->per_target_ops_nums);
    if (eps_created) {
        for (i = 0; i < comm_size; i++) {
            ucp_ep_h ep = OSC_UCX_GET_EP(module->comm, i);
            ucp_ep_destroy(ep);
        }
    }
    if (worker_created) ucp_worker_destroy(mca_osc_ucx_component.ucp_worker);
    if (module) free(module);
    return ret;
}
예제 #13
0
파일: fr_main.c 프로젝트: mbbill/Freya
static void fr_munmap(Addr a, SizeT len)
{
   if (clo_mmap)
      mem_map( a, a + len, NULL );
}
예제 #14
0
파일: fr_main.c 프로젝트: mbbill/Freya
static void fr_mmap(Addr a, SizeT len, Bool rr, Bool ww, Bool xx, ULong di_handle)
{
   if (clo_mmap)
      mem_map( a, a + len, alloc_trace(VG_(get_running_tid)()) );
}