static void
sweep_pinned_objects_callback (char *ptr, size_t size, void *data)
{
	if (SGEN_OBJECT_IS_PINNED (ptr)) {
		SGEN_UNPIN_OBJECT (ptr);
		DEBUG (6, fprintf (gc_debug_file, "Unmarked pinned object %p (%s)\n", ptr, safe_name (ptr)));
	} else {
		DEBUG (6, fprintf (gc_debug_file, "Freeing unmarked pinned object %p (%s)\n", ptr, safe_name (ptr)));
		free_pinned_object (ptr, size);
	}
}
示例#2
0
/* LOCKING: requires that the GC lock is held */
static void
collect_bridge_objects (CopyOrMarkObjectFunc copy_func, char *start, char *end, int generation, GrayQueue *queue)
{
	SgenHashTable *hash_table = get_finalize_entry_hash_table (generation);
	MonoObject *object;
	gpointer dummy;
	char *copy;

	if (no_finalize)
		return;

	SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
		int tag = tagged_object_get_tag (object);
		object = tagged_object_get_object (object);

		/* Bridge code told us to ignore this one */
		if (tag == BRIDGE_OBJECT_MARKED)
			continue;

		/* Object is a bridge object and major heap says it's dead  */
		if (!((char*)object >= start && (char*)object < end && !major_collector.is_object_live ((char*)object)))
			continue;

		/* Nursery says the object is dead. */
		if (!object_is_fin_ready (object))
			continue;

		if (!mono_sgen_is_bridge_object (object))
			continue;

		copy = (char*)object;
		copy_func ((void**)&copy, queue);

		mono_sgen_bridge_register_finalized_object ((MonoObject*)copy);
		
		if (hash_table == &minor_finalizable_hash && !ptr_in_nursery (copy)) {
			/* remove from the list */
			SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);

			/* insert it into the major hash */
			mono_sgen_hash_table_replace (&major_finalizable_hash, tagged_object_apply (copy, tag), NULL);

			DEBUG (5, fprintf (gc_debug_file, "Promoting finalization of object %p (%s) (was at %p) to major table\n", copy, safe_name (copy), object));

			continue;
		} else {
			/* update pointer */
			DEBUG (5, fprintf (gc_debug_file, "Updating object for finalization: %p (%s) (was at %p)\n", copy, safe_name (copy), object));
			SGEN_HASH_TABLE_FOREACH_SET_KEY (tagged_object_apply (copy, tag));
		}
	} SGEN_HASH_TABLE_FOREACH_END;
示例#3
0
static void unparse_boolexp1( dbref player, BOOLEXP *b, char outer_type, int format ) {
    ATTR *ap;

    char sep_ch;

    char *buff;

    if( b == TRUE_BOOLEXP ) {
        if( format == F_EXAMINE ) {
            safe_str( ( char * ) "*UNLOCKED*", boolexp_buf, &buftop );
        }
        return;
    }
    switch( b->type ) {
    case BOOLEXP_AND:
        if( outer_type == BOOLEXP_NOT ) {
            safe_chr( '(', boolexp_buf, &buftop );
        }
        unparse_boolexp1( player, b->sub1, b->type, format );
        safe_chr( AND_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub2, b->type, format );
        if( outer_type == BOOLEXP_NOT ) {
            safe_chr( ')', boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_OR:
        if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) {
            safe_chr( '(', boolexp_buf, &buftop );
        }
        unparse_boolexp1( player, b->sub1, b->type, format );
        safe_chr( OR_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub2, b->type, format );
        if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) {
            safe_chr( ')', boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_NOT:
        safe_chr( '!', boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_INDIR:
        safe_chr( INDIR_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_IS:
        safe_chr( IS_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_CARRY:
        safe_chr( CARRY_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_OWNER:
        safe_chr( OWNER_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_CONST:
        if( !mudstate.standalone ) {
            switch( format ) {
            case F_QUIET:

                /*
                 * Quiet output - for dumps and internal use.
                 * Always #Num
                 */

                safe_str( ( char * ) unparse_object_quiet( player,
                          b->thing ), boolexp_buf, &buftop );
                break;
            case F_EXAMINE:

                /*
                 * Examine output - informative. *
                 * Name(#Num) or Name
                 */

                buff = unparse_object( player, b->thing, 0 );
                safe_str( buff, boolexp_buf, &buftop );
                free_lbuf( buff );
                break;
            case F_DECOMPILE:

                /*
                 * Decompile output - should be usable on
                 * other MUSHes. *Name if player, Name if
                 * thing, else #Num
                 */

                switch( Typeof( b->thing ) ) {
                case TYPE_PLAYER:
                    safe_chr( '*', boolexp_buf, &buftop );
                case TYPE_THING:
                    safe_name( b->thing, boolexp_buf,
                               &buftop );
                    break;
                default:
                    safe_dbref( boolexp_buf, &buftop,
                                b->thing );
                    break;
                }
                break;
            case F_FUNCTION:

                /*
                 * Function output - must be usable by @lock
                 * cmd.  *Name if player, else #Num
                 */

                switch( Typeof( b->thing ) ) {
                case TYPE_PLAYER:
                    safe_chr( '*', boolexp_buf, &buftop );
                    safe_name( b->thing, boolexp_buf,
                               &buftop );
                    break;
                default:
                    safe_dbref( boolexp_buf, &buftop,
                                b->thing );
                    break;
                }
            }
        } else {
            safe_str( ( char * ) unparse_object_quiet( player,
                      b->thing ), boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_ATR:
    case BOOLEXP_EVAL:
        if( b->type == BOOLEXP_EVAL ) {
            sep_ch = '/';
        } else {
            sep_ch = ':';
        }
        ap = atr_num( b->thing );
        if( ap && ap->number ) {
            safe_str( ( char * ) ap->name, boolexp_buf, &buftop );
        } else {
            safe_ltos( boolexp_buf, &buftop, b->thing );
        }
        safe_chr( sep_ch, boolexp_buf, &buftop );
        safe_str( ( char * ) b->sub1, boolexp_buf, &buftop );
        break;
    default:
        log_write_raw( 1, "ABORT! unparse.c, bad boolexp type in unparse_boolexp1().\n" );
        abort();
        break;
    }
}
示例#4
0
文件: entity.c 项目: usrshare/ltest
int creature_init(struct t_creature* o_entity, struct t_creature_generate_rules* genrules) {

    memset(o_entity,0,sizeof(struct t_creature));

    if ((genrules == NULL) || (genrules->gender = EG_RANDOM) || !vrange(&genrules->age)) {
	random_gender_and_age(&o_entity->age, &o_entity->gender_id); }
    else {
	if ((genrules) || vrange(&genrules->age)) {
	    o_entity->age = randrange(&genrules->age); } else o_entity->age = 18 + randval(40);


	enum entity_gender g_gender = genrules ? genrules->gender : EG_RANDOM;

	switch (g_gender) {
	    case EG_MALE: o_entity->gender_id = EG_MALE; break;
	    case EG_FEMALE: o_entity->gender_id = EG_FEMALE; break;
	    case EG_WMPATRIARCH: o_entity->gender_id = EG_WMPATRIARCH; break; //will be replaced with male after the name is generated.
	    case EG_NEUTRAL:
				 o_entity->gender_id = EG_NEUTRAL; o_entity->gender_bio = randbetween(EG_MALE,EG_FEMALE); break;
	    case EG_MBIAS:
				 o_entity->gender_id = (randval(100) < 75) ? EG_MALE : EG_FEMALE; break;
	    case EG_FBIAS:
				 o_entity->gender_id = (randval(100) < 75) ? EG_MALE : EG_FEMALE; break;
	    case EG_RANDOM:
	    default:
				 o_entity->gender_id = (randval(100) < 52) ? EG_FEMALE : EG_MALE; break; //52% females according to U.S. Census data
	}
    }

    if ((randval(100) < 1) && (o_entity->gender_bio == EG_RANDOM))
	o_entity->gender_bio = randbetween(EG_NEUTRAL,EG_FEMALE); else o_entity->gender_bio = o_entity->gender_id; //will result in mismatches for 0.67% of cases.

    o_entity->birthday_month = randval(12) + 1;

    switch(o_entity->birthday_month)
    {
	case 4:
	case 6:
	case 9:
	case 11:
	    o_entity->birthday_day=randval(30)+1;
	    break;
	case 2:
	    o_entity->birthday_day=randval(28)+1;
	    break;
	default:
	    o_entity->birthday_day=randval(31)+1;
	    break;
    }

    o_entity->id=curcreatureid++;

    for(int w=0;w<EB_COUNT;w++)o_entity->wound[w]=0;

    for(int a=0;a<EA_COUNT;a++)o_entity->attributes[a]=1;

    int attnum=32;

    if (genrules) {

	o_entity->type = genrules->type;

	for (int i=0; i < RANDATTRS; i++)
	    if (vrange(&genrules->attrlim[i])) o_entity->attributes[genrules->attrs[i]] = randrange(&genrules->attrlim[i]);
	for (int i=0; i < RANDSKILLS; i++)
	    if (vrange(&genrules->skilllim[i])) o_entity->skills[genrules->skill[i]] = randrange(&genrules->skilllim[i]);

	enum Alignment align = genrules->align;

	if (genrules->random_align) align += randbetween(-2,2);

	if (align < ALIGN_ARCHCONSERVATIVE) align = ALIGN_ARCHCONSERVATIVE;
	if (align > ALIGN_ELITELIBERAL) align = ALIGN_ELITELIBERAL;

	o_entity->align = align;
	o_entity->orig_align = align;

	if (vrange(&genrules->juice)) o_entity->juice = randrange(&genrules->juice);
	if (vrange(&genrules->money)) o_entity->money = randrange(&genrules->money);

	for (int i=0; i < RANDATTRS; i++)
	    if (vrange(&genrules->attrlim[i])) o_entity->attributes[genrules->attrs[i]] = randrange(&genrules->attrlim[i]);
	for (int i=0; i < RANDSKILLS; i++)
	    if (vrange(&genrules->skilllim[i])) o_entity->skills[genrules->skill[i]] = randrange(&genrules->skilllim[i]);
	if (vrange(&genrules->attrpts)) attnum = randrange(&genrules->attrpts); 

    }

    while(attnum>0)
    {
	int a=randval(EA_COUNT);
	if(o_entity->attributes[a]<10)
	{
	    o_entity->attributes[a]++;
	    attnum--;
	}
    }

    //at this point, both the entity's alignment and gender are fixed.
    //let's generate a name.

    random_first_name(o_entity->firstname,o_entity->gender_id);
    random_last_name(o_entity->lastname,o_entity->align == ALIGN_ARCHCONSERVATIVE,o_entity->gender_id);

    int wi=0; int wn=0;

    while ((wi < RANDWEAPONS) && (genrules->weapons[wi])) {
	wn++; wi++; }

    if (wn) {
    
    wi = randval(wn);

    struct t_item new_weapon = {.type = IT_WEAPON, .itemtypeid = genrules->weapons[wi], .ammo = 200};
    
    struct t_item clips = {.type = IT_CLIP, .itemtypeid = weapontypes[genrules->weapons[wi]].attacks[0].ammotype, .ammo = cliptypes[weapontypes[genrules->weapons[wi]].attacks[0].ammotype].ammo };


    struct t_item* added_weapon = inv_add(o_entity->inventory, &new_weapon);
    o_entity->weapon = added_weapon;

    }

    o_entity->special[ESW_TEETH]=TOOTHNUM;
    o_entity->special[ESW_RIGHTEYE]=1;
    o_entity->special[ESW_LEFTEYE]=1;
    o_entity->special[ESW_NOSE]=1;
    o_entity->special[ESW_TONGUE]=1;
    o_entity->special[ESW_RIGHTLUNG]=1;
    o_entity->special[ESW_LEFTLUNG]=1;
    o_entity->special[ESW_HEART]=1;
    o_entity->special[ESW_LIVER]=1;
    o_entity->special[ESW_STOMACH]=1;
    o_entity->special[ESW_RIGHTKIDNEY]=1;
    o_entity->special[ESW_LEFTKIDNEY]=1;
    o_entity->special[ESW_SPLEEN]=1;
    o_entity->special[ESW_RIBS]=RIBNUM;
    o_entity->special[ESW_NECK]=1;
    o_entity->special[ESW_UPPERSPINE]=1;
    o_entity->special[ESW_LOWERSPINE]=1;

    o_entity->blood = 100;
    o_entity->alive = true;
    o_entity->exists = true;

    return 0;
}

int entity_name(struct t_creature* who) {
    random_first_name(who->firstname,who->gender_id);
    random_last_name(who->lastname,who->align == ALIGN_ARCHCONSERVATIVE,who->gender_id);
    return 0;
}

char* entityattrstr[EA_COUNT] = {
    "STR",
    "INT",
    "WIS",
    "AGI",
    "CON",
    "CHA",
    "HRT"
};

const char* safe_name(const char* nameptr) {
    if ((nameptr == NULL) || (strlen(nameptr) == 0)) return "???";
    return nameptr;
}

int describe_entity(struct t_creature* me, char* const restrict o_name, size_t strsize) {
    if (me != NULL) {
	if (strlen(me->nickname) != 0) {
	    strncpy(o_name,me->nickname,strsize);
	    return 0;}

	if (((strlen(me->firstname) != 0) || (strlen(me->firstname) != 0)) && (me->name_known)) {
	    char fullname[66];
	    strncpy(fullname,safe_name(me->firstname),32);
	    strncat(fullname," ",1);
	    strncat(fullname,safe_name(me->lastname),32);
	    strncpy(o_name,fullname,strsize);
	    return 0; }

	const char* td = type_description(me);

	if (td) { strncpy(o_name,type_description(me),strsize); return 0; }

    }
    strncpy(o_name, "*",32);
    return 0;
}

char temp_name[16][128];
int temp_name_i = 0;

const char* describe_entity_static(struct t_creature* me) {
    int r = describe_entity(me,temp_name[temp_name_i],128);
    const char* ret = (r == 0 ? temp_name[temp_name_i] : NULL);
    temp_name_i = (temp_name_i+1) % 16;
    return ret;
}
示例#5
0
/* LOCKING: requires that the GC lock is held */
static void
finalize_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, int generation, GrayQueue *queue)
{
	FinalizeEntryHashTable *hash_table = get_finalize_entry_hash_table (generation);
	FinalizeEntry *entry, *prev;
	int i;
	FinalizeEntry **finalizable_hash = hash_table->table;
	mword finalizable_hash_size = hash_table->size;

	if (no_finalize)
		return;
	for (i = 0; i < finalizable_hash_size; ++i) {
		prev = NULL;
		for (entry = finalizable_hash [i]; entry;) {
			if ((char*)entry->object >= start && (char*)entry->object < end && !major_collector.is_object_live (entry->object)) {
				gboolean is_fin_ready = object_is_fin_ready (entry->object);
				char *copy = entry->object;
				copy_func ((void**)&copy, queue);
				if (is_fin_ready) {
					char *from;
					FinalizeEntry *next;
					/* remove and put in fin_ready_list */
					if (prev)
						prev->next = entry->next;
					else
						finalizable_hash [i] = entry->next;
					next = entry->next;
					num_ready_finalizers++;
					hash_table->num_registered--;
					queue_finalization_entry (entry);
					bridge_register_finalized_object ((MonoObject*)copy);
					/* Make it survive */
					from = entry->object;
					entry->object = copy;
					DEBUG (5, fprintf (gc_debug_file, "Queueing object for finalization: %p (%s) (was at %p) (%d/%d)\n", entry->object, safe_name (entry->object), from, num_ready_finalizers, hash_table->num_registered));
					entry = next;
					continue;
				} else {
					char *from = entry->object;
					if (hash_table == &minor_finalizable_hash && !ptr_in_nursery (copy)) {
						FinalizeEntry *next = entry->next;
						unsigned int major_hash;
						/* remove from the list */
						if (prev)
							prev->next = entry->next;
						else
							finalizable_hash [i] = entry->next;
						hash_table->num_registered--;

						entry->object = copy;

						/* insert it into the major hash */
						rehash_fin_table_if_necessary (&major_finalizable_hash);
						major_hash = mono_object_hash ((MonoObject*) copy) %
							major_finalizable_hash.size;
						entry->next = major_finalizable_hash.table [major_hash];
						major_finalizable_hash.table [major_hash] = entry;
						major_finalizable_hash.num_registered++;

						DEBUG (5, fprintf (gc_debug_file, "Promoting finalization of object %p (%s) (was at %p) to major table\n", copy, safe_name (copy), from));

						entry = next;
						continue;
					} else {
						/* update pointer */
						DEBUG (5, fprintf (gc_debug_file, "Updating object for finalization: %p (%s) (was at %p)\n", entry->object, safe_name (entry->object), from));
						entry->object = copy;
					}
				}
			}
			prev = entry;
			entry = entry->next;
		}
	}
}
示例#6
0
/* LOCKING: requires that the GC lock is held */
static int
finalizers_for_domain (MonoDomain *domain, MonoObject **out_array, int out_size,
	FinalizeEntryHashTable *hash_table)
{
	FinalizeEntry **finalizable_hash = hash_table->table;
	mword finalizable_hash_size = hash_table->size;
	FinalizeEntry *entry, *prev;
	int i, count;

	if (no_finalize || !out_size || !out_array)
		return 0;
	count = 0;
	for (i = 0; i < finalizable_hash_size; ++i) {
		prev = NULL;
		for (entry = finalizable_hash [i]; entry;) {
			if (mono_object_domain (entry->object) == domain) {
				FinalizeEntry *next;
				/* remove and put in out_array */
				if (prev)
					prev->next = entry->next;
				else
					finalizable_hash [i] = entry->next;
				next = entry->next;
				hash_table->num_registered--;
				out_array [count ++] = entry->object;
				DEBUG (5, fprintf (gc_debug_file, "Collecting object for finalization: %p (%s) (%d/%d)\n", entry->object, safe_name (entry->object), num_ready_finalizers, hash_table->num_registered));
				entry = next;
				if (count == out_size)
					return count;
				continue;
			}
			prev = entry;
			entry = entry->next;
		}
	}
	return count;
}
static void
pin_pinned_object_callback (void *addr, size_t slot_size, SgenGrayQueue *queue)
{
	binary_protocol_pin (addr, (gpointer)SGEN_LOAD_VTABLE (addr), mono_sgen_safe_object_get_size ((MonoObject*)addr));
	if (!SGEN_OBJECT_IS_PINNED (addr))
		mono_sgen_pin_stats_register_object ((char*) addr, mono_sgen_safe_object_get_size ((MonoObject*) addr));
	SGEN_PIN_OBJECT (addr);
	GRAY_OBJECT_ENQUEUE (queue, addr);
	DEBUG (6, fprintf (gc_debug_file, "Marked pinned object %p (%s) from roots\n", addr, safe_name (addr)));
}
static void
major_copy_or_mark_object (void **obj_slot, SgenGrayQueue *queue)
{
	char *forwarded;
	char *obj = *obj_slot;
	mword objsize;

	DEBUG (9, g_assert (current_collection_generation == GENERATION_OLD));

	HEAVY_STAT (++stat_copy_object_called_major);

	DEBUG (9, fprintf (gc_debug_file, "Precise copy of %p from %p", obj, obj_slot));

	/*
	 * obj must belong to one of:
	 *
	 * 1. the nursery
	 * 2. the LOS
	 * 3. a pinned chunk
	 * 4. a non-to-space section of the major heap
	 * 5. a to-space section of the major heap
	 *
	 * In addition, objects in 1, 2 and 4 might also be pinned.
	 * Objects in 1 and 4 might be forwarded.
	 *
	 * Before we can copy the object we must make sure that we are
	 * allowed to, i.e. that the object not pinned, not already
	 * forwarded and doesn't belong to the LOS, a pinned chunk, or
	 * a to-space section.
	 *
	 * We are usually called for to-space objects (5) when we have
	 * two remset entries for the same reference.  The first entry
	 * copies the object and updates the reference and the second
	 * calls us with the updated reference that points into
	 * to-space.  There might also be other circumstances where we
	 * get to-space objects.
	 */

	if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj))) {
		DEBUG (9, g_assert (((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr));
		DEBUG (9, fprintf (gc_debug_file, " (already forwarded to %p)\n", forwarded));
		HEAVY_STAT (++stat_major_copy_object_failed_forwarded);
		*obj_slot = forwarded;
		return;
	}
	if (SGEN_OBJECT_IS_PINNED (obj)) {
		DEBUG (9, g_assert (((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr));
		DEBUG (9, fprintf (gc_debug_file, " (pinned, no change)\n"));
		HEAVY_STAT (++stat_major_copy_object_failed_pinned);
		return;
	}

	if (ptr_in_nursery (obj))
		goto copy;

	/*
	 * At this point we know obj is not pinned, not forwarded and
	 * belongs to 2, 3, 4, or 5.
	 *
	 * LOS object (2) are simple, at least until we always follow
	 * the rule: if objsize > SGEN_MAX_SMALL_OBJ_SIZE, pin the
	 * object and return it.  At the end of major collections, we
	 * walk the los list and if the object is pinned, it is
	 * marked, otherwise it can be freed.
	 *
	 * Pinned chunks (3) and major heap sections (4, 5) both
	 * reside in blocks, which are always aligned, so once we've
	 * eliminated LOS objects, we can just access the block and
	 * see whether it's a pinned chunk or a major heap section.
	 */

	objsize = SGEN_ALIGN_UP (mono_sgen_safe_object_get_size ((MonoObject*)obj));

	if (G_UNLIKELY (objsize > SGEN_MAX_SMALL_OBJ_SIZE || obj_is_from_pinned_alloc (obj))) {
		if (SGEN_OBJECT_IS_PINNED (obj))
			return;
		DEBUG (9, fprintf (gc_debug_file, " (marked LOS/Pinned %p (%s), size: %zd)\n", obj, safe_name (obj), objsize));
		binary_protocol_pin (obj, (gpointer)SGEN_LOAD_VTABLE (obj), mono_sgen_safe_object_get_size ((MonoObject*)obj));
		SGEN_PIN_OBJECT (obj);
		GRAY_OBJECT_ENQUEUE (queue, obj);
		HEAVY_STAT (++stat_major_copy_object_failed_large_pinned);
		return;
	}

	/*
	 * Now we know the object is in a major heap section.  All we
	 * need to do is check whether it's already in to-space (5) or
	 * not (4).
	 */
	if (MAJOR_OBJ_IS_IN_TO_SPACE (obj)) {
		DEBUG (9, g_assert (objsize <= SGEN_MAX_SMALL_OBJ_SIZE));
		DEBUG (9, fprintf (gc_debug_file, " (already copied)\n"));
		HEAVY_STAT (++stat_major_copy_object_failed_to_space);
		return;
	}

 copy:
	HEAVY_STAT (++stat_objects_copied_major);

	*obj_slot = copy_object_no_checks (obj, queue);
}