/* * Change @val to resolve identifier to value @selval for selector @ca. * Return @val. * @val must be an identifier, and @selval must have been obtained from * nstr_match_val(@val, CA0, @idx), where @ca = &CA0[@IDX]. */ static struct valstr * nstr_resolve_val(struct valstr *val, int selval, struct castr *ca) { enum nsc_type type = nstr_promote(ca->ca_type); if (CANT_HAPPEN(val->val_cat != NSC_ID)) { val->val_cat = NSC_NOCAT; return val; } if (type == NSC_STRING) { val->val_type = NSC_STRING; val->val_cat = NSC_VAL; /* map identifier ~ to empty string, like some commands do */ if (val->val_as.str.maxsz == 1 && val->val_as.str.base[0] == '~') val->val_as.str.maxsz = 0; return val; } if (CANT_HAPPEN(type != NSC_LONG || ca->ca_table == EF_BAD)) { val->val_type = NSC_NOTYPE; val->val_cat = NSC_NOCAT; return val; } val->val_type = type; val->val_cat = NSC_VAL; val->val_as.lng = selval; return val; }
/* * Return amount due for @loan at time @paytime. */ double loan_owed(struct lonstr *loan, time_t paytime) { time_t rtime; /* regular interest time */ time_t xtime; /* double interest time */ double rate; int dur; /* * Split interval paytime - l_lastpay into regular (up to * l_duedate) and extended (beyond l_duedate) time. */ rtime = loan->l_duedate - loan->l_lastpay; xtime = paytime - loan->l_duedate; if (rtime < 0) { xtime += rtime; rtime = 0; } if (xtime < 0) { rtime += xtime; xtime = 0; } if (CANT_HAPPEN(rtime < 0)) rtime = 0; dur = loan->l_ldur; if (CANT_HAPPEN(dur <= 0)) dur = 1; rate = loan->l_irate / 100.0 / (dur * SECS_PER_DAY); return loan->l_amtdue * (1.0 + (rtime + xtime * 2) * rate); }
int display_mark(i_type only_itype, int only_cheapest) { struct comstr comm; struct comstr comm2; int sellers = 0; int cnt = 0; int cheapest_items[I_MAX + 1]; i_type i; /* Execute trades so report lists only lots that are still available. */ check_market(); check_trade(); pr("\n Empire Market Report\n "); prdate(); pr(" lot high bid/unit by time left owner item amount sector\n"); pr(" --- ------------- -- --------- ----- ---- ------ ------\n"); if (only_cheapest) { for (i = I_NONE + 1; i <= I_MAX; i++) cheapest_items[i] = -1; for (sellers = 0; getcomm(sellers, &comm); sellers++) { if (comm.com_owner == 0) continue; if (CANT_HAPPEN(comm.com_type <= I_NONE || comm.com_type > I_MAX)) continue; if (cheapest_items[comm.com_type] != -1) { getcomm(cheapest_items[comm.com_type], &comm2); if (comm.com_price < comm2.com_price) { cheapest_items[comm.com_type] = sellers; } } else { cheapest_items[comm.com_type] = sellers; } } CANT_HAPPEN(only_itype != I_NONE); /* not implemented */ for (i = I_NONE + 1; i <= I_MAX; i++) { if (cheapest_items[i] == -1) continue; getcomm(cheapest_items[i], &comm); cnt = 1; pr_mark(&comm); } } else { for (sellers = 0; getcomm(sellers, &comm); sellers++) { if (comm.com_owner == 0) continue; if (only_itype != I_NONE && comm.com_type != only_itype) continue; cnt = 1; pr_mark(&comm); } } if (cnt <= 0) pr("\nHmmmm, the market seems to be empty today.\n"); else pr("\nLooks just like Christmas at K-mart, doesn't it!\n"); return RET_OK; }
static void unit_list(struct emp_qelem *unit_list) { struct emp_qelem *qp; struct emp_qelem *next; struct ulist *ulp; int type, npln, nch, nxl; struct empobj *unit; struct lndstr *lnd; struct shpstr *shp; if (CANT_HAPPEN(QEMPTY(unit_list))) return; qp = unit_list->q_back; ulp = (struct ulist *)qp; type = ulp->unit.gen.ef_type; if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP)) return; if (type == EF_LAND) pr("lnd# land type x,y a eff mil sh gun xl ln mu tech retr\n"); else pr("shp# ship type x,y fl eff mil sh gun pn he xl ln mob tech\n"); for (; qp != unit_list; qp = next) { next = qp->q_back; ulp = (struct ulist *)qp; lnd = &ulp->unit.land; shp = &ulp->unit.ship; unit = &ulp->unit.gen; if (CANT_HAPPEN(type != unit->ef_type)) continue; pr("%4d ", unit->uid); pr("%-16.16s ", empobj_chr_name(unit)); prxy("%4d,%-4d ", unit->x, unit->y); pr("%1.1s", &unit->group); pr("%4d%%", unit->effic); if (type == EF_LAND) { pr("%4d", lnd->lnd_item[I_MILIT]); pr("%4d", lnd->lnd_item[I_SHELL]); pr("%4d", lnd->lnd_item[I_GUN]); pr("%3d%3d", lnd_nxlight(lnd), lnd_nland(lnd)); } else { pr("%4d", shp->shp_item[I_MILIT]); pr("%4d", shp->shp_item[I_SHELL]); pr("%4d", shp->shp_item[I_GUN]); npln = shp_nplane(shp, &nch, &nxl, NULL); pr("%3d%3d%3d", npln - nch - nxl, nch, nxl); pr("%3d", shp_nland(shp)); } pr("%4d", unit->mobil); pr("%4d", unit->tech); if (type == EF_LAND) { pr("%4d%%", lnd->lnd_retreat); } pr("\n"); } }
/* * Add to @cl's cargo list for type @type the uid @uid. * @uid must not be on any cargo list already. */ static void clink_add(struct clink *cl, int type, int uid) { int *head = clink_headp(cl, type); if (CANT_HAPPEN(type < 0 || type > EF_NUKE || uid < 0 || uid >= nclink[type])) return; if (CANT_HAPPEN(*head >= nclink[type])) *head = -1; CANT_HAPPEN(clink[type][uid].next >= 0); clink[type][uid].next = *head; *head = uid; }
/* * Get build materials from sector @sp. * @bp is the sector's build pointer. * @mvec[] defines the materials needed to build 100%. * @pct is the percentage to build. * Adjust build percentage downwards so that available materials * suffice. Remove the materials. * Return adjusted build percentage. */ int get_materials(struct sctstr *sp, struct bp *bp, int *mvec, int pct) { int i, amt; for (i = I_NONE + 1; i <= I_MAX; i++) { if (mvec[i] == 0) continue; amt = bp_get_item(bp, sp, i); if (amt * 100 < mvec[i] * pct) pct = amt * 100 / mvec[i]; } for (i = I_NONE + 1; i <= I_MAX; i++) { if (mvec[i] == 0) continue; amt = bp_get_item(bp, sp, i); amt -= roundavg(mvec[i] * pct / 100.0); if (CANT_HAPPEN(amt < 0)) amt = 0; bp_put_item(bp, sp, i, amt); if (!player->simulation) sp->sct_item[i] = amt; } return pct; }
/* * Dump @val prefixed with @sep to @xd, in machine readable format. * @val must be evaluated. * Return " ". */ static char * xdprval_nosym(struct xdstr *xd, struct valstr *val, char *sep) { if (CANT_HAPPEN(val->val_cat != NSC_VAL)) { xd->pr("%snil", sep); return " "; } switch (val->val_type) { case NSC_LONG: xd->pr("%s%ld", sep, val->val_as.lng); break; case NSC_DOUBLE: xd->pr("%s%#g", sep, val->val_as.dbl); break; case NSC_STRING: if (val->val_as.str.base) { xd->pr("%s\"", sep); xdpresc(xd, val->val_as.str.base, val->val_as.str.maxsz); xd->pr("\""); } else xd->pr("%snil", sep); break; default: CANT_REACH(); xd->pr("%snil", sep); } return " "; }
void lwp_rwlock_unlock(struct lwp_rwlock *rwlock) { struct lwpProc *p; int maxpri; lwpStatus(LwpCurrent, "unlocking rwlock %s", rwlock->name); if (CANT_HAPPEN(rwlock->count == 0)) return; if (rwlock->count < 0) rwlock->count = 0; else rwlock->count--; if (rwlock->count == 0 && rwlock->wq.head) { p = lwpGetFirst(&rwlock->wq); lwpStatus(p, "wake up next writer of rwlock %s", rwlock->name); maxpri = p->pri; lwpReady(p); } else if (rwlock->count >= 0 && rwlock->rq.head && !rwlock->wq.head) { maxpri = 0; while ((p = lwpGetFirst(&rwlock->rq))) { lwpStatus(p, "wake up next reader of rwlock %s", rwlock->name); maxpri = MAX(maxpri, p->pri); lwpReady(p); } } else return; if (LwpCurrent->pri < maxpri) { lwpStatus(LwpCurrent, "yielding to thread with higher priority"); lwpYield(); } }
static void unit_view(struct emp_qelem *list) { struct sctstr sect; struct emp_qelem *qp; struct emp_qelem *next; struct ulist *ulp; for (qp = list->q_back; qp != list; qp = next) { next = qp->q_back; ulp = (struct ulist *)qp; if (CANT_HAPPEN(!(ef_flags(ulp->unit.gen.ef_type) & EFF_XY))) continue; getsect(ulp->unit.gen.x, ulp->unit.gen.y, §); if (ulp->unit.gen.ef_type == EF_SHIP) { if (mchr[ulp->unit.ship.shp_type].m_flags & M_FOOD) pr("[fert:%d] ", sect.sct_fertil); if (mchr[ulp->unit.ship.shp_type].m_flags & M_OIL) pr("[oil:%d] ", sect.sct_oil); } pr("%s @ %s %d%% %s\n", unit_nameof(&ulp->unit.gen), xyas(ulp->unit.gen.x, ulp->unit.gen.y, player->cnum), sect.sct_effic, dchr[sect.sct_type].d_name); } }
/* * Is identifier @val the name of the selector given by @ca and @idx? * Return non-zero if and only if @idx is non-negative and @val is the * name of @ca[@idx]. * @idx must have been obtained from nstr_match_ca(@val, @ca). */ static int nstr_is_name_of_ca(struct valstr *val, struct castr *ca, int idx) { if (CANT_HAPPEN(val->val_cat != NSC_ID && idx >= 0)) return 0; return idx >= 0 && strlen(ca[idx].ca_name) == val->val_as.str.maxsz; }
int do_look(int type) { int i; struct nstr_item ni; union empobj_storage unit; struct sctstr sect; int x, y; unsigned char *bitmap; int changed = 0; if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP)) type = EF_SHIP; if (!snxtitem(&ni, type, player->argp[1], NULL)) return RET_SYN; bitmap = calloc((WORLD_SZ() + 7) / 8, 1); if (!bitmap) { logerror("malloc failed in do_look\n"); pr("Memory error. Tell the deity.\n"); return RET_FAIL; } while (nxtitem(&ni, &unit)) { if (!player->owner) continue; if (type == EF_LAND) { if (unit.land.lnd_ship >= 0) continue; if (unit.land.lnd_land >= 0) continue; /* Spies don't need military to do a "llook". Other units do */ if ((unit.land.lnd_item[I_MILIT] <= 0) && !(lchr[(int)unit.land.lnd_type].l_flags & L_SPY)) continue; look_land(&unit.land); } else look_ship(&unit.ship); for (i = 0; i <= 6; i++) { x = diroff[i][0] + unit.gen.x; y = diroff[i][1] + unit.gen.y; if (emp_getbit(x, y, bitmap)) continue; emp_setbit(x, y, bitmap); getsect(x, y, §); if (sect.sct_type == SCT_WATER) continue; look_at_sect(§, 10); changed += map_set(player->cnum, x, y, dchr[sect.sct_type].d_mnem, 0); if (opt_HIDDEN) { setcont(player->cnum, sect.sct_own, FOUND_LOOK); } } } if (changed) writemap(player->cnum); free(bitmap); return RET_OK; }
/* * Dump @val prefixed with @sep to @xd, return " ". * @val must be evaluated. * @ca describes the field from which the value was fetched. */ static char * xdprval_sym(struct xdstr *xd, struct valstr *val, struct castr *ca, char *sep) { unsigned long bit; if (CANT_HAPPEN(val->val_cat != NSC_VAL)) { xd->pr("%snil", sep); return " "; } if (!xd->human || val->val_type != NSC_LONG || ca->ca_table == EF_BAD || ef_cadef(ca->ca_table) != symbol_ca) return xdprval_nosym(xd, val, sep); if (ca->ca_flags & NSC_BITS) { xd->pr("%s(", sep); sep = ""; for (bit = 1; bit; bit <<= 1) { if (bit & val->val_as.lng) sep = xdprsym(xd, bit, ca->ca_table, sep); } xd->pr(")"); return " "; } return xdprsym(xd, val->val_as.lng, ca->ca_table, sep); }
int line_of_sight(char **rad, int ax, int ay, int bx, int by) { int dxn = XNORM(bx - ax); int dyn = YNORM(by - ay); int dx = dxn > WORLD_X / 2 ? dxn - WORLD_X : dxn; int dy = dyn > WORLD_Y / 2 ? dyn - WORLD_Y : dyn; int dlen = LEN(dx, dy); int n; int cx = 0; int cy = 0; int tx, ty; /* test point */ double cd_dist = dlen; /* closest distance from c to vector d */ double md_dist; /* minimum distance from t to vector d */ double td_dist; /* distance from t to vector d */ double td_proj; /* the projection of t onto vector d */ int closest; /* index of closest */ int blocked = 0; struct sctstr *sectp; while (cd_dist) { if (blocked) return 0; md_dist = 100; /* will always be <= 2 */ closest = -1; for (n = 1; n <= 6; ++n) { /* Directions */ tx = cx + diroff[n][0]; ty = cy + diroff[n][1]; if (DIST(tx, ty, dx, dy) >= cd_dist) continue; td_proj = (double)DOT(tx, ty, dx, dy) / dlen; td_dist = DIST(tx, ty, td_proj * dx, td_proj * dy); if (td_dist < md_dist) { md_dist = td_dist; closest = n; } } if (CANT_HAPPEN(closest < 0)) return 0; cx = cx + diroff[closest][0]; cy = cy + diroff[closest][1]; if (rad) { blocked = (rad[YNORM(ay + cy)][XNORM(ax + cx)] != dchr[SCT_WATER].d_mnem); } else { sectp = getsectp((ax + cx), (ay + cy)); if (sectp) { if (sectp->sct_type == SCT_WATER || sectp->sct_type == SCT_BSPAN) { blocked = 0; } else { blocked = 1; } } } cd_dist = DIST(cx, cy, dx, dy); } return 1; }
void lwp_rwlock_destroy(struct lwp_rwlock *rwlock) { if (CANT_HAPPEN(rwlock->count)) return; free(rwlock->name); free(rwlock); }
char * prnatid(natid cnum) { struct natstr *np = getnatp(cnum); if (CANT_HAPPEN(!np)) return prbuf("%d (#%d)", cnum, cnum); return prnat(np); }
/* * Return how much of product @pp can be made from its resource. * If @pp depletes a resource, @resource must point to its value. */ int prod_resource_limit(struct pchrstr *pp, unsigned char *resource) { if (CANT_HAPPEN(pp->p_nrndx && !resource)) return 0; if (resource && pp->p_nrdep != 0) return *resource * 100 / pp->p_nrdep; return ITEM_MAX; }
static void materials_charge(struct pchrstr *pp, short *vec, int count) { int i, n; i_type item; for (i = 0; i < MAXPRCON; ++i) { item = pp->p_ctype[i]; if (!pp->p_camt[i]) continue; if (CANT_HAPPEN(item <= I_NONE || I_MAX < item)) continue; n = vec[item] - pp->p_camt[i] * count; if (CANT_HAPPEN(n < 0)) n = 0; vec[item] = n; } }
/* * Return the item value tracked in BP for sector SP's item COMM. * COMM must be a tracked item type. */ int bp_get_item(struct bp *bp, struct sctstr *sp, i_type comm) { enum bp_item_idx idx = bud_key[comm]; if (CANT_HAPPEN(idx < 0)) return sp->sct_item[comm]; return bp_ref(bp, sp)->bp_item[idx]; }
double sector_mcost(struct sctstr *sp, int mobtype) { double base, cost; base = dchr[sp->sct_type].d_mob0; if (base < 0) return -1.0; if (mobtype == MOB_RAIL && opt_RAILWAYS) { if (!SCT_HAS_RAIL(sp)) return -1; mobtype = MOB_MARCH; } /* linear function in eff, d_mob0 at 0%, d_mob1 at 100% */ base += (dchr[sp->sct_type].d_mob1 - base) * sp->sct_effic / 100; if (CANT_HAPPEN(base < 0)) base = 0; if (mobtype == MOB_MOVE || mobtype == MOB_MARCH) { /* linear function in road, base at 0%, base/10 at 100% */ cost = base; if (intrchr[INT_ROAD].in_enable) cost -= base * 0.009 * sp->sct_road; } else if (mobtype == MOB_RAIL) { if (!intrchr[INT_RAIL].in_enable || sp->sct_rail <= 0) return -1.0; /* linear function in rail, base at 0%, base/100 at 100% */ cost = base - base * 0.0099 * sp->sct_rail; } else { CANT_REACH(); cost = base; } if (CANT_HAPPEN(cost < 0)) cost = 0; if (mobtype == MOB_MOVE) return MAX(cost, 0.001); if (sp->sct_own != sp->sct_oldown && sp->sct_mobil <= 0) /* slow down land units in newly taken sectors */ return cost + 0.2; return MAX(cost, 0.02); }
static char * unit_move_route(struct empobj *unit, char *buf, size_t bufsz) { coord destx; coord desty; struct sctstr sect; size_t len; double c; int mtype; if (CANT_HAPPEN(unit->ef_type != EF_LAND && unit->ef_type != EF_SHIP)) return NULL; if (!sarg_xy(buf, &destx, &desty)) return buf; if (unit->ef_type == EF_SHIP) { c = path_find(unit->x, unit->y, destx, desty, player->cnum, MOB_SAIL); if (c < 0 || unit->mobil <= 0) { pr("Can't get to '%s' right now.\n", xyas(destx, desty, player->cnum)); return NULL; } } else { getsect(unit->x, unit->y, §); mtype = lnd_mobtype((struct lndstr *)unit); /* * Note: passing sect.sct_own for actor is funny, but works: * its only effect is to confine the search to that nation's * land. It doesn't affect mobility costs. The real actor is * different for marching in allied land, and passing it would * break path finding there. */ c = path_find(unit->x, unit->y, destx, desty, sect.sct_own, mtype); if (c < 0) { pr("No owned %s from %s to %s!\n", mtype == MOB_RAIL ? "railway" : "path", xyas(unit->x, unit->y, player->cnum), xyas(destx, desty, player->cnum)); return NULL; } } len = path_find_route(buf, bufsz, unit->x, unit->y, destx, desty); if (len == 0 || unit->ef_type == EF_LAND) { if (len + 1 < bufsz) strcpy(buf + len, "h"); len++; } if (len >= bufsz) { pr("Can't handle path to %s, it's too long, sorry\n", xyas(destx, desty, player->cnum)); return NULL; } pr("Using path '%s'\n", buf); return buf; }
void setrej(natid us, natid them, int how, int what) { struct natstr *np = getnatp(us); if (CANT_HAPPEN(!np)) return; putreject(np, them, how, what); putnat(np); }
void setcont(natid us, natid them, int contact) { struct natstr *np = getnatp(us); if (CANT_HAPPEN(!np)) return; putcontact(np, them, contact); putnat(np); }
/* * Parse a value in @str into @val. * Return a pointer to the first character after the value. * Value is either evaluated into NSC_STRING, NSC_DOUBLE or NSC_LONG, * or an identifier. */ static char * nstr_parse_val(char *str, struct valstr *val) { long l; double d; char *tail, *tail2; /* string */ if (str[0] == '\'') { for (tail = str + 1; *tail && *tail != '\''; ++tail) ; /* FIXME implement \ quoting */ val->val_type = NSC_STRING; val->val_cat = NSC_VAL; val->val_as.str.base = str + 1; val->val_as.str.maxsz = tail - (str + 1); if (*tail) ++tail; /* FIXME else unclosed string */ return tail; } /* identifier */ if (isalpha(str[0])) { for (tail = str+1; isalnum(*tail) || *tail == '_'; ++tail) ; val->val_type = NSC_NOTYPE; val->val_cat = NSC_ID; val->val_as.str.base = str; val->val_as.str.maxsz = tail - str; return tail; } /* number */ l = strtol(str, &tail, 0); d = strtod(str, &tail2); if (tail2 > tail) { val->val_type = NSC_DOUBLE; val->val_cat = NSC_VAL; val->val_as.dbl = d; return tail2; } if (tail != str) { val->val_type = NSC_LONG; val->val_cat = NSC_VAL; val->val_as.lng = l; return tail; } /* funny character, interpret as identifier */ tail = CANT_HAPPEN(!*str) ? str : str + 1; val->val_type = NSC_NOTYPE; val->val_cat = NSC_ID; val->val_as.str.base = str; val->val_as.str.maxsz = tail - str; return tail; }
/* * Return pointer to @cl's cargo list head for file type @type. */ static int * clink_headp(struct clink *cl, int type) { static int dummy; if (CANT_HAPPEN(type < EF_PLANE || type > EF_NUKE)) { dummy = -1; return &dummy; } return &cl->head[type - EF_PLANE]; }
/* unload_it * A guess alot of this looks like load_it but because of its location * in the autonav code I had to split the 2 procedures up. * unload_it dumps all the goods from the ship to the harbor. * ONLY goods in the trade fields will be unloaded. * new autonav code * Chad Zabel 6/1/94 */ void unload_it(struct shpstr *sp) { struct sctstr *sectp; int i; int landowner; int shipown; i_type comm; int sect_amt; int ship_amt; int max_amt; sectp = getsectp(sp->shp_x, sp->shp_y); landowner = sectp->sct_own; shipown = sp->shp_own; for (i = 0; i < TMAX; ++i) { if (sp->shp_tend[i] == I_NONE || sp->shp_lend[i] == 0) continue; if (landowner == 0) continue; if (sectp->sct_type != SCT_HARBR) continue; comm = sp->shp_tend[i]; if (CANT_HAPPEN(comm <= I_NONE || comm > I_MAX)) continue; ship_amt = sp->shp_item[comm]; sect_amt = sectp->sct_item[comm]; /* check for disloyal civilians */ if (sectp->sct_oldown != shipown && comm == I_CIVIL) { wu(0, sp->shp_own, "Ship #%d - unable to unload civilians into a disloyal sector at %s.", sp->shp_uid, xyas(sectp->sct_x, sectp->sct_y, sp->shp_own)); continue; } if (comm == I_CIVIL) ship_amt--; /* This leaves 1 civs on board the ship */ max_amt = MIN(ship_amt, ITEM_MAX - sect_amt); if (max_amt <= 0) continue; sp->shp_item[comm] = ship_amt - max_amt; sectp->sct_item[comm] = sect_amt + max_amt; if (sectp->sct_pstage == PLG_INFECT && sp->shp_pstage == PLG_HEALTHY) sp->shp_pstage = PLG_EXPOSED; if (sp->shp_pstage == PLG_INFECT && sectp->sct_pstage == PLG_HEALTHY) sectp->sct_pstage = PLG_EXPOSED; } }
static void prhold(int hold, i_type itype, int amt) { if (itype != I_NONE && amt != 0) { if (CANT_HAPPEN(itype <= I_NONE || itype > I_MAX)) return; pr("%d-", hold + 1); pr("%c", ichr[itype].i_mnem); pr(":"); pr("%d ", amt); } }
/* * Remove from @cl's cargo list for type @type the uid @uid. * @uid must be on that cargo list. */ static void clink_rem(struct clink *cl, int type, int uid) { int *head = clink_headp(cl, type); struct clink *linkv; int n; int *p; if (CANT_HAPPEN(type < 0 || type > EF_NUKE)) return; linkv = clink[type]; n = nclink[type]; for (p = head; *p != uid; p = &linkv[*p].next) { if (CANT_HAPPEN(*p < 0 || *p >= n)) return; } *p = linkv[uid].next; linkv[uid].next = -1; }
void lwp_rwlock_wrlock(struct lwp_rwlock *rwlock) { if (rwlock->count) { lwpAddTail(&rwlock->wq, LwpCurrent); lwpStatus(LwpCurrent, "blocked to acquire rwlock %s for writing", rwlock->name); lwpReschedule(); } CANT_HAPPEN(rwlock->count != 0); rwlock->count = -1; lwpStatus(LwpCurrent, "acquired rwlock %s for writing", rwlock->name); }
void lwp_rwlock_rdlock(struct lwp_rwlock *rwlock) { if (rwlock->count < 0 || rwlock->wq.head) { lwpStatus(LwpCurrent, "blocked to acquire rwlock %s for reading", rwlock->name); lwpAddTail(&rwlock->rq, LwpCurrent); lwpReschedule(); } CANT_HAPPEN(rwlock->count < 0); rwlock->count++; lwpStatus(LwpCurrent, "acquired rwlock %s for reading", rwlock->name); }
/* * Dump symbol with value @key from symbol table @type to @xd. * Prefix with @sep, return " ". */ static char * xdprsym(struct xdstr *xd, int key, int type, char *sep) { char *sym = symbol_by_value(key, ef_ptr(type, 0)); if (!sym) { CANT_HAPPEN(!xd->sloppy); xd->pr("%s%d", sep, key); } else { xd->pr("%s", sep); xdpresc(xd, sym, INT_MAX); } return " "; }