/* returns 0 on success, error message on failure */ char* secureidcheck(char *user, char *response) { Packet *req = nil, *resp = nil; ulong u[4]; uchar x[16]; char *radiussecret; char ruser[ 64]; char dest[3*IPaddrlen+20]; Secret shared, pass; char *rv = "authentication failed"; Ndbs s; Ndbtuple *t, *nt, *tt; uchar *ip; static Ndb *netdb; if(netdb == nil) netdb = ndbopen(0); /* bad responses make them disable the fob, avoid silly checks */ if(strlen(response) < 4 || strpbrk(response,"abcdefABCDEF") != nil) goto out; /* get radius secret */ radiussecret = ndbgetvalue(db, &s, "radius", "lra-radius", "secret", &t); if(radiussecret == nil){ syslog(0, AUTHLOG, "secureidcheck: nil radius secret: %r"); goto out; } /* translate user name if we have to */ strcpy(ruser, user); for(nt = t; nt; nt = nt->entry){ if(strcmp(nt->attr, "uid") == 0 && strcmp(nt->val, user) == 0) for(tt = nt->line; tt != nt; tt = tt->line) if(strcmp(tt->attr, "rid") == 0){ strcpy(ruser, tt->val); break; } } ndbfree(t); u[0] = fastrand(); u[1] = fastrand(); u[2] = fastrand(); u[3] = fastrand(); req = newRequest((uchar*)u); if(req == nil) goto out; shared.s = (uchar*)radiussecret; shared.len = strlen(radiussecret); ip = getipv4addr(); if(ip == nil){ syslog(0, AUTHLOG, "no interfaces: %r\n"); goto out; } if(setAttribute(req, R_NASIPAddress, ip + IPv4off, 4) < 0) goto out; if(setAttribute(req, R_UserName, (uchar*)ruser, strlen(ruser)) < 0) goto out; pass.s = (uchar*)response; pass.len = strlen(response); hide(&shared, req->authenticator, &pass, x); if(setAttribute(req, R_UserPassword, x, 16) < 0) goto out; t = ndbsearch(netdb, &s, "sys", "lra-radius"); if(t == nil){ syslog(0, AUTHLOG, "secureidcheck: nil radius sys search: %r\n"); goto out; } for(nt = t; nt; nt = nt->entry){ if(strcmp(nt->attr, "ip") != 0) continue; snprint(dest,sizeof dest,"udp!%s!oradius", nt->val); resp = rpc(dest, &shared, req); if(resp == nil){ syslog(0, AUTHLOG, "%s nil response", dest); continue; } if(resp->ID != req->ID){ syslog(0, AUTHLOG, "%s mismatched ID req=%d resp=%d", dest, req->ID, resp->ID); freePacket(resp); resp = nil; continue; } switch(resp->code){ case R_AccessAccept: syslog(0, AUTHLOG, "%s accepted ruser=%s", dest, ruser); rv = nil; break; case R_AccessReject: syslog(0, AUTHLOG, "%s rejected ruser=%s %s", dest, ruser, replymsg(resp)); rv = "secureid failed"; break; case R_AccessChallenge: syslog(0, AUTHLOG, "%s challenge ruser=%s %s", dest, ruser, replymsg(resp)); rv = "secureid out of sync"; break; default: syslog(0, AUTHLOG, "%s code=%d ruser=%s %s", dest, resp->code, ruser, replymsg(resp)); break; } break; /* we have a proper reply, no need to ask again */ } ndbfree(t); free(radiussecret); out: freePacket(req); freePacket(resp); return rv; }
void HeavenGen::generateChunk(int x, int z, int map) { NBT_Value* main = new NBT_Value(NBT_Value::TAG_COMPOUND); NBT_Value* val = new NBT_Value(NBT_Value::TAG_COMPOUND); generateWithNoise(x, z, map); val->Insert("Blocks", new NBT_Value(heavenblocks)); val->Insert("Data", new NBT_Value(blockdata)); val->Insert("SkyLight", new NBT_Value(skylight)); val->Insert("BlockLight", new NBT_Value(blocklight)); val->Insert("HeightMap", new NBT_Value(heightmap)); val->Insert("Entities", new NBT_Value(NBT_Value::TAG_LIST, NBT_Value::TAG_COMPOUND)); val->Insert("TileEntities", new NBT_Value(NBT_Value::TAG_LIST, NBT_Value::TAG_COMPOUND)); val->Insert("LastUpdate", new NBT_Value((int64_t)time(NULL))); val->Insert("xPos", new NBT_Value(x)); val->Insert("zPos", new NBT_Value(z)); val->Insert("TerrainPopulated", new NBT_Value((char)1)); main->Insert("Level", val); /* uint32_t chunkid; ServerInstance->map()->posToId(x, z, &chunkid); ServerInstance->map()->maps[chunkid].x = x; ServerInstance->map()->maps[chunkid].z = z; */ std::vector<uint8_t> *t_blocks = (*val)["Blocks"]->GetByteArray(); std::vector<uint8_t> *t_data = (*val)["Data"]->GetByteArray(); std::vector<uint8_t> *t_blocklight = (*val)["BlockLight"]->GetByteArray(); std::vector<uint8_t> *t_skylight = (*val)["SkyLight"]->GetByteArray(); std::vector<int32_t> *heightmap = (*val)["HeightMap"]->GetIntArray(); sChunk* chunk = new sChunk(); chunk->blocks = &((*t_blocks)[0]); chunk->data = &((*t_data)[0]); chunk->blocklight = &((*t_blocklight)[0]); chunk->skylight = &((*t_skylight)[0]); chunk->heightmap = &((*heightmap)[0]); chunk->nbt = main; chunk->x = x; chunk->z = z; ServerInstance->map(map)->chunks.insert(ChunkMap::value_type(ChunkMap::key_type(x, z), chunk)); // Update last used time //ServerInstance->map()->mapLastused[chunkid] = (int)time(0); // Not changed //ServerInstance->map()->mapChanged[chunkid] = ServerInstance->config()->bData("save_unchanged_chunks"); //ServerInstance->map()->maps[chunkid].nbt = main; if (addOre) { AddOre(x, z, map, BLOCK_STATIONARY_WATER); } // Add trees if (addTrees) { AddTrees(x, z, map, fastrand() % 2 + 3); } if (expandBeaches) { ExpandBeaches(x, z, map); } }
void WorldRenderer::GenerateGrass(const Vector2UINT& sectorCoords) { // Grass Turned Off if ( !zGrassDensity ) { return; } // Delete previous grass if existing. auto grassIterator = this->zGrass.find(sectorCoords); // Create Sector Rect Rect sectorRect; sectorRect.topLeft.x = (float)sectorCoords.x * FSECTOR_WORLD_SIZE; sectorRect.topLeft.y = (float)sectorCoords.y * FSECTOR_WORLD_SIZE; sectorRect.size.x = FSECTOR_WORLD_SIZE; sectorRect.size.y = FSECTOR_WORLD_SIZE; // Check if inside clip range Circle clipCircle(zGraphics->GetCamera()->GetPosition().GetXZ(), zGrassFarDistance); // Check Intersection if ( !DoesIntersect(sectorRect, clipCircle) ) { if ( grassIterator != this->zGrass.end() ) { // Remove from graphics engine. this->zGraphics->DeleteBillboardCollection(grassIterator->second); // Remove from map. this->zGrass.erase(grassIterator); } return; } // Delete Old Grass if( grassIterator != this->zGrass.end() ) { // Remove from graphics engine. this->zGraphics->DeleteBillboardCollection(grassIterator->second); // Reset grassIterator->second = 0; } // First check if the sector has any grass texture Sector* sector = this->zWorld->GetSector(sectorCoords); bool found = false; for(unsigned int i = 0; i < SECTOR_BLEND_CHANNELS && !found; ++i) { if(strcmp(sector->GetTextureName(i), "01_v02-Moss.png") == 0) { found = true; } else if(strcmp(sector->GetTextureName(i), "06_v01-MossDark.png") == 0) { found = true; } else if(strcmp(sector->GetTextureName(i), "07_v01-MossLight.png") == 0) { found = true; } } // No Grass Textures Found if(!found) { return; } float width = FSECTOR_WORLD_SIZE; float depth = FSECTOR_WORLD_SIZE; unsigned int sqrtGrassDensity = (unsigned int)sqrt((long)this->zGrassDensity); float xDiff = width / sqrtGrassDensity; float zDiff = depth / sqrtGrassDensity; Vector2 grassPos = Vector2(0.0f); Vector2 terrainPosXZ = sectorRect.topLeft; float blendValueGrassLight = 0.0f; float blendValueGrassMedium = 0.0f; float blendValueGrassDark = 0.0f; float blendThreshHold = 0.32f; const static float RGB_MIN_MAX = 50.0f / 255.0f; Vector3* positions = new Vector3[this->zGrassDensity]; Vector2* sizes = new Vector2[this->zGrassDensity]; Vector3* colors = new Vector3[this->zGrassDensity]; fast_rand_seed = sectorCoords.x + sectorCoords.y; float rndMaxInv = 1.0f / (float)RAND_MAX; float grassWidth = 0.0f; float grassHeight = 0.0f; float terrainY = 0.0f; Vector2 offsetVector = Vector2(xDiff, zDiff) * 0.5f; unsigned int index = 0; float totBlendValue = 0.0f; //Values taken from average texture color. Vector3 colorGrassLight = Vector3(91.0f, 131.0f, 65.0f) / 255.0f; Vector3 colorGrassMedium = Vector3(107.0f, 142.0f, 77.0f) / 255.0f; Vector3 colorGrassDark = Vector3(68.0f, 104.0f, 45.0f) / 255.0f; Vector3 rndGrassColorOffsetVecGrassLight = Vector3(0.0f, 0.0f, 0.0f); Vector3 rndGrassColorOffsetVecGrassMedium = Vector3(0.0f, 0.0f, 0.0f); Vector3 rndGrassColorOffsetVecGrassDark = Vector3(0.0f, 0.0f, 0.0f); float minMaxDistX = xDiff * 0.5f - zGrassNeightbourDistance * 0.5f; float minMaxDistZ = zDiff * 0.5f - zGrassNeightbourDistance * 0.5f; for(unsigned int x = 0; x < sqrtGrassDensity; ++x) { for(unsigned int z = 0; z < sqrtGrassDensity; ++z) { // Initial position grassPos = terrainPosXZ + Vector2((float)x * xDiff, (float)z * zDiff) + offsetVector; // Move initial position randomly grassPos.x += fastrand() * rndMaxInv * 2.0f * minMaxDistX - minMaxDistX; grassPos.y += fastrand() * rndMaxInv * 2.0f * minMaxDistZ - minMaxDistZ; // Randomize Size grassWidth = fastrand() * rndMaxInv * (zGrassWidthMax-zGrassWidthMin) + zGrassWidthMin; grassHeight = fastrand() * rndMaxInv * (zGrassHeightMax-zGrassHeightMin) + zGrassHeightMin; // Randomize dark grass RGB = rgb[-RGB_MIN_MAX, 0] rndGrassColorOffsetVecGrassDark.y = fastrand() * rndMaxInv * RGB_MIN_MAX - RGB_MIN_MAX; // Randomize medium grass RGB = rgb[-RGB_MIN_MAX / 2, RGB_MIN_MAX / 2] rndGrassColorOffsetVecGrassMedium.y = (fastrand() * rndMaxInv * 2.0f * RGB_MIN_MAX - RGB_MIN_MAX)*0.5f; // Randomize light grass RGB = rgb[0, RGB_MIN_MAX] rndGrassColorOffsetVecGrassLight.y = fastrand() * rndMaxInv * RGB_MIN_MAX; try { terrainY = zWorld->CalcHeightAtWorldPos(grassPos); } catch (...) { continue; } //blendValueGrassLight + blendValueGrassMedium + blendValueGrassDark -> range[0,1] blendValueGrassLight = this->zWorld->GetAmountOfTexture(grassPos, "07_v01-MossLight.png"); blendValueGrassMedium = this->zWorld->GetAmountOfTexture(grassPos, "01_v02-Moss.png"); blendValueGrassDark = this->zWorld->GetAmountOfTexture(grassPos, "06_v01-MossDark.png"); totBlendValue = blendValueGrassLight + blendValueGrassMedium + blendValueGrassDark; if(totBlendValue > blendThreshHold) { //totBlendValue range[blendThreshHold, 1], we want [0,1] float tmp = totBlendValue - blendThreshHold; //range[0, 1 - blendThreshHold]; tmp /= 1.0f - blendThreshHold; totBlendValue = tmp; //Set size grassHeight *= totBlendValue; //modify grass height depending on blend values //If it is below minGrassHeight, don't add it. (It can never be greater than maxHeight) if(grassHeight >= zGrassHeightMin) { sizes[index] = Vector2(grassWidth, grassHeight); //Set position positions[index] = Vector3(grassPos.x, terrainY + grassHeight * 0.5f, grassPos.y); //Set color Vector3 test = (colorGrassLight + rndGrassColorOffsetVecGrassLight) * blendValueGrassLight + (colorGrassMedium + rndGrassColorOffsetVecGrassMedium) * blendValueGrassMedium + (colorGrassDark + rndGrassColorOffsetVecGrassDark) * blendValueGrassDark + Vector3(1.0f, 1.0f, 1.0f) //Color is a multiplier. - Vector3(0.8f, 0.8f, 0.8f); //Adjust ambient & diffuse TTILLMAN colors[index] = test; //Increase index(number of grass objects) index++; } } } } //Add grass //No offset vector needed since grass positions is in world space. if(index > 0) { this->zGrass[sectorCoords] = this->zGraphics->CreateBillboardCollection(index, positions, sizes, colors, Vector3(0.0f, 0.0f, 0.0f), "Media/Grass.png"); this->zGrass[sectorCoords]->SetRenderShadowFlag(false); //Don't render shadows. this->zGrass[sectorCoords]->SetCullFarDistance(zGrassFarDistance); this->zGrass[sectorCoords]->SetCullNearDistance(zGrassNearDistance); } //Delete data delete [] positions; delete [] sizes; delete [] colors; }
AuthInfo* p9any(int fd) { char buf[1024], buf2[1024], cchal[CHALLEN], *bbuf, *p, *dom, *u; char *pass; char tbuf[TICKETLEN+TICKETLEN+AUTHENTLEN], trbuf[TICKREQLEN]; char authkey[DESKEYLEN]; Authenticator auth; int afd, i, v2; Ticketreq tr; Ticket t; AuthInfo *ai; if((afd = open("/mnt/factotum/ctl", ORDWR)) >= 0) return p9anyfactotum(fd, afd); if(readstr(fd, buf, sizeof buf) < 0) fatal(1, "cannot read p9any negotiation"); bbuf = buf; v2 = 0; if(strncmp(buf, "v.2 ", 4) == 0){ v2 = 1; bbuf += 4; } if((p = strchr(bbuf, ' '))) *p = 0; p = bbuf; if((dom = strchr(p, '@')) == nil) fatal(1, "bad p9any domain"); *dom++ = 0; if(strcmp(p, "p9sk1") != 0) fatal(1, "server did not offer p9sk1"); sprint(buf2, "%s %s", p, dom); if(write(fd, buf2, strlen(buf2)+1) != strlen(buf2)+1) fatal(1, "cannot write user/domain choice in p9any"); if(v2){ if(readstr(fd, buf, sizeof buf) != 3) fatal(1, "cannot read OK in p9any"); if(memcmp(buf, "OK\0", 3) != 0) fatal(1, "did not get OK in p9any"); } for(i=0; i<CHALLEN; i++) cchal[i] = fastrand(); if(write(fd, cchal, 8) != 8) fatal(1, "cannot write p9sk1 challenge"); if(readn(fd, trbuf, TICKREQLEN) != TICKREQLEN) fatal(1, "cannot read ticket request in p9sk1"); convM2TR(trbuf, &tr); u = user; pass = findkey(&u, tr.authdom); if(pass == nil) again: pass = getkey(u, tr.authdom); if(pass == nil) fatal(1, "no password"); passtokey(authkey, pass); memset(pass, 0, strlen(pass)); tr.type = AuthTreq; strecpy(tr.hostid, tr.hostid+sizeof tr.hostid, u); strecpy(tr.uid, tr.uid+sizeof tr.uid, u); convTR2M(&tr, trbuf); if(gettickets(&tr, authkey, trbuf, tbuf) < 0) fatal(1, "cannot get auth tickets in p9sk1"); convM2T(tbuf, &t, authkey); if(t.num != AuthTc){ print("?password mismatch with auth server\n"); goto again; } memmove(tbuf, tbuf+TICKETLEN, TICKETLEN); auth.num = AuthAc; memmove(auth.chal, tr.chal, CHALLEN); auth.id = 0; convA2M(&auth, tbuf+TICKETLEN, t.key); if(write(fd, tbuf, TICKETLEN+AUTHENTLEN) != TICKETLEN+AUTHENTLEN) fatal(1, "cannot send ticket and authenticator back in p9sk1"); if(readn(fd, tbuf, AUTHENTLEN) != AUTHENTLEN) fatal(1, "cannot read authenticator in p9sk1"); convM2A(tbuf, &auth, t.key); if(auth.num != AuthAs || memcmp(auth.chal, cchal, CHALLEN) != 0 || auth.id != 0){ print("?you and auth server agree about password.\n"); print("?server is confused.\n"); fatal(1, "server lies got %llux.%d want %llux.%d", *(vlong*)auth.chal, auth.id, *(vlong*)cchal, 0); } //print("i am %s there.\n", t.suid); ai = mallocz(sizeof(AuthInfo), 1); ai->secret = mallocz(8, 1); des56to64((uchar*)t.key, ai->secret); ai->nsecret = 8; ai->suid = strdup(t.suid); ai->cuid = strdup(t.cuid); memset(authkey, 0, sizeof authkey); return ai; }
unsigned rnd (unsigned max) { return (fastrand () % max); }
void MapGen::AddOre(int x, int z, int map, uint8_t type) { sChunk* chunk = Mineserver::get()->map(map)->getChunk(x, z); int blockX, blockY, blockZ; uint8_t block; // Parameters for deposits int count, startHeight, minDepoSize, maxDepoSize; switch (type) { case BLOCK_COAL_ORE: count = fastrand() % 10 + 20; // 20-30 coal deposits startHeight = 90; minDepoSize = 3; maxDepoSize = 7; break; case BLOCK_IRON_ORE: count = fastrand() % 8 + 10; // 10-18 iron deposits startHeight = 60; minDepoSize = 2; maxDepoSize = 5; break; case BLOCK_GOLD_ORE: count = fastrand() % 4 + 5; // 4-9 gold deposits startHeight = 32; minDepoSize = 2; maxDepoSize = 4; break; case BLOCK_DIAMOND_ORE: count = fastrand() % 1 + 2; // 1-3 diamond deposits startHeight = 17; minDepoSize = 1; maxDepoSize = 2; break; case BLOCK_REDSTONE_ORE: count = fastrand() % 5 + 5; // 5-10 redstone deposits startHeight = 25; minDepoSize = 2; maxDepoSize = 4; break; case BLOCK_LAPIS_ORE: count = fastrand() % 1 + 2; // 1-3 lapis lazuli deposits startHeight = 17; minDepoSize = 1; maxDepoSize = 2; break; case BLOCK_GRAVEL: count = fastrand() % 10 + 20; // 20-30 gravel deposits startHeight = 90; minDepoSize = 4; maxDepoSize = 10; break; default: return; } int i = 0; while (i < count) { blockX = fastrand() % 8 + 4; blockZ = fastrand() % 8 + 4; blockY = heightmap[(blockZ << 4) + blockX]; blockY -= 5; // Check that startheight is not higher than height at that column if (blockY > startHeight) { blockY = startHeight; } //blockX += xBlockpos; //blockZ += zBlockpos; // Calculate Y blockY = fastrand() % blockY; i++; block = chunk->blocks[blockY + ((blockZ << 7) + (blockX << 11))]; // No ore in caves if (block == BLOCK_AIR) { continue; } AddDeposit(blockX, blockY, blockZ, map, type, minDepoSize, maxDepoSize, chunk); } }
bool Render::renderNext(unsigned int pixels) { assert(pixels); assert(inProgress); assert(!curx || curx < imageWidth); assert(!cury || cury < imageHeight); if (!pixels || !inProgress || curx >= imageWidth || cury >= imageHeight) return false; const Vector3 origin = renderCameraEye; const float sqRenderSampleNum = float(renderSampleNum * renderSampleNum); const float rz = float(imageWidth) / 2.0f / tanf(camera.fov / 2.0f); const float imageWidthHalf = imageWidth / 2.0f; const float imageHeightHalf = imageHeight / 2.0f; while (pixels > 0) { const float rx = float(curx) - imageWidthHalf; const float ry = float(cury) - imageHeightHalf; Vector3 ray(rx, ry, rz); if (renderSampleNum < 0) { unsigned int absRenderSampleNum = abs(renderSampleNum); if (!(curx % absRenderSampleNum || cury % absRenderSampleNum)) { ray = renderCameraView * ray; const Color tracedColor = scene.trace(origin, ray, renderReflectNum); const int endQx = min(imageWidth, curx + absRenderSampleNum); const int endQy = min(imageHeight, cury + absRenderSampleNum); for (int qx = curx; qx < endQx; qx++) for (int qy = cury; qy < endQy; qy++) image[qx + qy * imageWidth] = tracedColor; } } else if (renderSampleNum > 0) { Color finColor; const float rndx = renderAdditive ? float(fastrand()) / FAST_RAND_MAX : 0; const float rndy = renderAdditive ? float(fastrand()) / FAST_RAND_MAX : 0; finColor = Color(0.0f, 0.0f, 0.0f); for (int ssx = 0; ssx < renderSampleNum; ssx++) for (int ssy = 0; ssy < renderSampleNum; ssy++) { Vector3 ray = Vector3(rx + float(ssx) / renderSampleNum + rndx, ry + float(ssy) / renderSampleNum + rndy, rz); ray = renderCameraView * ray; finColor += scene.trace(origin, ray, renderReflectNum); } finColor /= sqRenderSampleNum; if (additiveCounter > 1) image[curx + cury * imageWidth] += finColor; else image[curx + cury * imageWidth] = finColor; } pixels--; curx++; if (curx == imageWidth) { curx = 0; cury++; } if (cury == imageHeight) { inProgress = false; break; } } return inProgress; }
void sendmail(char *content, char *subject, char *msg) { int fd; Biobuf *bin, *bout; if((fd = dial(conf.smtp, 0, 0, 0)) < 0) { vtlogprint(errlog, "dial %s: %r\n", conf.smtp); return; } bin = vtmalloc(sizeof *bin); bout = vtmalloc(sizeof *bout); Binit(bin, fd, OREAD); Binit(bout, fd, OWRITE); if(smtpread(bin, 220) < 0){ error: close(fd); Bterm(bin); Bterm(bout); return; } Bprint(bout, "HELO venti-mgr\n"); Bflush(bout); if(smtpread(bin, 250) < 0) goto error; Bprint(bout, "MAIL FROM:<%s>\n", conf.mailfrom); Bflush(bout); if(smtpread(bin, 250) < 0) goto error; Bprint(bout, "RCPT TO:<%s>\n", conf.mailfrom); Bflush(bout); if(smtpread(bin, 250) < 0) goto error; Bprint(bout, "DATA\n"); Bflush(bout); if(smtpread(bin, 354) < 0) goto error; Bprint(bout, "From: \"venti mgr\" <%s>\n", conf.mailfrom); Bprint(bout, "To: <%s>\n", conf.mailto); Bprint(bout, "Subject: %s\n", subject); Bprint(bout, "MIME-Version: 1.0\n"); Bprint(bout, "Content-Type: %s; charset=\"UTF-8\"\n", content); Bprint(bout, "Content-Transfer-Encoding: quoted-printable\n"); Bprint(bout, "Message-ID: %08lux%[email protected]\n", fastrand(), fastrand()); Bprint(bout, "\n"); qp(bout, msg); Bprint(bout, ".\n"); Bflush(bout); if(smtpread(bin, 250) < 0) goto error; Bprint(bout, "QUIT\n"); Bflush(bout); Bterm(bin); Bterm(bout); close(fd); }
/* generate a random number between 0 and max ( 0 <=r<=max) */ unsigned int fastrand_max(unsigned int max) { return fastrand()%(max+1); }
void *reader( void *ptr) { struct timespec start, end; int tid = *((int *) ptr); uint64_t seed = 0xdeadbeef + tid; int sum = 0; /** < The node and lock to use in an iteration */ int node_id, lock_id; /** < The snapshotted lock version and node data */ int lock_version; node_t node_snapshot; /** < Total number of times we start the snapshotting procedure */ int num_tries = 0; /** < Total number of iterations (for measurement) */ int num_iters = 0; clock_gettime(CLOCK_REALTIME, &start); while(1) { if(num_iters == ITERS_PER_MEASUREMENT) { clock_gettime(CLOCK_REALTIME, &end); double seconds = (end.tv_sec - start.tv_sec) + (double) (end.tv_nsec - start.tv_nsec) / GHZ_CPS; printf("Reader %d: rate = %.2f M/s. Sum = %d. Avg. tries = %f\n", tid, num_iters / (1000000 * seconds), sum, (double) num_tries / num_iters); num_iters = 0; num_tries = 0; clock_gettime(CLOCK_REALTIME, &start); } node_id = fastrand(&seed) & NUM_NODES_; lock_id = node_id & NUM_LOCKS_; try_again: num_tries ++; /** < Enter the critical section when the version is even */ lock_version = locks[lock_id].lock; if((lock_version & 1) != 0) { goto try_again; } /** < version load #1 --> snapshot loads */ asm volatile("" ::: "memory"); node_snapshot.a = nodes[node_id].a; node_snapshot.b = nodes[node_id].b; /** < snapshot loads --> version load #2 */ asm volatile("" ::: "memory"); if(locks[lock_id].lock == lock_version) { // Snapshot was correct assert(node_snapshot.b == node_snapshot.a + 1); sum += node_snapshot.a + node_snapshot.b; } else { goto try_again; } num_iters ++; } }
/// calculate a random integer modulo K int fastrandK (int K) { return fastrand () % K; }