extern "C" CDECL void upcall_s_exchange_malloc(s_exchange_malloc_args *args) { rust_task *task = args->task; LOG_UPCALL_ENTRY(task); LOG(task, mem, "upcall exchange malloc(0x%" PRIxPTR ")", args->td); size_t total_size = get_box_size(args->size, args->td->align); // FIXME--does this have to be calloc? (Issue #2682) void *p = task->kernel->calloc(total_size, "exchange malloc"); rust_opaque_box *header = static_cast<rust_opaque_box*>(p); header->ref_count = -1; // This is not ref counted header->td = args->td; header->prev = 0; header->next = 0; args->retval = (uintptr_t)header; }
extern "C" CDECL void upcall_s_exchange_malloc(s_exchange_malloc_args *args) { rust_task *task = args->task; LOG_UPCALL_ENTRY(task); size_t total_size = get_box_size(args->size, args->td->align); void *p = task->kernel->malloc(total_size, "exchange malloc"); rust_opaque_box *header = static_cast<rust_opaque_box*>(p); header->ref_count = -1; // This is not ref counted header->td = args->td; header->prev = 0; header->next = 0; LOG(task, mem, "exchange malloced %p of size %" PRIuPTR, header, args->size); args->retval = (uintptr_t)header; }
rust_opaque_box *boxed_region::malloc(type_desc *td, size_t body_size) { size_t total_size = get_box_size(body_size, td->align); rust_opaque_box *box = (rust_opaque_box*)backing_region->malloc(total_size, "@"); box->td = td; box->ref_count = 1; box->prev = NULL; box->next = live_allocs; if (live_allocs) live_allocs->prev = box; live_allocs = box; LOG(rust_get_current_task(), box, "@malloc()=%p with td %p, size %lu==%lu+%lu, " "align %lu, prev %p, next %p\n", box, td, total_size, sizeof(rust_opaque_box), body_size, td->align, box->prev, box->next); return box; }
GRECT calculate_box( int reference, short x, short y, int attributes, FONTINFO* font_ptr, int parent_number ) { GRECT box ; BOOLEAN size_changed = FALSE ; box = get_box_size( reference, x, y, attributes, font_ptr, parent_number ) ; if( box.g_x - 1 < custom_tree.org_x ) { size_changed = TRUE ; if( custom_display.x_start <= custom_tree.org_x ) custom_display.x_start = box.g_x - 1 ; custom_tree.org_x = box.g_x - 1 ; send_redraw_message( &custom_display.custom_box, custom_form.fm_handle ) ; } if( rect_end( &box ) > custom_tree.lim_x ) { size_changed = TRUE ; custom_tree.lim_x = rect_end( &box ) + 1 ; } if( box.g_y - 1 < custom_tree.org_y ) { size_changed = TRUE ; if( custom_display.y_start <= custom_tree.org_y ) custom_display.y_start = box.g_y - 1 ; custom_tree.org_y = box.g_y - 1 ; send_redraw_message( &custom_display.custom_box, custom_form.fm_handle ) ; } if( rect_bottom( &box ) + 1 > custom_tree.lim_y ) { size_changed = TRUE ; custom_tree.lim_y = rect_bottom( &box ) + 1 ; } if( size_changed ) set_cust_sliders() ; return box ; }
Custom_couple* add_custom_coupling( Custom_person* Cp_ptr, short side ) { Custom_couple* Cc_ptr ; Custom_couple* sCc_ptr ; Custom_person* sCp_ptr ; /* spouse Cp pointer */ Custom_person* cCp_ptr ; /* child Cp pointer */ Person* pptr ; Couple* cptr ; BOOLEAN male ; /* sex of pre-existing partner */ short block ; int couple_reference = 0 ; int* new_coupling_list ; int* couple_list_ptr ; int* new_list_ptr ; char* coup_ptr ; int couple_ref ; /* Couple reference number */ int spouse_reference ; GRECT spouse_box ; short spouse_x ; short child_y ; int* child_number_ptr ; char* child_ptr ; int progeny[MAX_CHILDREN+1] ; int* prog_list_ptr ; short number_of_children ; short nearest_x ; short furthest_x ; short highest_y ; short parent_box_bottom ; Cc_ptr = new_custom_couple() ; if( Cc_ptr == NULL ) return Cc_ptr ; pptr = get_pdata_ptr( Cp_ptr->reference, &block ) ; coup_ptr = pptr->couplings ; new_coupling_list = (int *) checked_malloc( ( Cp_ptr->couplings_drawn + 2 ) * sizeof( int ) ) ; if( new_coupling_list == NULL ) { remove_custom_coupling( Cc_ptr ) ; return NULL ; } new_list_ptr = new_coupling_list ; /* find couple to add */ if( Cp_ptr->couplings_drawn != 0 ) { assert( Cp_ptr->coupling_list != NULL ) ; /* find first undrawn coupling */ while( couple_ref = form_ref( &coup_ptr ), couple_ref != 0 && couple_reference == 0 ) { BOOLEAN used ; couple_list_ptr = Cp_ptr->coupling_list ; used = FALSE ; while( *couple_list_ptr != 0 && couple_reference == 0 ) { sCc_ptr = get_Cc_ptr( *couple_list_ptr++) ; if( couple_ref == sCc_ptr->reference ) used = TRUE ; } if( !used ) couple_reference = couple_ref ; else couple_list_ptr++ ; } couple_list_ptr = Cp_ptr->coupling_list ; while( *couple_list_ptr ) *new_list_ptr++ = *couple_list_ptr++ ; free( Cp_ptr->coupling_list ) ; } else couple_reference = form_ref( &coup_ptr ) ; /* initialise some values */ *new_list_ptr++ = Cc_ptr->list_number ; *new_list_ptr++ = 0 ; Cc_ptr->reference = couple_reference ; Cp_ptr->coupling_list = new_coupling_list ; Cp_ptr->couplings_drawn++ ; Cc_ptr->y = Cp_ptr->y ; /* ascertain sex of existing */ /* partner and ref of spouse, if */ /* any */ if( couples[couple_reference].male_reference == Cp_ptr->reference ) { male = TRUE ; Cc_ptr->male_number = Cp_ptr->list_number ; spouse_reference = couples[couple_reference].female_reference ; } else { male = FALSE ; Cc_ptr->female_number = Cp_ptr->list_number ; spouse_reference = couples[couple_reference].male_reference ; } /* if spouse, add them to tree and */ /* calculate lowest point of couple */ if( spouse_reference != 0 ) { if( male && side == CUST_LEFT || !male && side == CUST_RIGHT ) Cc_ptr->status |= CUST_REVERSED ; spouse_box = get_box_size( spouse_reference, 0, 0, custom_tree.attributes, NULL, 0 ) ; if( side == RIGHT ) Cc_ptr->x = rect_end( &(Cp_ptr->box) ) + couple_gap ; else Cc_ptr->x = Cp_ptr->box.g_x - couple_gap ; if( side == RIGHT ) spouse_x = Cc_ptr->x + spouse_box.g_w / 2 + couple_gap ; else spouse_x = Cc_ptr->x - spouse_box.g_w / 2 - couple_gap ; sCp_ptr = add_custom_person( spouse_reference, spouse_x, Cc_ptr->y, NULL, 0 ) ; if( sCp_ptr != NULL ) { sCp_ptr->couplings_drawn = 1 ; if( male ) Cc_ptr->female_number = sCp_ptr->list_number ; else Cc_ptr->male_number = sCp_ptr->list_number ; sCp_ptr->coupling_list = (int *) checked_malloc( 2 * sizeof( int ) ) ; if( sCp_ptr->coupling_list != NULL ) { *(sCp_ptr->coupling_list) = Cc_ptr->list_number ; *(sCp_ptr->coupling_list + 1) = 0 ; /* terminate list */ } } if( rect_bottom( &(sCp_ptr->box) ) > rect_bottom( &(Cp_ptr->box) ) ) parent_box_bottom = rect_bottom( &(sCp_ptr->box) ) ; else parent_box_bottom = rect_bottom( &(Cp_ptr->box) ) ; } /* else if no spouse set bottom of */ /* couple to bottom of person and */ /* set spouse number to 0 */ else { Cc_ptr->x = Cp_ptr->x ; parent_box_bottom = rect_bottom( &(Cp_ptr->box) ) ; if( male ) Cc_ptr->female_number = 0 ; else Cc_ptr->male_number = 0 ; } /* set hline_y even if there are no */ /* children yet, ready for updating */ Cc_ptr->hline_y = parent_box_bottom + generation_gap / 2 ; Cc_ptr->hline_x0 = Cc_ptr->x ; Cc_ptr->hline_x1 = Cc_ptr->x ; /* if any children, add them to */ /* tree and couple list */ cptr = get_cdata_ptr( Cc_ptr->reference, &block ) ; if( child_ptr = cptr->children, child_ptr != NULL ) { prog_list_ptr = progeny ; number_of_children = 0 ; while( *prog_list_ptr++ = form_ref( &child_ptr ) ) { number_of_children++ ; } Cc_ptr->child_numbers = (int *) checked_malloc( ( number_of_children + 1 ) * sizeof( int ) ) ; if( Cc_ptr->child_numbers != NULL ) { int previous_last_number ; previous_last_number = custom_tree.end_person->list_number ; child_y = Cc_ptr->y + generation_gap ; /* measure width of children and add them at an arbitrary x position (i.e. 0) */ highest_y = child_y ; /* initialise to too low value */ add_children( progeny, 0, Cc_ptr, TRUE, 0, 0, child_y, &furthest_x, &highest_y) ; prog_list_ptr = progeny ; child_number_ptr = Cc_ptr->child_numbers ; while( *prog_list_ptr ) { *child_number_ptr++ = get_cust_person_by_ref( *prog_list_ptr++, previous_last_number ) ; } *child_number_ptr = 0 ; child_number_ptr = Cc_ptr->child_numbers ; cCp_ptr = get_Cp_ptr( Cc_ptr->child_numbers[0] ) ; nearest_x = cCp_ptr->x ; while( *child_number_ptr ) { cCp_ptr = get_Cp_ptr( *child_number_ptr++ ) ; cCp_ptr->x += Cc_ptr->x - ( nearest_x + furthest_x ) / 2 ; cCp_ptr->box.g_x += Cc_ptr->x - ( nearest_x + furthest_x ) / 2 ; cCp_ptr->y += Cc_ptr->hline_y + generation_gap / 2 - highest_y ; cCp_ptr->box.g_y += Cc_ptr->hline_y + generation_gap / 2 - highest_y ; } cCp_ptr = get_Cp_ptr( Cc_ptr->child_numbers[0] ) ; Cc_ptr->hline_x0 = cCp_ptr->x ; if( custom_display.x_start <= custom_tree.org_x ) { if( Cc_ptr->x - 1 < custom_display.x_start ) custom_display.x_start = Cc_ptr->x - 1 ; } cCp_ptr = get_Cp_ptr( Cc_ptr->child_numbers[number_of_children - 1] ) ; Cc_ptr->hline_x1 = cCp_ptr->x ; } } return Cc_ptr ; }
BOOLEAN add_children( int* child_refs, short first_child, Custom_couple* Cc_ptr, BOOLEAN rightwards, short upper_x, short lower_x, short base_position_y, short* furthest_x, short* highest_y) { Custom_person* child_ptr ; short child ; short sidestep ; short spacing ; BOOLEAN upper = TRUE ; GRECT box ; short upper_limit = upper_x ; short lower_limit = lower_x ; short child_position_x ; short child_position_y ; BOOLEAN fail = FALSE ; sidestep = rightwards ? 1 : -1 ; *furthest_x = upper_x ; child = first_child ; while( child >= 0 && child_refs[child] && !fail ) { box = get_box_size( child_refs[child], 0, 0, custom_tree.attributes, NULL, Cc_ptr->list_number ) ; spacing = box.g_w / 2 + sibling_gap ; if( upper ) { child_position_x = upper_limit + sidestep * spacing ; child_position_y = base_position_y ; } else { if( ( box.g_w / 2 ) < sidestep * ( upper_limit - lower_limit ) ) child_position_x = upper_limit + sidestep * sibling_gap ; else child_position_x = lower_limit + sidestep * spacing ; child_position_y = base_position_y + box.g_h ; } child_ptr = add_custom_person( child_refs[child], child_position_x, child_position_y, NULL, Cc_ptr->list_number ) ; if( child_ptr ) { child_ptr->parent_number = Cc_ptr->list_number ; Cc_ptr->child_numbers[child] = child_ptr->list_number ; if( upper ) { if( rightwards ) upper_limit = rect_end( &(child_ptr->box) ) + 1 ; else upper_limit = child_ptr->box.g_x ; } else { upper_limit = child_ptr->box.g_x + child_ptr->box.g_w / 2 ; if( rightwards ) lower_limit = rect_end( &(child_ptr->box) ) ; else lower_limit = child_ptr->box.g_x ; } upper = !upper ; *furthest_x = child_ptr->x ; if( child_ptr->box.g_y < *highest_y ) *highest_y = child_ptr->box.g_y ; child += sidestep ; } else fail = TRUE ; } if( fail ) /* remove all children who have been added */ { short failed_child ; failed_child = child ; child = first_child ; while( child != failed_child ) { child_ptr = get_Cp_ptr( Cc_ptr->child_numbers[child] ) ; remove_custom_person( child_ptr ) ; child += sidestep ; } } return fail ; }
Custom_couple* add_custom_parents( Custom_person* Cp_ptr ) { Custom_couple* Cc_ptr ; int siblings[MAX_CHILDREN] ; Custom_person* mCp_ptr = NULL ; /* pointer to male parent */ Custom_person* fCp_ptr = NULL ; /* pointer to female parent */ Person* pptr ; Couple* cptr ; int parents ; int father, mother ; int ref ; /* temporary reference */ short child ; /* loop counter */ short children ; /* number of siblings, inc original */ char* child_refs_ptr ; /* pointer to references */ short base_position_y ; /* y position of original child */ short upper_limit, lower_limit ; short leftest_sibling_x, rightest_sibling_x ; short highest_position_y ; short father_x, mother_x ; GRECT box_father, box_mother ; short parent_box_bottom ; short block ; /* block number for get_[p/c]data_ptr */ BOOLEAN fail = FALSE ; Cc_ptr = new_custom_couple() ; if( Cc_ptr == NULL ) return Cc_ptr ; pptr = get_pdata_ptr( Cp_ptr->reference, &block ) ; assert( pptr != NULL ) ; parents = pptr->parents ; assert( parents != 0 ) ; Cc_ptr->reference = parents ; Cp_ptr->parent_number = Cc_ptr->list_number ; cptr = get_cdata_ptr( parents, &block ) ; child_refs_ptr = cptr->children ; assert( child_refs_ptr ) ; /* Force temporary father number in order that */ /* auto_fname will work for add children. */ /* Note that male_reference is wrongly used, it */ /* will later be replaced with list number. */ Cc_ptr->male_number = couples[parents].male_reference ; /* if person has auto fname, their size will change */ /* with the addition of their father. Adjust their */ /* position to allow for this if they are coupled. */ if( cptr->male_reference != 0 && ( Cp_ptr->attributes & FNAME_AUTO_BIT || ( (Cp_ptr->attributes & FNAME_BITS) == 0 && custom_tree.attributes & FNAME_AUTO_BIT ) ) ) { Custom_couple* xCc_ptr ; short old_edge_x ; /* active edge of person's box */ short x_correction ; short reversed = FALSE ; short not_reversed = FALSE ; short coupling_index = 0 ; BOOLEAN left_partner = FALSE ; if( Cp_ptr->couplings_drawn != 0 ) { while( *(Cp_ptr->coupling_list + coupling_index) ) { xCc_ptr = get_Cc_ptr( *(Cp_ptr->coupling_list + coupling_index) ) ; assert( xCc_ptr ) ; if( xCc_ptr->status & CUST_REVERSED ) reversed = TRUE ; else not_reversed = TRUE ; coupling_index++ ; } /* check if adjustment is possible, i.e. all */ /* couplings on same side */ if( reversed && !not_reversed || not_reversed && !reversed ) { if( !reversed && xCc_ptr->male_number == Cp_ptr->list_number ) left_partner = TRUE ; if( left_partner ) old_edge_x = rect_end( &(Cp_ptr->box) ) ; else old_edge_x = Cp_ptr->box.g_x ; } } Cp_ptr->box = calculate_box( Cp_ptr->reference, Cp_ptr->x, Cp_ptr->y, Cp_ptr->attributes, Cp_ptr->font_ptr, Cp_ptr->parent_number ) ; if( Cp_ptr->couplings_drawn != 0 ) { if( left_partner ) x_correction = old_edge_x - rect_end( &(Cp_ptr->box) ) ; else x_correction = old_edge_x - Cp_ptr->box.g_x ; Cp_ptr->x += x_correction ; Cp_ptr->box.g_x += x_correction ; } } child = 0 ; while( ( ref = form_ref( &child_refs_ptr ) ) && ( child < MAX_CHILDREN ) ) { siblings[child] = ref ; child++ ; } siblings[child] = 0 ; children = child ; /* find current person in sibling array */ child = 0 ; while( siblings[child] != Cp_ptr->reference ) child++ ; Cc_ptr->child_numbers = (int*) checked_malloc( (children + 1) * sizeof( int ) ) ; if( Cc_ptr->child_numbers == NULL ) { Cp_ptr->parent_number = 0 ; remove_custom_coupling( Cc_ptr ) ; return NULL ; } Cc_ptr->child_numbers[child] = Cp_ptr->list_number ; Cc_ptr->child_numbers[children] = 0 ; /* terminate list */ upper_limit = Cp_ptr->box.g_x + Cp_ptr->box.g_w / 2 ; leftest_sibling_x = upper_limit ; /* initialise limits to centre of original */ rightest_sibling_x = upper_limit ; lower_limit = Cp_ptr->box.g_x ; base_position_y = Cp_ptr->box.g_y - Cp_ptr->box.g_h / 2 ; highest_position_y = Cp_ptr->box.g_y ; /* add any children to the left */ if( child >= 1 ) fail = add_children( siblings, child-1, Cc_ptr, FALSE, upper_limit, lower_limit, base_position_y, &leftest_sibling_x, &highest_position_y) ; else leftest_sibling_x = Cp_ptr->x ; if( fail ) { Cp_ptr->parent_number = 0 ; remove_custom_coupling( Cc_ptr ) ; return NULL ; } /* add any children to the right */ if( child+1 < children ) fail = add_children( siblings, child+1, Cc_ptr, TRUE, upper_limit, lower_limit, base_position_y, &rightest_sibling_x, &highest_position_y) ; else rightest_sibling_x = Cp_ptr->x ; if( fail ) { if( child >= 1 ) while( --child >= 0 ) remove_custom_person( get_Cp_ptr( Cc_ptr->child_numbers[child] ) ) ; Cp_ptr->parent_number = 0 ; remove_custom_coupling( Cc_ptr ) ; return NULL ; } if( father = couples[parents].male_reference ) box_father = get_box_size( father, 0, 0, custom_tree.attributes, NULL, 0 ) ; if( mother = couples[parents].female_reference ) box_mother = get_box_size( mother, 0, 0, custom_tree.attributes, NULL, 0 ) ; if( father ) Cc_ptr->y = highest_position_y - box_father.g_h - generation_gap ; else Cc_ptr->y = highest_position_y - box_mother.g_h - generation_gap ; Cc_ptr->x = (leftest_sibling_x + rightest_sibling_x) / 2 ; if( father && mother ) { father_x = Cc_ptr->x - box_father.g_w / 2 - couple_gap ; mother_x = Cc_ptr->x + box_mother.g_w / 2 + couple_gap ; } else { father_x = Cc_ptr->x ; mother_x = Cc_ptr->x ; } if( father ) { mCp_ptr = add_custom_person( father, father_x, Cc_ptr->y, NULL, 0 ) ; if( mCp_ptr != NULL ) { mCp_ptr->couplings_drawn = 1 ; Cc_ptr->male_number = mCp_ptr->list_number ; mCp_ptr->coupling_list = (int *) checked_malloc( 2 * sizeof( int ) ) ; if( mCp_ptr->coupling_list != NULL ) { *(mCp_ptr->coupling_list) = Cc_ptr->list_number ; *(mCp_ptr->coupling_list + 1) = 0 ; /* terminate list */ } else fail = TRUE ; parent_box_bottom = rect_bottom( &(mCp_ptr->box) ) ; } else fail = TRUE ; } if( !fail && mother ) { fCp_ptr = add_custom_person( mother, mother_x, Cc_ptr->y, NULL, 0 ) ; if( fCp_ptr != NULL ) { fCp_ptr->couplings_drawn = 1 ; Cc_ptr->female_number = fCp_ptr->list_number ; fCp_ptr->coupling_list = (int *) checked_malloc( 2 * sizeof( int ) ) ; if( fCp_ptr->coupling_list != NULL ) { *(fCp_ptr->coupling_list) = Cc_ptr->list_number ; *(fCp_ptr->coupling_list + 1) = 0 ; /* terminate list */ } else fail = TRUE ; } else fail = TRUE ; if( father ) { if( rect_bottom( &(fCp_ptr->box) ) > parent_box_bottom ) parent_box_bottom = rect_bottom( &(fCp_ptr->box) ) ; } else parent_box_bottom = rect_bottom( &(fCp_ptr->box) ) ; } Cc_ptr->hline_x0 = leftest_sibling_x ; Cc_ptr->hline_x1 = rightest_sibling_x ; Cc_ptr->hline_y = parent_box_bottom + generation_gap / 2 ; if( fail ) { /* remove children */ child = 0 ; while( child < children ) { if( Cc_ptr->child_numbers[child] != Cp_ptr->list_number ) remove_custom_person( get_Cp_ptr( Cc_ptr->child_numbers[child] ) ) ; child++ ; } if( mCp_ptr ) remove_custom_person( mCp_ptr ) ; if( fCp_ptr ) remove_custom_person( fCp_ptr ) ; Cp_ptr->parent_number = 0 ; remove_custom_coupling( Cc_ptr ) ; Cc_ptr = NULL ; } return Cc_ptr ; }