TEST_F(OperatorsProjectionTest, ForwardsIfPossibleDataTableAndExpression) { const auto projection = std::make_shared<opossum::Projection>(table_wrapper_a, expression_vector(a_b, a_a, add_(a_b, a_a))); projection->execute(); const auto input_chunk = table_wrapper_a->get_output()->get_chunk(ChunkID{0}); const auto output_chunk = projection->get_output()->get_chunk(ChunkID{0}); EXPECT_EQ(input_chunk->get_segment(ColumnID{1}), output_chunk->get_segment(ColumnID{0})); EXPECT_EQ(input_chunk->get_segment(ColumnID{0}), output_chunk->get_segment(ColumnID{1})); }
TEST_F(OperatorsProjectionTest, DontForwardReferencesWithExpression) { const auto table_scan = create_table_scan(table_wrapper_a, ColumnID{0}, PredicateCondition::LessThan, 100'000); table_scan->execute(); const auto projection = std::make_shared<opossum::Projection>(table_scan, expression_vector(a_b, a_a, add_(a_b, a_a))); projection->execute(); const auto input_chunk = table_wrapper_a->get_output()->get_chunk(ChunkID{0}); const auto output_chunk = projection->get_output()->get_chunk(ChunkID{0}); EXPECT_NE(input_chunk->get_segment(ColumnID{1}), output_chunk->get_segment(ColumnID{0})); EXPECT_NE(input_chunk->get_segment(ColumnID{0}), output_chunk->get_segment(ColumnID{1})); }
TEST_F(OperatorsProjectionTest, ForwardsIfPossibleDataTable) { // The Projection will forward segments from its input if all expressions are segment references. // Why would you enforce something like this? E.g., Update relies on it. const auto projection = std::make_shared<opossum::Projection>(table_wrapper_a, expression_vector(a_b, a_a)); projection->execute(); const auto input_chunk = table_wrapper_a->get_output()->get_chunk(ChunkID{0}); const auto output_chunk = projection->get_output()->get_chunk(ChunkID{0}); EXPECT_EQ(input_chunk->get_segment(ColumnID{1}), output_chunk->get_segment(ColumnID{0})); EXPECT_EQ(input_chunk->get_segment(ColumnID{0}), output_chunk->get_segment(ColumnID{1})); EXPECT_TRUE(projection->get_output()->has_mvcc() == UseMvcc::Yes); EXPECT_TRUE(projection->get_output()->get_chunk(ChunkID{0})->mvcc_data()); }
/** Returns a point inside the cylinder, specified by its location relative to the cylinder axis, its relative radius and its rotation angle about the axis @param relative_height a number in the range [0..1] that specifies the point location relative to the cylinder axis such that 0 specifies the cylinder bottom and 1 specifies its top @param relative_radius a number in the range [0..1] that specifies the distance of the point from the cylinder axis relative to the cylinder radius, 0 being on the axis itself, and 1 being on the cylinder surface @param angle angle in radians about the cylinder axis, with 0 set to an arbitrary but consistent direction */ const Vector3D Cylinder3D::get_inner_point_at(double relative_height, double relative_radius, double angle) const { // compute the point relative to cylinder of equivalent dimensions, // but whose main axis segment is z-aligned and lying at the origin Vector3D scaling(get_radius() * relative_radius, get_radius() * relative_radius, get_segment().get_length()); Vector3D pt(scaling[0] * sin(angle), scaling[1] * cos(angle), scaling[2] * relative_height); // transform the cylinder axis from the origin to the correct location Rotation3D rot = get_rotation_taking_first_to_second( Vector3D(0, 0, 1), get_segment().get_point(1) - get_segment().get_point(0)); Transformation3D tr(rot, get_segment().get_point(0)); return tr.get_transformed(pt); }
/* Function: al_destroy_path */ void al_destroy_path(ALLEGRO_PATH *path) { unsigned i; if (!path) { return; } if (path->drive) { al_ustr_free(path->drive); path->drive = NULL; } if (path->filename) { al_ustr_free(path->filename); path->filename = NULL; } for (i = 0; i < _al_vector_size(&path->segments); i++) { al_ustr_free(get_segment(path, i)); } _al_vector_free(&path->segments); if (path->basename) { al_ustr_free(path->basename); path->basename = NULL; } if (path->full_string) { al_ustr_free(path->full_string); path->full_string = NULL; } _AL_FREE(path); }
/* Function: al_make_path_canonical */ bool al_make_path_canonical(ALLEGRO_PATH *path) { unsigned i; ASSERT(path); for (i = 0; i < _al_vector_size(&path->segments); ) { if (strcmp(get_segment_cstr(path, i), ".") == 0) al_remove_path_component(path, i); else i++; } /* Remove leading '..'s on absolute paths. */ if (_al_vector_size(&path->segments) >= 1 && al_ustr_size(get_segment(path, 0)) == 0) { while (_al_vector_size(&path->segments) >= 2 && strcmp(get_segment_cstr(path, 1), "..") == 0) { al_remove_path_component(path, 1); } } return true; }
Container trim_token_left(const Container& token, const Container& xs) { auto result = xs; while (is_prefix_of(token, result)) { result = get_segment(size_of_cont(token), size_of_cont(result), result); } return result; }
double Contour::GetContourValue(double parameter){ if (parameter <= _coordinates_parameters.front()){ return low_extrapolate(parameter); } else if (parameter <_coordinates_parameters.back()){ std::pair< double_pair,double_pair > segment=get_segment(parameter); return interpolate(parameter,segment); } else { return high_extrapolate(parameter); } }
void cmtp_dump(int level, struct frame *frm) { struct frame *msg; uint8_t hdr, bid; uint16_t len; while (frm->len > 0) { hdr = p_get_u8(frm); bid = (hdr & 0x3c) >> 2; switch ((hdr & 0xc0) >> 6) { case 0x01: len = p_get_u8(frm); break; case 0x02: len = htons(p_get_u16(frm)); break; default: len = 0; break; } p_indent(level, frm); printf("CMTP: %s: id %d len %d\n", bst2str(hdr & 0x03), bid, len); switch (hdr & 0x03) { case 0x00: add_segment(bid, frm, len); msg = get_segment(bid, frm); if (!msg) break; if (!p_filter(FILT_CAPI)) capi_dump(level + 1, msg); else raw_dump(level, msg); free_segment(bid, frm); break; case 0x01: add_segment(bid, frm, len); break; default: free_segment(bid, frm); break; } frm->ptr += len; frm->len -= len; } }
/* Function: al_remove_path_component */ void al_remove_path_component(ALLEGRO_PATH *path, int i) { ASSERT(path); ASSERT(i < (int)_al_vector_size(&path->segments)); if (i < 0) i = _al_vector_size(&path->segments) + i; ASSERT(i >= 0); al_ustr_free(get_segment(path, i)); _al_vector_delete_at(&path->segments, i); }
/* Function: al_replace_path_component */ void al_replace_path_component(ALLEGRO_PATH *path, int i, const char *s) { ASSERT(path); ASSERT(s); ASSERT(i < (int)_al_vector_size(&path->segments)); if (i < 0) i = _al_vector_size(&path->segments) + i; ASSERT(i >= 0); al_ustr_assign_cstr(get_segment(path, i), s); }
static void path_to_ustr(const ALLEGRO_PATH *path, int32_t delim, ALLEGRO_USTR *str) { unsigned i; al_ustr_assign(str, path->drive); for (i = 0; i < _al_vector_size(&path->segments); i++) { al_ustr_append(str, get_segment(path, i)); al_ustr_append_chr(str, delim); } al_ustr_append(str, path->filename); }
/** * get a shuffled list of all fields, to create a preferably random behaviour * */ void get_movement_order(struct Field **movements, int fields) { struct Segment *segment = get_segment(); int i = 0; for (int x = segment->x1; x <= segment->x2; x++) { for (int y = segment->y1; y <= segment->y2; y++) { movements[i] = get_field(x, y); i++; } } shuffle((void **) movements, fields); }
void init_render_segments(Memory *memory, GameState *game_state, FrameBuffer *frame_buffer) { game_state->screen_render_region.start = (V2) { 0, 0 }; game_state->screen_render_region.end = (V2) { frame_buffer->width, frame_buffer->height }; game_state->screen_render_region = grow(game_state->screen_render_region, -20); game_state->world_render_region = grow(game_state->screen_render_region, -10); V2 ns = {4, 4}; game_state->render_segs.segments = push_structs(memory, Rectangle, ns.x * ns.y); game_state->render_segs.n_segments = ns; V2 s; for (s.y = 0; s.y < ns.y; ++s.y) { for (s.x = 0; s.x < ns.x; ++s.x) { Rectangle *segment = game_state->render_segs.segments + (u32)s.y + (u32)ns.y*(u32)s.x; *segment = grow(get_segment(game_state->screen_render_region, s, ns), 0); } } game_state->render_queue.empty = true; game_state->render_queue.full = false; game_state->render_queue.head = 0; game_state->render_queue.tail = 0; pthread_mutex_init(&game_state->render_queue.mut, 0); pthread_cond_init(&game_state->render_queue.not_full, 0); pthread_cond_init(&game_state->render_queue.not_empty, 0); for (u32 t = 0; t < ns.x*ns.y; ++t) { pthread_t thread; pthread_create(&thread, 0, consume_from_render_queue, &game_state->render_queue); } }
/* Function: al_clone_path */ ALLEGRO_PATH *al_clone_path(const ALLEGRO_PATH *path) { ALLEGRO_PATH *clone; unsigned int i; ASSERT(path); clone = al_create_path(NULL); if (!clone) { return NULL; } al_ustr_assign(clone->drive, path->drive); al_ustr_assign(clone->filename, path->filename); for (i = 0; i < _al_vector_size(&path->segments); i++) { ALLEGRO_USTR **slot = _al_vector_alloc_back(&clone->segments); (*slot) = al_ustr_dup(get_segment(path, i)); } return clone; }
/** * get a result (amount of animals / plants) of the current simulation step * */ struct StepResult* calculate_step_result(int step) { // statistics struct StepResult *resultset = malloc(sizeof(struct StepResult)); resultset->amount_prey = 0; resultset->amount_predators = 0; resultset->amount_plants = 0; resultset->current_step = step; resultset->operations = _operations; resultset->next = 0; struct Segment *segment = get_segment(); for (int x = segment->x1; x <= segment->x2; x++) { for (int y = segment->y1; y <= segment->y2; y++) { struct Field *field = get_field(x, y); if (field->population_type == PREY) { resultset->amount_prey++; } else if (field->population_type == PREDATOR) { resultset->amount_predators++; } if (field->contains_plant) { resultset->amount_plants++; } } } return resultset; }
void exec_image(char *image) /* Get a Minix image into core, patch it up and execute. */ { int i; struct image_header hdr; char *buf; u32_t vsec, addr, limit, aout, n, totalmem = 0; struct process *procp; /* Process under construction. */ long a_text, a_data, a_bss, a_stack; int banner= 0; long processor= a2l(b_value("processor")); u16_t kmagic, mode; char *console; char params[SECTOR_SIZE]; extern char *sbrk(int); char *verb; /* The stack is pretty deep here, so check if heap and stack collide. */ (void) sbrk(0); if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil) verboseboot = a2l(verb); printf("\nLoading "); pretty_image(image); printf(".\n"); vsec= 0; /* Load this sector from image next. */ addr= mem[0].base; /* Into this memory block. */ limit= mem[0].base + mem[0].size; if (limit > caddr) limit= caddr; /* Allocate and clear the area where the headers will be placed. */ aout = (limit -= PROCESS_MAX * A_MINHDR); /* Clear the area where the headers will be placed. */ raw_clear(aout, PROCESS_MAX * A_MINHDR); /* Read the many different processes: */ for (i= 0; vsec < image_size; i++) { u32_t startaddr; startaddr = addr; if (i == PROCESS_MAX) { printf("There are more then %d programs in %s\n", PROCESS_MAX, image); errno= 0; return; } procp= &process[i]; /* Read header. */ DEBUGEXTRA(("Reading header... ")); for (;;) { if ((buf= get_sector(vsec++)) == nil) return; memcpy(&hdr, buf, sizeof(hdr)); if (BADMAG(hdr.process)) { errno= ENOEXEC; return; } /* Check the optional label on the process. */ if (selected(hdr.name)) break; /* Bad label, skip this process. */ vsec+= proc_size(&hdr); } DEBUGEXTRA(("done\n")); /* Sanity check: an 8086 can't run a 386 kernel. */ if (hdr.process.a_cpu == A_I80386 && processor < 386) { printf("You can't run a 386 kernel on this 80%ld\n", processor); errno= 0; return; } /* Get the click shift from the kernel text segment. */ if (i == KERNEL_IDX) { if (!get_clickshift(vsec, &hdr)) return; addr= align(addr, click_size); /* big kernels must be loaded into extended memory */ if (k_flags & K_KHIGH) { addr= mem[1].base; limit= mem[1].base + mem[1].size; } } /* Save a copy of the header for the kernel, with a_syms * misused as the address where the process is loaded at. */ DEBUGEXTRA(("raw_copy(0x%x, 0x%lx, 0x%x)... ", aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR)); hdr.process.a_syms= addr; raw_copy(aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR); DEBUGEXTRA(("done\n")); if (!banner) { DEBUGBASIC((" cs ds text data bss")); if (k_flags & K_CHMEM) DEBUGBASIC((" stack")); DEBUGBASIC(("\n")); banner= 1; } /* Segment sizes. */ DEBUGEXTRA(("a_text=0x%lx; a_data=0x%lx; a_bss=0x%lx; a_flags=0x%x)\n", hdr.process.a_text, hdr.process.a_data, hdr.process.a_bss, hdr.process.a_flags)); a_text= hdr.process.a_text; a_data= hdr.process.a_data; a_bss= hdr.process.a_bss; if (k_flags & K_CHMEM) { a_stack= hdr.process.a_total - a_data - a_bss; if (!(hdr.process.a_flags & A_SEP)) a_stack-= a_text; } else { a_stack= 0; } /* Collect info about the process to be. */ procp->cs= addr; /* Process may be page aligned so that the text segment contains * the header, or have an unmapped zero page against vaxisms. */ procp->entry= hdr.process.a_entry; if (hdr.process.a_flags & A_PAL) a_text+= hdr.process.a_hdrlen; if (hdr.process.a_flags & A_UZP) procp->cs-= click_size; /* Separate I&D: two segments. Common I&D: only one. */ if (hdr.process.a_flags & A_SEP) { /* Read the text segment. */ DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, a_text, addr, limit)); if (!get_segment(&vsec, &a_text, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx a_text=0x%lx " "addr=0x%lx\n", vsec, a_text, addr)); /* The data segment follows. */ procp->ds= addr; if (hdr.process.a_flags & A_UZP) procp->ds-= click_size; procp->data= addr; } else { /* Add text to data to form one segment. */ procp->data= addr + a_text; procp->ds= procp->cs; a_data+= a_text; } /* Read the data segment. */ DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, a_data, addr, limit)); if (!get_segment(&vsec, &a_data, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx a_data=0x%lx " "addr=0x%lx\n", vsec, a_data, addr)); /* Make space for bss and stack unless... */ if (i != KERNEL_IDX && (k_flags & K_CLAIM)) a_bss= a_stack= 0; DEBUGBASIC(("%07lx %07lx %8ld %8ld %8ld", procp->cs, procp->ds, hdr.process.a_text, hdr.process.a_data, hdr.process.a_bss)); if (k_flags & K_CHMEM) DEBUGBASIC((" %8ld", a_stack)); /* Note that a_data may be negative now, but we can look at it * as -a_data bss bytes. */ /* Compute the number of bss clicks left. */ a_bss+= a_data; n= align(a_bss, click_size); a_bss-= n; /* Zero out bss. */ DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit)); if (addr + n > limit) { errno= ENOMEM; return; } raw_clear(addr, n); DEBUGEXTRA(("done\n")); addr+= n; /* And the number of stack clicks. */ a_stack+= a_bss; n= align(a_stack, click_size); a_stack-= n; /* Add space for the stack. */ addr+= n; /* Process endpoint. */ procp->end= addr; if (verboseboot >= VERBOSEBOOT_BASIC) printf(" %s\n", hdr.name); else { u32_t mem; mem = addr-startaddr; printf("%s ", hdr.name); totalmem += mem; } if (i == 0 && (k_flags & (K_HIGH | K_KHIGH)) == K_HIGH) { /* Load the rest in extended memory. */ addr= mem[1].base; limit= mem[1].base + mem[1].size; } } if (verboseboot < VERBOSEBOOT_BASIC) printf("(%dk)\n", totalmem/1024); if ((n_procs= i) == 0) { printf("There are no programs in %s\n", image); errno= 0; return; } /* Check the kernel magic number. */ raw_copy(mon2abs(&kmagic), process[KERNEL_IDX].data + MAGIC_OFF, sizeof(kmagic)); if (kmagic != KERNEL_D_MAGIC) { printf("Kernel magic number is incorrect (0x%x@0x%lx)\n", kmagic, process[KERNEL_IDX].data + MAGIC_OFF); errno= 0; return; } /* Patch sizes, etc. into kernel data. */ DEBUGEXTRA(("patch_sizes()... ")); patch_sizes(); DEBUGEXTRA(("done\n")); #if !DOS if (!(k_flags & K_MEML)) { /* Copy the a.out headers to the old place. */ raw_copy(HEADERPOS, aout, PROCESS_MAX * A_MINHDR); } #endif /* Run the trailer function just before starting Minix. */ DEBUGEXTRA(("run_trailer()... ")); if (!run_trailer()) { errno= 0; return; } DEBUGEXTRA(("done\n")); /* Translate the boot parameters to what Minix likes best. */ DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params))); if (!params2params(params, sizeof(params))) { errno= 0; return; } DEBUGEXTRA(("done\n")); /* Set the video to the required mode. */ if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) { mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE : MONO_MODE; } DEBUGEXTRA(("set_mode(%d)... ", mode)); set_mode(mode); DEBUGEXTRA(("done\n")); /* Close the disk. */ DEBUGEXTRA(("dev_close()... ")); (void) dev_close(); DEBUGEXTRA(("done\n")); /* Minix. */ DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n", process[KERNEL_IDX].entry, process[KERNEL_IDX].cs, process[KERNEL_IDX].ds, params, sizeof(params), aout)); minix(process[KERNEL_IDX].entry, process[KERNEL_IDX].cs, process[KERNEL_IDX].ds, params, sizeof(params), aout); if (!(k_flags & K_BRET)) { extern u32_t reboot_code; raw_copy(mon2abs(params), reboot_code, sizeof(params)); } parse_code(params); /* Return from Minix. Things may have changed, so assume nothing. */ fsok= -1; errno= 0; /* Read leftover character, if any. */ scan_keyboard(); /* Restore screen contents. */ restore_screen(); }
/** * Tell the GST source element it is time to prepare to do work * * This is one of the last functions GStreamer will call when the pipeline * is being put together. It is the last place the element has a chance to * allocate resources and in our case startup our background task for network * connectivity. * After this function returns, we are ready to start processing data from the pipeliine. * * We allocate some of the last minute buffers, and setup a connection to the network; * this is used primarily by the background task, but we need access to it for name initialization. * * Next we initialize our fifo queue, and startup the background task. * * Lastly we return to the GST to begin processing information. * * \param bsrc -> to the context source element * \return true if the initialization went well and we are ready to process data, false otherwise */ static gboolean gst_ccnxsrc_start (GstBaseSrc * bsrc) { Gstccnxsrc *src; CcnxInterestState *istate; struct ccn_charbuf *p_name = NULL; uintmax_t *p_seg = NULL; gint i_ret = 0; gboolean b_ret = FALSE; src = GST_CCNXSRC (bsrc); GST_DEBUG ("starting, getting connections"); /* setup the connection to ccnx */ if ((src->ccn = ccn_create ()) == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("ccn_create failed")); return FALSE; } if (-1 == ccn_connect (src->ccn, ccndHost ())) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("ccn_connect failed to %s", ccndHost ())); return FALSE; } loadKey (src->ccn, &src->sp); /* A closure is what defines what to do when an inbound interest or data arrives */ if ((src->ccn_closure = calloc (1, sizeof (struct ccn_closure))) == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("closure alloc failed")); return FALSE; } /* We setup the closure to keep our context [src] and to call the incoming_content() function */ src->ccn_closure->data = src; src->ccn_closure->p = incoming_content; /* Allocate buffers and construct the name from the uri the user gave us */ GST_INFO ("step 1"); if ((p_name = ccn_charbuf_create ()) == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("p_name alloc failed")); return FALSE; } if ((src->p_name = ccn_charbuf_create ()) == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("src->p_name alloc failed")); return FALSE; } if ((i_ret = ccn_name_from_uri (p_name, src->uri)) < 0) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("name from uri failed for \"%s\"", src->uri)); return FALSE; } /* Find out what the latest one of these is called, and keep it in our context */ ccn_charbuf_append (src->p_name, p_name->buf, p_name->length); i_ret = ccn_resolve_version (src->ccn, src->p_name, CCN_V_HIGHEST, CCN_VERSION_TIMEOUT); GST_INFO ("step 20 - name so far..."); // hDump(src->p_name->buf, src->p_name->length); src->i_seg = 0; if (i_ret == 0) { /* name is versioned, so get the meta data to obtain the length */ p_seg = get_segment (src->ccn, src->p_name, CCN_HEADER_TIMEOUT); if (p_seg != NULL) { src->i_seg = *p_seg; GST_INFO ("step 25 - next seg: %d", src->i_seg); free (p_seg); } } ccn_charbuf_destroy (&p_name); /* Even though the recent segment published is likely to be >> 0, we still need to ask for segment 0 */ /* because it seems to contain valuable stream information. Attempts to skip segment 0 resulted in no */ /* proper rendering of the stream on my screen during testing */ i_ret = request_segment (src, 0); if (i_ret < 0) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("interest sending failed")); return FALSE; } src->post_seg = 0; istate = allocInterestState (src); if (!istate) { // This should not happen, but maybe GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("trouble allocating interest state structure")); return FALSE; } istate->seg = 0; istate->state = OInterest_waiting; /* Now start up the background work which will fetch all the rest of the R/T segments */ eventTask = gst_task_create (ccn_event_thread, src); if (NULL == eventTask) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("creating event thread failed")); return FALSE; } src->fifo_cond = g_cond_new (); src->fifo_lock = g_mutex_new (); gst_task_set_lock (eventTask, &task_mutex); eventCond = g_cond_new (); eventLock = g_mutex_new (); b_ret = gst_task_start (eventTask); if (FALSE == b_ret) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("starting event thread failed")); return FALSE; } GST_DEBUG ("event thread started"); /* Done! */ return TRUE; }
static bool InitLinkMap_32(MmapFile& irExec, MmapFile& irCore) { char* lpExecStart = irExec.GetStartAddr(); char* lpCoreStart = irCore.GetStartAddr(); char* lpCoreEnd = irCore.GetEndAddr(); Elf32_Ehdr* elfhdr = (Elf32_Ehdr*)lpExecStart; // search for .dynamic section Elf32_Dyn* dyn = NULL; #if defined(linux) Elf32_Xword dyn_size = 0; #elif defined(sun) Elf32_Word dyn_size = 0; #endif Elf32_Shdr* shdr = (Elf32_Shdr*)(lpExecStart + elfhdr->e_shoff); Elf32_Shdr* shstrtbl = shdr + elfhdr->e_shstrndx; char* shstr = lpExecStart + shstrtbl->sh_offset; for (int i=0; i < elfhdr->e_shnum; i++) { if (0 == strcmp(shstr+shdr->sh_name, ".dynamic") && shdr->sh_type == SHT_DYNAMIC) { dyn = (Elf32_Dyn*) shdr->sh_addr; dyn_size = shdr->sh_size; //printf("Exec's .dynamic section vaddr = 0x%lx\n", dyn); break; } shdr++; } if (!dyn) { printf("Failed to find Exec's .dynamic\n"); return false; } // The content of .dynamic section is in core Elf32_Dyn* core_dyn = (Elf32_Dyn*) core_to_mmap_addr((address_t)dyn); if (!core_dyn) { printf("Failed to find Exec's .dynamic section in core\n"); return false; } // Find the DT_DEBUG entry in the the .dynamic section. Elf32_Dyn* debug_dyn = NULL; for (dyn = core_dyn; (char*)dyn - (char*)core_dyn < dyn_size; dyn++) { if (GetUInt(&dyn->d_tag) == DT_DEBUG) { debug_dyn = dyn; break; } } if (!debug_dyn) { printf("Failed to find debug_dyn\n"); return false; } // If the executable's dynamic section has a DT_DEBUG element, // the run-time linker sets that element's value to the address // where this struct r_debug (link.h) can be found. struct r_debug_32* pdebug = (struct r_debug_32*)GetUInt(&debug_dyn->d_un.d_ptr); pdebug = (struct r_debug_32*) core_to_mmap_addr((address_t)pdebug); if (!pdebug) { printf("Failed to find link map in core\n"); return false; } gLinkMap_32 = (struct link_map_32 *) core_to_mmap_addr((address_t)GetUInt(&pdebug->r_map)); if (!gLinkMap_32) { printf("Failed to find link map in core\n"); return false; } // set executable and library segments. struct link_map_32 * linkmap = gLinkMap_32; while (linkmap && (char*)linkmap > lpCoreStart && (char*)linkmap < lpCoreEnd) { ca_segment* segment = NULL; #ifdef sun address_t load_addr = GetUInt(&linkmap->l_addr); if (! (segment = get_segment(load_addr, 1) ) ) break; #endif Elf32_Dyn* dyn = (Elf32_Dyn*) core_to_mmap_addr((address_t)GetUInt(&linkmap->l_ld)); for (; (char*)dyn >lpCoreStart && (char*)dyn < lpCoreEnd; dyn++) { #if defined(linux) Elf32_Xword tag = GetUInt(&dyn->d_tag); #elif defined(sun) Elf32_Sword tag = GetUInt(&dyn->d_tag); #endif if (tag == DT_NULL) break; #ifdef linux address_t vaddr = GetUInt(&dyn->d_un.d_ptr); #elif defined(sun) address_t vaddr = load_addr + GetUInt(&dyn->d_un.d_ptr); #endif if (vaddr) { // The segment is likely the same as previous dynamic section if (!segment || vaddr < segment->m_vaddr || vaddr >= segment->m_vaddr + segment->m_vsize) segment = get_segment(vaddr, 1); if (segment && segment->m_type == ENUM_UNKNOWN) { if (segment->m_write) segment->m_type = ENUM_MODULE_DATA; else segment->m_type = ENUM_MODULE_TEXT; segment->m_module_name = (char*) core_to_mmap_addr((address_t)GetUInt(&linkmap->l_name)); #ifdef linux if (segment->m_module_name == NULL) { if (linkmap == gLinkMap_32) segment->m_module_name = gpInputExecName; else segment->m_module_name = "/lib/ld-linux-x86-64.so.2"; } #endif } } } if ((address_t)GetUInt(&linkmap->l_next) == 0) break; linkmap = (struct link_map_32*) core_to_mmap_addr((address_t)GetULong(&linkmap->l_next)); if (linkmap == gLinkMap_32) break; } #ifdef CA_DEBUG linkmap = gLinkMap_32; for (int i=0; linkmap; i++) { char* name = (char*) core_to_mmap_addr((address_t)GetUInt(&linkmap->l_name)); // find the strtab void* strtab = NULL; dyn = (Elf32_Dyn*) core_to_mmap_addr((address_t)GetUInt(&linkmap->l_ld)); while (dyn && GetUInt(&dyn->d_tag)) { if (GetUInt(&dyn->d_tag) == DT_STRTAB) strtab = (void*)GetUInt(&dyn->d_un.d_ptr); dyn++; }; printf("[%d] base=[0x%lx] name=%s .dyn=0x%lx\n", i, GetUInt(&linkmap->l_addr), name, GetUInt(&linkmap->l_ld)); if (linkmap->l_next == 0) break; linkmap = (struct link_map_32*) core_to_mmap_addr((address_t)GetUInt(&linkmap->l_next)); if (linkmap == gLinkMap_32) break; } #endif return true; }
static bool path_is_absolute(const ALLEGRO_PATH *path) { /* If the first segment is empty, we have an absolute path. */ return (_al_vector_size(&path->segments) > 0) && (al_ustr_size(get_segment(path, 0)) == 0); }
/* * Read a blx "record" * * In this layer "records" are internally thought of as the number of * bits to the next blank expansion character, but to the caller * there is no such thing as a FULL "blx" record. * * "records" and blocks are supported only in multiples of 8 bits. * There is no logical limit for the maximum record size. The * maximum block size is determined arbitrarily to be 512 words. * * Parameters: * fio - fdinfo block pointer * bufptr - bit pointer to where data is to go. * nbytes - number of bytes to be read * stat - pointer to status return word * fulp - full or partial write mode flag * ubc - pointer to unused bit count (not used) */ ssize_t _blx_read(struct fdinfo *fio, bitptr bufptr, size_t nbytes, struct ffsw *stat, int fulp, int *ubc) { int64 skip_len, nbits, bits, movdbits; int eorstat, ret; struct blx_info *blx_dat; nbits = (uint64)nbytes << 3; /* convert bytes to bits */ movdbits = 0; /* number of bits given to caller */ if (*ubc != 0) /* ubc should always be zero */ ERETURN(stat, FDC_ERR_UBC, 0); if (fio->rwflag == WRITIN) { /* read after write error */ ERETURN(stat, FDC_ERR_RAWR, 0); } fio->rwflag = READIN; /* set operation type */ /* * Get blx_info. */ blx_dat = (struct blx_info *)fio->lyr_info; /* * Loop until one of the following occurs: * - the caller's request of nbits is satisfied * - an EOF/EOD is found */ while ( movdbits < nbits ) /* while caller is not satisfied */ { bits = nbits - movdbits; /* bits to move this pass */ /* * If segment is empty and we're all out of blanks, get the * next segment. */ if ((fio->segbits == 0) && (blx_dat->u_blx == 0)) { ret = get_segment(fio, stat); if (ret != 0) { if ((ret == FFEOF) || (ret == FFEOD)) { if (movdbits != 0) { blx_dat->eor = _TRUE; goto chkdone; } fio->ateof = (ret == FFEOF ? 1:0); fio->ateod = (ret == FFEOD ? 1:0); fio->segbits = 0; SETSTAT(stat, ret, 0) return(0); } else return(ERR); /* Status should be set */ } }
/* get_segment_cstr: * Return the i'th directory component of a path as a C string. */ static const char *get_segment_cstr(const ALLEGRO_PATH *path, unsigned i) { return al_cstr(get_segment(path, i)); }
/* * Read TEXT records * * Records and blocks are supported only in multiples of 8 bits. * There is no logical limit for the maximum record size. The * maximum block size is determined arbitrarily to be 512 words. * * Parameters: * fio - Pointer to fdinfo block * bufptr - bit pointer to where data is to go. * nbytes - number of bytes to be read * stat - pointer to status return word * fulp - full or partial write mode flag * ubc - pointer to unused bit count (not used) */ ssize_t _txt_read(struct fdinfo *fio, bitptr bufptr, size_t nbytes, struct ffsw *stat,int fulp, int *ubc) { int64 nbits, bits, movdbits; int ret, eorstat; nbits = (uint64)nbytes << 3; /* convert bytes to bits */ movdbits = 0; if (*ubc != 0) /* ubc should always be zero */ ERETURN(stat, FDC_ERR_UBC, 0); /* read after write error */ if (fio->rwflag == WRITIN) ERETURN(stat, FDC_ERR_RAWR, 0); fio->rwflag = READIN; /* set operation type */ /* * If segment is empty, get the next segment. */ fio->ateor = 0; if (fio->segbits == 0) { ret = get_segment(fio, stat); /* if EOF or EOD found */ if (ret > 0) return(0); if (ret < 0) return(ret); /* stat set by get_segment */ } /* * Loop until one of the following occurs: * - the caller's request of nbits is satisfied * - an EOR is found * - an EOF is found * - an EOD is found */ eorstat = FFCNT; while ( nbits > 0 ) /* while caller is not satisfied */ { /* * If more bits are requested than are in the segment, return * segment. If the scc (segment operation from get_segment()) * equals SCCFULL then return (i.e., hit end-of-record (EOR)). * If the scc equals SCCMIDL (i.e., the fio buffer is empty and * no EOR was hit) subtract the number of bits moved from nbits * and go on. */ bits = nbits; if (fio->segbits < nbits) bits = fio->segbits; GETDATA(bufptr, fio, bits); movdbits += bits; SET_BPTR(bufptr, INC_BPTR(bufptr, bits)); nbits -= bits; if (fio->segbits == 0) { if (fio->scc == SCCFULL) { nbits = 0; /* return anyway */ eorstat = FFEOR; } else { ret = get_segment(fio, stat); /* if EOF or EOD found */ if (ret > 0) return(0); if (ret < 0) return(ret); /* stat set by get_segment */ } } } /* end while */ /* * Set status now, before doing any skip to EOR * Must check EOR status again... */ if ((fio->segbits == 0) && (fio->scc == SCCFULL)) eorstat = FFEOR; fio->recbits += movdbits; /* * If the mode is FULL and more bits are * available in the current record, -or- if * the number of bits requested just happpened to * be the number of bits in the record, skip to the next EOR. * If EOF/EOD found while skipping, set the status (this is an error) * and return. */ if ((fulp == FULL) || (eorstat == FFEOR)) { ret = skip2eor(fio, stat); if (ret > 0) return(0); /* EOF/EOD */ if (ret < 0) return(ERR); /* Status should be set */ fio->last_recbits = fio->recbits; fio->recbits = 0; } SETSTAT(stat, eorstat, (uint64)movdbits >> 3); /* assume CNT */ return ((uint64)movdbits >> 3); } /* end of _txt_read */
REQUIRE_APPROX_EQUAL(nec.get_impedance_real(0), 8.2698E+01 ); REQUIRE_APPROX_EQUAL(nec.get_impedance_imag(0), 4.6306E+01 ); nec_antenna_input* ai = nec.get_input_parameters(0); REQUIRE(ai->get_segment()[0] == 4 ); /* ----- ANTENNA INPUT PARAMETERS ----- TAG SEG VOLTAGE (VOLTS) CURRENT (AMPS) IMPEDANCE (OHMS) ADMITTANCE (MHOS) POWER NO. NO. REAL IMAGINARY REAL IMAGINARY REAL IMAGINARY REAL IMAGINARY (WATTS) 0 4 1.0000E+00 0.0000E+00 8.9547E-03 -4.0515E-03 9.2698E+01 4.1941E+01 8.9547E-03 -4.0515E-03 4.4773E-03 */ REQUIRE_APPROX_EQUAL(nec.get_impedance_real(1), 9.2698E+01 ); REQUIRE_APPROX_EQUAL(nec.get_impedance_imag(1), 4.1941E+01 ); ai = nec.get_input_parameters(1); REQUIRE(ai->get_segment()[0] == 4 ); REQUIRE_APPROX_EQUAL(ai->get_current()[0], nec_complex(8.9547E-03, -4.0515E-03) ); } TEST_CASE( "Voltage Excitation", "[voltage_excitation]") { /** CM A simple structure excited by a plane wave, and at multiple frequencies. CE go blue ! GW 0 36 0 0 0 -0.042 0.008 0.017 0.001 GE 0 GN -1 LD 5 0 0 0 3.720E+07 FR 0 1 0 0 2400
void exec_mb(char *kernel, char* modules) /* Get a Minix image into core, patch it up and execute. */ { int i; static char hdr[SECTOR_SIZE]; char *buf; u32_t vsec, addr, limit, n, totalmem = 0; u16_t kmagic, mode; char *console; char params[SECTOR_SIZE]; extern char *sbrk(int); char *verb; u32_t text_vaddr, text_paddr, text_filebytes, text_membytes; u32_t data_vaddr, data_paddr, data_filebytes, data_membytes; u32_t pc; u32_t text_offset, data_offset; i32_t segsize; int r; u32_t cs, ds; char *modstring, *mod; multiboot_info_t *mbinfo; multiboot_module_t *mbmodinfo; u32_t mbinfo_size, mbmodinfo_size; char *memvar; memory *mp; u32_t mod_cmdline_start, kernel_cmdline_start; u32_t modstringlen; int modnr; /* The stack is pretty deep here, so check if heap and stack collide. */ (void) sbrk(0); if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil) verboseboot = a2l(verb); printf("\nLoading %s\n", kernel); vsec= 0; /* Load this sector from kernel next. */ addr= mem[0].base; /* Into this memory block. */ limit= mem[0].base + mem[0].size; if (limit > caddr) limit= caddr; /* set click size for get_segment */ click_size = PAGE_SIZE; k_flags = K_KHIGH|K_BRET|K_MEML|K_INT86|K_RET|K_HDR |K_HIGH|K_CHMEM|K_I386; /* big kernels must be loaded into extended memory */ addr= mem[1].base; limit= mem[1].base + mem[1].size; /* Get first sector */ DEBUGEXTRA(("get_sector\n")); if ((buf= get_sector(vsec++)) == nil) { DEBUGEXTRA(("get_sector failed\n")); return; } memcpy(hdr, buf, SECTOR_SIZE); /* Get ELF header */ DEBUGEXTRA(("read_header_elf\n")); r = read_header_elf(hdr, &text_vaddr, &text_paddr, &text_filebytes, &text_membytes, &data_vaddr, &data_paddr, &data_filebytes, &data_membytes, &pc, &text_offset, &data_offset); if (r < 0) { errno= ENOEXEC; return; } /* Read the text segment. */ addr = text_paddr; segsize = (i32_t) text_filebytes; vsec = text_offset / SECTOR_SIZE; DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, segsize, addr, limit)); if (!get_segment(&vsec, &segsize, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx " "addr=0x%lx\n", vsec, segsize, addr)); /* Read the data segment. */ addr = data_paddr; segsize = (i32_t) data_filebytes; vsec = data_offset / SECTOR_SIZE; DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, segsize, addr, limit)); if (!get_segment(&vsec, &segsize, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx " "addr=0x%lx\n", vsec, segsize, addr)); n = data_membytes - align(data_filebytes, click_size); /* Zero out bss. */ DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit)); if (addr + n > limit) { errno= ENOMEM; return; } raw_clear(addr, n); DEBUGEXTRA(("done\n")); addr+= n; /* Check the kernel magic number. */ raw_copy(mon2abs(&kmagic), data_paddr + MAGIC_OFF, sizeof(kmagic)); if (kmagic != KERNEL_D_MAGIC) { printf("Kernel magic number is incorrect (0x%x@0x%lx)\n", kmagic, data_paddr + MAGIC_OFF); errno= 0; return; } /* Translate the boot parameters to what Minix likes best. */ DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params))); if (!params2params(params, sizeof(params))) { errno= 0; return; } DEBUGEXTRA(("done\n")); /* Create multiboot info struct */ mbinfo = malloc(sizeof(multiboot_info_t)); if (mbinfo == nil) { errno= ENOMEM; return; } memset(mbinfo, 0, sizeof(multiboot_info_t)); /* Module info structs start where kernel ends */ mbinfo->mods_addr = addr; modstring = strdup(modules); if (modstring == nil) {errno = ENOMEM; return; } modstringlen = strlen(modules); mbinfo->mods_count = split_module_list(modules); mbmodinfo_size = sizeof(multiboot_module_t) * mbinfo->mods_count; mbmodinfo = malloc(mbmodinfo_size); if (mbmodinfo == nil) { errno= ENOMEM; return; } addr+= mbmodinfo_size; addr= align(addr, click_size); mod_cmdline_start = mbinfo->mods_addr + sizeof(multiboot_module_t) * mbinfo->mods_count; raw_copy(mod_cmdline_start, mon2abs(modules), modstringlen+1); mbmodinfo[0].cmdline = mod_cmdline_start; modnr = 1; for (i= 0; i < modstringlen; ++i) { if (modules[i] == '\0') { mbmodinfo[modnr].cmdline = mod_cmdline_start + i + 1; ++modnr; } } kernel_cmdline_start = mod_cmdline_start + modstringlen + 1; mbinfo->cmdline = kernel_cmdline_start; raw_copy(kernel_cmdline_start, mon2abs(kernel), strlen(kernel)+1); mbinfo->flags = MULTIBOOT_INFO_MODS|MULTIBOOT_INFO_CMDLINE| MULTIBOOT_INFO_BOOTDEV|MULTIBOOT_INFO_MEMORY; mbinfo->boot_device = mbdev; mbinfo->mem_lower = mem[0].size/1024; mbinfo->mem_upper = mem[1].size/1024; for (i = 0, mod = strtok(modstring, " "); mod != nil; mod = strtok(nil, " "), i++) { mod = select_image(mod); if (mod == nil) {errno = 0; return; } mbmodinfo[i].mod_start = addr; mbmodinfo[i].mod_end = addr + image_bytes; mbmodinfo[i].pad = 0; segsize= image_bytes; vsec= 0; DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, segsize, addr, limit)); if (!get_segment(&vsec, &segsize, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx " "addr=0x%lx\n", vsec, segsize, addr)); addr+= segsize; addr= align(addr, click_size); } free(modstring); DEBUGEXTRA(("modinfo raw_copy: dst 0x%lx src 0x%lx sz 0x%lx\n", mbinfo->mods_addr, mon2abs(mbmodinfo), mbmodinfo_size)); raw_copy(mbinfo->mods_addr, mon2abs(mbmodinfo), mbmodinfo_size); free(mbmodinfo); raw_copy(MULTIBOOT_INFO_ADDR, mon2abs(mbinfo), sizeof(multiboot_info_t)); free(mbinfo); /* Run the trailer function just before starting Minix. */ DEBUGEXTRA(("run_trailer()... ")); if (!run_trailer()) { errno= 0; return; } DEBUGEXTRA(("done\n")); /* Set the video to the required mode. */ if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) { mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE : MONO_MODE; } DEBUGEXTRA(("set_mode(%d)... ", mode)); set_mode(mode); DEBUGEXTRA(("done\n")); /* Close the disk. */ DEBUGEXTRA(("dev_close()... ")); (void) dev_close(); DEBUGEXTRA(("done\n")); /* Minix. */ cs = ds = text_paddr; DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n", pc, cs, ds, params, sizeof(params), 0)); minix(pc, cs, ds, params, sizeof(params), 0); if (!(k_flags & K_BRET)) { extern u32_t reboot_code; raw_copy(mon2abs(params), reboot_code, sizeof(params)); } parse_code(params); /* Return from Minix. Things may have changed, so assume nothing. */ fsok= -1; errno= 0; /* Read leftover character, if any. */ scan_keyboard(); /* Restore screen contents. */ restore_screen(); }
CA_BOOL segment_command_impl(char* args) { struct ca_segment* segment; if (args) { address_t addr = ca_eval_address (args); segment = get_segment(addr, 0); if (segment) { CA_PRINT("Address %s belongs to segment:\n", args); print_segment(segment); } else CA_PRINT("Address %s doesn't belong to any segment\n", args); } else { unsigned int i; CA_PRINT("vaddr size perm name\n"); CA_PRINT("=====================================================\n"); for (i=0; i<g_segment_count; i++) { struct ca_segment* segment = &g_segments[i]; CA_PRINT("[%4d] ", i); print_segment(segment); } // Find out why SIZE is much bigger than RSS, it might be modules, thread stack or heap, or all /*if (!g_debug_core) { size_t heap_gap = 0, stack_gap = 0, module_gap = 0; // account for gap between RSS and SIZE int pid = ptid_get_pid (inferior_ptid); char fname[128]; FILE* fp; snprintf(fname, 128, "/proc/%d/smaps", pid); if ((fp = fopen (fname, "r")) != NULL) { int ret; // Now iterate until end-of-file. do { int k; address_t addr, endaddr, offset, inode; char permissions[8], device[8], filename[128]; size_t vsize, rss, dumb; ret = fscanf (fp, "%lx-%lx %s %lx %s %lx", &addr, &endaddr, permissions, &offset, device, &inode); if (ret <= 0 || ret == EOF) break; filename[0] = '\0'; if (ret > 0 && ret != EOF) ret += fscanf (fp, "%[^\n]\n", filename); ret = fscanf (fp, "Size: %ld kB\n", &vsize); ret = fscanf (fp, "Rss: %ld kB\n", &rss); for (k = 0; k < 11; k++) fgets(filename, 128, fp); // Pss, etc. //CA_PRINT("Segment: 0x%lx SIZE=%ld RSS=%ld\n", addr, vsize, rss); if (vsize > rss) { struct ca_segment* segment = get_segment(addr, 1); size_t gap = (vsize - rss) * 1024; if (segment) { if (segment->m_type == ENUM_STACK) stack_gap += gap; else if (segment->m_type == ENUM_MODULE_TEXT || segment->m_type == ENUM_MODULE_DATA) module_gap += gap; else if (segment->m_type == ENUM_HEAP) heap_gap += gap; } } } while(1); fclose(fp); CA_PRINT("Gap between SIZE and RSS:\n"); CA_PRINT("\tmodules: "); print_size(module_gap); CA_PRINT("\n"); CA_PRINT("\tthreads: "); print_size(stack_gap); CA_PRINT("\n"); CA_PRINT("\theap: "); print_size(heap_gap); CA_PRINT("\n"); } }*/ } return CA_TRUE; }
/** * simulate a single step * */ void simulation_step(int step) { _operations = 0; struct Segment *segment = get_segment(); irecv_field(); int fields = segment->width * segment->height; struct Field **movements = malloc(sizeof(struct Field *) * fields); get_movement_order(movements, fields); for (int i = 0; i < fields; i++) { _operations++; struct Field *field = movements[i]; if(is_near_border(field)) irecv_field(); if (field->population_type != EMPTY) { check_for_food(field); // suche nach Beute } } get_movement_order(movements, fields); for (int i = 0; i < fields; i++) { _operations++; struct Field *field = movements[i]; if(is_near_border(field)) irecv_field(); if (field->population_type != EMPTY) { // if the animal becomes to old or starves, it will die if (should_die(field)) { reset_field(field); } else { // has the animal on this field been moved before? (e.g. because it has found food) if(field->last_step < step) { struct Field *moved = move_animal(field); if(moved != 0) { field->last_step++; if(is_field_in_segment(moved)) { field = moved; } else { field = 0; // animal has moved, but is now out of our segment } } } if(field != 0) { // check, whether the animal is old enough and should get a child if (should_get_child(field->population_type)) { create_child(field); } field->energy -= 2; field->age++; } } } else if(field->population_type == EMPTY) { if(random_int(1, 100) <= (PLANT_RATE * 100)) { field->contains_plant = 1; } } } irecv_field(); free(movements); }