////////////////////////////////////////////////////////////////////////// // NOTE: This function must be thread-safe. Before adding stuff contact MarcoC. void CVehicleMovementVTOL::ProcessAI(const float deltaTime) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); if(!m_isVTOLMovement) { CVehicleMovementHelicopter::ProcessAI(deltaTime); return; } m_velDamp = 0.15f; const float maxDirChange = 15.0f; // it's useless to progress further if the engine has yet to be turned on if(!m_isEnginePowered) return; m_movementAction.Clear(); m_movementAction.isAI = true; ResetActions(); // Our current state const Vec3 worldPos = m_PhysPos.pos; const Matrix33 worldMat(m_PhysPos.q); Ang3 worldAngles = Ang3::GetAnglesXYZ(worldMat); const Vec3 currentVel = m_PhysDyn.v; const Vec3 currentVel2D(currentVel.x, currentVel.y, 0.0f); // +ve direction mean rotation anti-clocwise about the z axis - 0 means along y float currentDir = worldAngles.z; // to avoid singularity const Vec3 vWorldDir = worldMat * FORWARD_DIRECTION; const Vec3 vWorldDir2D = Vec3(vWorldDir.x, vWorldDir.y, 0.0f).GetNormalizedSafe(); // Our inputs const float desiredSpeed = m_aiRequest.HasDesiredSpeed() ? m_aiRequest.GetDesiredSpeed() : 0.0f; const Vec3 desiredMoveDir = m_aiRequest.HasMoveTarget() ? (m_aiRequest.GetMoveTarget() - worldPos).GetNormalizedSafe() : vWorldDir; const Vec3 desiredMoveDir2D = Vec3(desiredMoveDir.x, desiredMoveDir.y, 0.0f).GetNormalizedSafe(vWorldDir2D); const Vec3 desiredVel = desiredMoveDir * desiredSpeed; const Vec3 desiredVel2D(desiredVel.x, desiredVel.y, 0.0f); const Vec3 desiredLookDir = m_aiRequest.HasLookTarget() ? (m_aiRequest.GetLookTarget() - worldPos).GetNormalizedSafe() : desiredMoveDir; const Vec3 desiredLookDir2D = Vec3(desiredLookDir.x, desiredLookDir.y, 0.0f).GetNormalizedSafe(vWorldDir2D); // Calculate the desired 2D velocity change Vec3 desiredVelChange2D = desiredVel2D - currentVel2D; float velChangeLength = desiredVelChange2D.GetLength2D(); bool isLandingMode = false; if(m_pLandingGears && m_pLandingGears->AreLandingGearsOpen()) isLandingMode = true; bool isHorizontal = (desiredSpeed >= 5.0f) && (desiredMoveDir.GetLength2D() > desiredMoveDir.z); float desiredPitch = 0.0f; float desiredRoll = 0.0f; float desiredDir = atan2f(-desiredLookDir2D.x, desiredLookDir2D.y); while(currentDir < desiredDir - gf_PI) currentDir += 2.0f * gf_PI; while(currentDir > desiredDir + gf_PI) currentDir -= 2.0f * gf_PI; float diffDir = (desiredDir - currentDir); m_actionYaw = diffDir * m_yawInputConst; m_actionYaw += m_yawInputDamping * (currentDir - m_lastDir) / deltaTime; m_lastDir = currentDir; if(isHorizontal && !isLandingMode) { float desiredFwdSpeed = desiredVelChange2D.GetLength(); desiredFwdSpeed *= min(1.0f, diffDir / DEG2RAD(maxDirChange)); if(!iszero(desiredFwdSpeed)) { const Vec3 desiredWorldTiltAxis = Vec3(-desiredVelChange2D.y, desiredVelChange2D.x, 0.0f); const Vec3 desiredLocalTiltAxis = worldMat.GetTransposed() * desiredWorldTiltAxis; m_forwardAction = m_fwdPID.Update(currentVel.y, desiredLocalTiltAxis.GetLength(), -1.0f, 1.0f); float desiredTiltAngle = m_tiltPerVelDifference * desiredVelChange2D.GetLength(); Limit(desiredTiltAngle, -m_maxTiltAngle, m_maxTiltAngle); if(desiredTiltAngle > 0.0001f) { const Vec3 desiredWorldTiltAxis2 = Vec3(-desiredVelChange2D.y, desiredVelChange2D.x, 0.0f).GetNormalizedSafe(); const Vec3 desiredLocalTiltAxis2 = worldMat.GetTransposed() * desiredWorldTiltAxis2; Vec3 vVelLocal = worldMat.GetTransposed() * desiredVel; vVelLocal.NormalizeSafe(); float dotup = vVelLocal.Dot(Vec3(0.0f,0.0f,1.0f)); float currentSpeed = currentVel.GetLength(); desiredPitch = dotup *currentSpeed / 100.0f; desiredRoll = desiredTiltAngle * desiredLocalTiltAxis2.y *currentSpeed/30.0f; } } } else { float desiredTiltAngle = m_tiltPerVelDifference * desiredVelChange2D.GetLength(); Limit(desiredTiltAngle, -m_maxTiltAngle, m_maxTiltAngle); if(desiredTiltAngle > 0.0001f) { const Vec3 desiredWorldTiltAxis = Vec3(-desiredVelChange2D.y, desiredVelChange2D.x, 0.0f).GetNormalizedSafe(); const Vec3 desiredLocalTiltAxis = worldMat.GetTransposed() * desiredWorldTiltAxis; desiredPitch = desiredTiltAngle * desiredLocalTiltAxis.x; desiredRoll = desiredTiltAngle * desiredLocalTiltAxis.y; } } float currentHeight = m_PhysPos.pos.z; if(m_aiRequest.HasMoveTarget()) { m_hoveringPower = m_powerPID.Update(currentVel.z, desiredVel.z, -1.0f, 4.0f); //m_hoveringPower = (m_desiredHeight - currentHeight) * m_powerInputConst; //m_hoveringPower += m_powerInputDamping * (currentHeight - m_lastHeight) / deltaTime; if(isHorizontal) { if(desiredMoveDir.z > 0.6f || desiredMoveDir.z < -0.85f) { desiredPitch = max(-0.5f, min(0.5f, desiredMoveDir.z)) * DEG2RAD(35.0f); m_forwardAction += abs(desiredMoveDir.z); } m_liftAction = min(2.0f, max(m_liftAction, m_hoveringPower * 2.0f)); } else { m_liftAction = 0.0f; } } else { // to keep hovering at the same place m_hoveringPower = m_powerPID.Update(currentVel.z, m_desiredHeight - currentHeight, -1.0f, 1.0f); m_liftAction = 0.0f; if(m_pVehicle->GetAltitude() > 10.0f) //TODO: this line is not MTSafe m_liftAction = m_forwardAction; } m_actionPitch += m_pitchActionPerTilt * (desiredPitch - worldAngles.x); m_actionRoll += m_pitchActionPerTilt * (desiredRoll - worldAngles.y); Limit(m_actionPitch, -1.0f, 1.0f); Limit(m_actionRoll, -1.0f, 1.0f); Limit(m_actionYaw, -1.0f, 1.0f); if(m_horizontal > 0.0001f) m_desiredHeight = m_PhysPos.pos.z; Limit(m_forwardAction, -1.0f, 1.0f); }
//------------------------------------------------------------------------ void CVehicleMovementVTOL::Update(const float deltaTime) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); CVehicleMovementHelicopter::Update(deltaTime); CryAutoCriticalSection lk(m_lock); if(m_pWingsAnimation) { m_pWingsAnimation->SetTime(m_wingsAnimTime); } IActorSystem *pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem(); assert(pActorSystem); IActor *pActor = pActorSystem->GetActor(m_actorId); if(pActor && pActor->IsClient()) { float turbulence = m_turbulence; if(m_pAltitudeLimitVar) { float altitudeLimit = m_pAltitudeLimitVar->GetFVal(); float currentHeight = m_pEntity->GetWorldPos().z; if(!iszero(altitudeLimit)) { float altitudeLowerOffset; if(m_pAltitudeLimitLowerOffsetVar) { float r = 1.0f - min(1.0f, max(0.0f, m_pAltitudeLimitLowerOffsetVar->GetFVal())); altitudeLowerOffset = r * altitudeLimit; if(currentHeight >= altitudeLowerOffset) { if(currentHeight > altitudeLowerOffset) { float zone = altitudeLimit - altitudeLowerOffset; turbulence += (currentHeight - altitudeLowerOffset) / (zone); } } } } } if(turbulence > 0.0f) { static_cast<CActor *>(pActor)->CameraShake(0.50f * turbulence, 0.0f, 0.05f, 0.04f, Vec3(0.0f, 0.0f, 0.0f), 10, "VTOL_Update_Turbulence"); } float enginePowerRatio = m_enginePower / m_enginePowerMax; if(enginePowerRatio > 0.0f) { float rpmScaleDesired = 0.2f; rpmScaleDesired += abs(m_forwardAction) * 0.8f; rpmScaleDesired += abs(m_strafeAction) * 0.4f; rpmScaleDesired += abs(m_turnAction) * 0.25f; rpmScaleDesired = min(1.0f, rpmScaleDesired); Interpolate(m_rpmScale, rpmScaleDesired, 1.0f, deltaTime); } float turnParamGoal = min(1.0f, abs(m_turnAction)) * 0.6f; turnParamGoal *= (min(1.0f, max(0.0f, m_speedRatio)) + 1.0f) * 0.50f; turnParamGoal += turnParamGoal * m_boost * 0.25f; Interpolate(m_soundParamTurn, turnParamGoal, 0.5f, deltaTime); SetSoundParam(eSID_Run, "turn", m_soundParamTurn); float damage = GetSoundDamage(); if(damage > 0.1f) { //if (ISound* pSound = GetOrPlaySound(eSID_Damage, 5.f, m_enginePos)) //SetSoundParam(pSound, "damage", damage); } } }
//------------------------------------------------------------------------ void CVehicleMovementVTOL::ProcessActions(const float deltaTime) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); UpdateDamages(deltaTime); UpdateEngine(deltaTime); m_velDamp = 0.25f; m_playerControls.ProcessActions(deltaTime); Limit(m_forwardAction, -1.0f, 1.0f); Limit(m_strafeAction, -1.0f, 1.0f); m_actionYaw = 0.0f; Vec3 worldPos = m_pEntity->GetWorldPos(); IPhysicalEntity *pPhysics = GetPhysics(); // get the current state // roll pitch + yaw Matrix34 worldTM = m_pRotorPart ? m_pRotorPart->GetWorldTM() : m_pEntity->GetWorldTM(); // if (m_pRotorPart) // worldTM = m_pRotorPart->GetWorldTM(); // else // worldTM = m_pEntity->GetWorldTM(); Vec3 specialPos = worldTM.GetTranslation(); Ang3 angles = Ang3::GetAnglesXYZ(Matrix33(worldTM)); Matrix33 tm; tm.SetRotationXYZ((angles)); // +ve pitch means nose up const float ¤tPitch = angles.x; // +ve roll means to the left const float ¤tRoll = angles.y; // +ve direction mean rotation anti-clockwise about the z axis - 0 means along y float currentDir = angles.z; const float maxPitchAngle = 60.0f; float pitchDeg = RAD2DEG(currentPitch); if(pitchDeg >= (maxPitchAngle * 0.75f)) { float mult = pitchDeg / (maxPitchAngle); if(mult > 1.0f && m_desiredPitch < 0.0f) { m_desiredPitch *= 0.0f; m_actionPitch *= 0.0f; m_desiredPitch += 0.2f * mult; } else if(m_desiredPitch < 0.0f) { m_desiredPitch *= (1.0f - mult); m_desiredPitch += 0.05f; } } else if(pitchDeg <= (-maxPitchAngle * 0.75f)) { float mult = abs(pitchDeg) / (maxPitchAngle); if(mult > 1.0f && m_desiredPitch > 0.0f) { m_desiredPitch *= 0.0f; m_actionPitch *= 0.0f; m_desiredPitch += 0.2f * mult; } else if(m_desiredPitch > 0.0f) { m_desiredPitch *= (1.0f - mult); m_desiredPitch -= 0.05f; } } if(currentRoll >= DEG2RAD(m_maxRollAngle * 0.7f) && m_desiredRoll > 0.001f) { float r = currentRoll / DEG2RAD(m_maxRollAngle); r = min(1.0f, r * 1.0f); r = 1.0f - r; m_desiredRoll *= r; m_desiredRoll = min(1.0f, m_desiredRoll); } else if(currentRoll <= DEG2RAD(-m_maxRollAngle * 0.7f) && m_desiredRoll < 0.001f) { float r = abs(currentRoll) / DEG2RAD(m_maxRollAngle); r = min(1.0f, r * 1.0f); r = 1.0f - r; m_desiredRoll *= r; m_desiredRoll = max(-1.0f, m_desiredRoll); } Vec3 currentFwdDir2D = m_currentFwdDir; currentFwdDir2D.z = 0.0f; currentFwdDir2D.NormalizeSafe(); Vec3 currentLeftDir2D(-currentFwdDir2D.y, currentFwdDir2D.x, 0.0f); Vec3 currentVel = m_PhysDyn.v; Vec3 currentVel2D = currentVel; currentVel2D.z = 0.0f; float currentHeight = worldPos.z; float currentFwdSpeed = currentVel.Dot(currentFwdDir2D); ProcessActions_AdjustActions(deltaTime); float inputMult = m_basicSpeedFraction; // desired things float turnDecreaseScale = m_yawDecreaseWithSpeed / (m_yawDecreaseWithSpeed + fabs(currentFwdSpeed)); Vec3 desired_vel2D = currentFwdDir2D * m_forwardAction * m_maxFwdSpeed * inputMult + currentLeftDir2D * m_strafeAction * m_maxLeftSpeed * inputMult; // calculate the angle changes Vec3 desiredVelChange2D = desired_vel2D - currentVel2D; float desiredTiltAngle = m_tiltPerVelDifference * desiredVelChange2D.GetLength(); Limit(desiredTiltAngle, -m_maxTiltAngle, m_maxTiltAngle); float goal = abs(m_desiredPitch) + abs(m_desiredRoll); goal *= 1.5f; Interpolate(m_playerAcceleration, goal, 0.25f, deltaTime); Limit(m_playerAcceleration, 0.0f, 5.0f); //static float g_angleLift = 4.0f; if(abs(m_liftAction) > 0.001f && abs(m_forwardAction) < 0.001) { // float pitch = RAD2DEG(currentPitch); if(m_liftPitchAngle < 0.0f && m_liftAction > 0.0f) m_liftPitchAngle = 0.0f; else if(m_liftPitchAngle > 0.0f && m_liftAction < 0.0f) m_liftPitchAngle = 0.0f; Interpolate(m_liftPitchAngle, 1.25f * m_liftAction, 0.75f, deltaTime); if(m_liftPitchAngle < 1.0f && m_liftPitchAngle > -1.0f) m_desiredPitch += 0.05f * m_liftAction; } else if(m_liftAction < 0.001f && abs(m_liftPitchAngle) > 0.001) { Interpolate(m_liftPitchAngle, 0.0f, 1.0f, deltaTime); m_desiredPitch += 0.05f * -m_liftPitchAngle; } /* todo else if (m_liftAction < -0.001f) { m_desiredPitch += min(0.0f, (DEG2RAD(-5.0f) - currentPitch)) * 0.5f * m_liftAction; }*/ if(!iszero(m_desiredPitch)) { m_actionPitch -= m_desiredPitch * m_pitchInputConst; Limit(m_actionPitch, -m_maxYawRate, m_maxYawRate); } float rollAccel = 1.0f; if(abs(currentRoll + m_desiredRoll) < abs(currentRoll)) rollAccel *= 1.25f; m_actionRoll += m_pitchActionPerTilt * m_desiredRoll * rollAccel * (m_playerAcceleration + 1.0f); Limit(m_actionRoll, -10.0f, 10.0f); Limit(m_actionPitch, -10.0f, 10.0f); // roll as we turn if(!m_strafeAction) { m_actionYaw += m_yawPerRoll * currentRoll; } if(abs(m_strafeAction) > 0.001f) { float side = 0.0f; side = min(1.0f, max(-1.0f, m_strafeAction)); float roll = DEG2RAD(m_extraRollForTurn * 0.25f * side) - (currentRoll); m_actionRoll += max(0.0f, abs(roll)) * side * 1.0f; } float relaxRollTolerance = 0.0f; if(abs(m_turnAction) > 0.01f || abs(m_PhysDyn.w.z) > DEG2RAD(3.0f)) { m_actionYaw += -m_turnAction * m_yawInputConst * GetDamageMult(); float side = 0.0f; if(abs(m_turnAction) > 0.01f) side = min(1.0f, max(-1.0f, m_turnAction)); float roll = DEG2RAD(m_extraRollForTurn * side) - (currentRoll); m_actionRoll += max(0.0f, abs(roll)) * side * m_rollForTurnForce; roll *= max(1.0f, abs(m_PhysDyn.w.z)); m_actionRoll += roll; Limit(m_actionYaw, -m_maxYawRate, m_maxYawRate); } m_desiredDir = currentDir; m_lastDir = currentDir; float boost = Boosting() ? m_boostMult : 1.0f; float liftActionMax = 1.0f; if(m_pAltitudeLimitVar) { float altitudeLimit = m_pAltitudeLimitVar->GetFVal(); if(!iszero(altitudeLimit)) { float altitudeLowerOffset; if(m_pAltitudeLimitLowerOffsetVar) { float r = 1.0f - min(1.0f, max(0.0f, m_pAltitudeLimitLowerOffsetVar->GetFVal())); altitudeLowerOffset = r * altitudeLimit; } else altitudeLowerOffset = altitudeLimit; float mult = 1.0f; if(currentHeight >= altitudeLimit) { if(m_liftAction > 0.f) { mult = 0.0f; } } else if(currentHeight >= altitudeLowerOffset) { float zone = altitudeLimit - altitudeLowerOffset; mult = (altitudeLimit - currentHeight) / (zone); } m_liftAction *= mult; if(currentPitch > DEG2RAD(0.0f)) { if(m_forwardAction > 0.0f) m_forwardAction *= mult; if(m_actionPitch > 0.0f) { m_actionPitch *= mult; m_actionPitch += -currentPitch; } } m_desiredHeight = min(altitudeLowerOffset, currentHeight); } } else { m_desiredHeight = currentHeight; } if(abs(m_liftAction) > 0.001f) { m_liftAction = min(liftActionMax, max(-0.2f, m_liftAction)); m_hoveringPower = (m_powerInputConst * m_liftAction) * boost; m_noHoveringTimer = 0.0f; } else if(!m_isTouchingGround) { if(m_noHoveringTimer <= 0.0f) { float gravity; pe_simulation_params paramsSim; if(pPhysics->GetParams(¶msSim)) gravity = abs(paramsSim.gravity.z); else gravity = 9.2f; float upDirZ = m_workingUpDir.z; if(abs(m_forwardAction) > 0.01 && upDirZ > 0.0f) upDirZ = 1.0f; else if(upDirZ > 0.8f) upDirZ = 1.0f; float upPower = upDirZ; upPower -= min(1.0f, abs(m_forwardAction) * abs(angles.x)); float turbulenceMult = 1.0f - min(m_turbulenceMultMax, m_turbulence); Vec3 &impulse = m_control.impulse; impulse += Vec3(0.0f, 0.0f, upPower) * gravity * turbulenceMult * GetDamageMult(); impulse.z -= m_PhysDyn.v.z * turbulenceMult; } else { m_noHoveringTimer -= deltaTime; } } if(m_pStabilizeVTOL) { float stabilizeTime = m_pStabilizeVTOL->GetFVal(); if(stabilizeTime > 0.0f) { if(m_relaxTimer < 6.0f) m_relaxTimer += deltaTime; else { float r = currentRoll - relaxRollTolerance; r = min(1.0f, max(-1.0f, r)); m_actionRoll += -r * m_relaxForce * (m_relaxTimer / 6.0f); } } } if(m_netActionSync.PublishActions(CNetworkMovementHelicopter(this))) m_pVehicle->GetGameObject()->ChangedNetworkState(eEA_GameClientDynamic); }
virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Initialize: break; case eFE_Activate: if (IsPortActive(pActInfo, EIP_Trigger)) { const Vec3& dir = GetPortVec3(pActInfo, EIP_LimitDir); const bool localSpace = GetPortBool(pActInfo, EIP_LocalSpace); const float rangeH = GetPortFloat(pActInfo, EIP_LimitYaw); const float rangeV = GetPortFloat(pActInfo, EIP_LimitPitch); CActor *pPlayerActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetClientActor()); if (pPlayerActor) { CPlayer::SStagingParams stagingParams; CPlayer* pPlayer = static_cast<CPlayer*> (pPlayerActor); if (dir.len2()>0.01f) { if (localSpace) { const Quat& viewQuat = pPlayer->GetViewQuatFinal(); // WC Vec3 dirWC = viewQuat * dir; stagingParams.vLimitDir = dirWC.GetNormalizedSafe(ZERO); } else stagingParams.vLimitDir = dir.GetNormalizedSafe(ZERO); } stagingParams.vLimitRangeH = DEG2RAD(rangeH); stagingParams.vLimitRangeV = DEG2RAD(rangeV); stagingParams.bLocked = GetPortBool(pActInfo, EIP_Lock); int stance = GetPortInt(pActInfo, EIP_Stance); if (stance < STANCE_NULL || stance >= STANCE_LAST) { stance = STANCE_NULL; GameWarning("[flow] PlayerStaging: stance=%d invalid", stance); } stagingParams.stance = (EStance) stance; bool bActive = (stagingParams.bLocked || (!stagingParams.vLimitDir.IsZero() && !iszero(stagingParams.vLimitRangeH) && !iszero(stagingParams.vLimitRangeV)) ); pPlayer->StagePlayer(bActive, &stagingParams); /* SActorParams* pActorParams = pPlayerActor->GetActorParams(); if (pActorParams) { CPlayer* pPlayer = static_cast<CPlayer*> (pPlayerActor); if (dir.len2()>0.01f) { if (localSpace) { const Quat& viewQuat = pPlayer->GetViewQuatFinal(); // WC Vec3 dirWC = viewQuat * dir; pActorParams->vLimitDir = dirWC.GetNormalizedSafe(ZERO); } else pActorParams->vLimitDir = dir.GetNormalizedSafe(ZERO); } else pActorParams->vLimitDir.zero(); pActorParams->vLimitRangeH = DEG2RAD(rangeH); pActorParams->vLimitRangeV = DEG2RAD(rangeV); const bool bLock = GetPortBool(pActInfo, EIP_Lock); // AlexL 23/01/2007: disable this until we have a working solution to lock player movement (action filter) // SPlayerStats* pActorStats = static_cast<SPlayerStats*> (pPlayer->GetActorStats()); // if (pActorStats) // pActorStats->spectatorMode = bLock ? CActor::eASM_Cutscene : 0; IActionMapManager* pAmMgr = g_pGame->GetIGameFramework()->GetIActionMapManager(); if (pAmMgr) pAmMgr->EnableFilter("no_move", bLock); if (bLock) { // CPlayerMovementController* pMC = static_cast<CPlayerMovementController*> (pPlayer->GetMovementController()); // pMC->Reset(); if(pPlayer->GetPlayerInput()) pPlayer->GetPlayerInput()->Reset(); } } */ } ActivateOutput(pActInfo, EOP_Done, false); } break; } }
static void test_egd_success(void *arg) { int pipefds[2] = {-1,-1}; struct sockaddr_un sun; char dir[128] = "/tmp/otterylite_test_XXXXXX"; char fname[128] = {0}; int listener = -1; pid_t pid; int r, exitstatus=0; u8 buf[64]; unsigned flags; (void)arg; tt_assert(mkdtemp(dir) != NULL); tt_int_op(-1, ==, ottery_egd_socklen); tt_int_op(-1, ==, OTTERY_PUBLIC_FN(set_egd_address)((struct sockaddr*)&sun, 16384)); tt_assert(strlen(dir) < 128 - 32); snprintf(fname, sizeof(fname), "%s/fifo", dir); tt_int_op(strlen(fname), <, sizeof(sun.sun_path)); tt_int_op(-2, ==, ottery_getentropy_egd(buf, &flags)); /* not turned on. */ memset(&sun, 0, sizeof(sun)); sun.sun_family = -1; /* Bad family */ tt_int_op(0, ==, OTTERY_PUBLIC_FN(set_egd_address)((struct sockaddr*)&sun, sizeof(sun))); tt_int_op(-1, ==, ottery_getentropy_egd(buf, &flags)); /* bad family */ sun.sun_family = AF_UNIX; memcpy(sun.sun_path, fname, strlen(fname)+1); listener = socket(AF_UNIX, SOCK_STREAM, 0); tt_int_op(listener, >=, 0); tt_int_op(0, ==, pipe(pipefds)); tt_int_op(0, ==, OTTERY_PUBLIC_FN(set_egd_address)((struct sockaddr*)&sun, sizeof(sun))); tt_int_op(sizeof(sun), ==, ottery_egd_socklen); tt_int_op(-1, ==, ottery_getentropy_egd(buf, &flags)); /* nobody listening yet */ tt_int_op(bind(listener, (struct sockaddr*)&sun, sizeof(sun)), ==, 0); tt_int_op(listen(listener, 16), ==, 0); if ((pid = fork())) { /* parent */ close(listener); close(pipefds[1]); } else { /* child */ close(pipefds[0]); run_egd_server(listener, pipefds[1]); exit(1); } memset(buf, 0, sizeof(buf)); r = ottery_getentropy_egd(buf, &flags); tt_int_op(r, ==, ENTROPY_CHUNK); tt_assert(iszero(buf + ENTROPY_CHUNK, sizeof(buf) - ENTROPY_CHUNK)); tt_assert(! iszero(buf, ENTROPY_CHUNK)); tt_mem_op(buf, ==, notsorandom, ENTROPY_CHUNK); r = (int)read(pipefds[0], buf, 1); tt_int_op(r, ==, 1); waitpid(pid, &exitstatus, 0); tt_int_op(exitstatus, ==, 0); tt_int_op(buf[0], ==, 'Y'); tt_int_op(0, ==, OTTERY_PUBLIC_FN(set_egd_address)(NULL, 0)); tt_int_op(-1, ==, ottery_egd_socklen); end: if (pipefds[0] >= 0) close(pipefds[0]); if (pipefds[1] >= 1) close(pipefds[1]); if (*fname) unlink(fname); rmdir(dir); }
void top_level_eval(void) { save(); trigmode = 0; p1 = symbol(AUTOEXPAND); if (iszero(get_binding(p1))) expanding = 0; else expanding = 1; p1 = pop(); push(p1); eval(); p2 = pop(); // "draw", "for" and "setq" return "nil", there is no result to print if (p2 == symbol(NIL)) { push(p2); restore(); return; } // update "last" set_binding(symbol(LAST), p2); if (!iszero(get_binding(symbol(BAKE)))) { push(p2); bake(); p2 = pop(); } // If we evaluated the symbol "i" or "j" and the result was sqrt(-1) // then don't do anything. // Otherwise if "j" is an imaginary unit then subst. // Otherwise if "i" is an imaginary unit then subst. if ((p1 == symbol(SYMBOL_I) || p1 == symbol(SYMBOL_J)) && isimaginaryunit(p2)) ; else if (isimaginaryunit(get_binding(symbol(SYMBOL_J)))) { push(p2); push(imaginaryunit); push_symbol(SYMBOL_J); subst(); p2 = pop(); } else if (isimaginaryunit(get_binding(symbol(SYMBOL_I)))) { push(p2); push(imaginaryunit); push_symbol(SYMBOL_I); subst(); p2 = pop(); } #ifndef LINUX // if we evaluated the symbol "a" and got "b" then print "a=b" // do not print "a=a" if (issymbol(p1) && !iskeyword(p1) && p1 != p2 && test_flag == 0) { push_symbol(SETQ); push(p1); push(p2); list(3); p2 = pop(); } #endif push(p2); restore(); }
int main(int argc, char *argv[]) { p_mem_t shared_mem, results_mem; uint32_t eram_base; char results[1024] = { '\0' }; int device_cols, device_rows, nside; p_dev_t dev; p_prog_t prog; p_team_t team; p_coords_t size; p_coords_t start = { .row = 0, .col = 0 }; unsigned int msize; float seed; unsigned int addr; //, clocks; size_t sz; int verbose=0; double tdiff[3]; int result, retval = 0; msize = 0x00400000; get_args(argc, argv); fo = stderr; fi = stdin; printf( "------------------------------------------------------------\n"); printf( "Calculating: C[%d][%d] = A[%d][%d] * B[%d][%d]\n", _Smtx, _Smtx, _Smtx, _Smtx, _Smtx, _Smtx); seed = 0.0; if(verbose){ printf( "Seed = %f\n", seed); } dev = p_init(P_DEV_EPIPHANY, 0); if (p_error(dev)) { fprintf(stderr, "Error initializing PAL\n"); return p_error(dev); } device_cols = p_query(dev, P_PROP_COLS); device_rows = p_query(dev, P_PROP_ROWS); // Use min size nside = device_cols > device_rows ? device_cols : device_rows; if (nside < 4) { fprintf(stderr, "Error: Too small device, need at least 4x4\n"); return 1; } // Either 1024, 256, 64, or 16 cores (side must be power of two), nside = nside >= 32 ? 32 : nside >= 16 ? 16 : nside >= 8 ? 8 : 4; size.row = nside; size.col = nside; team = p_open4(dev, P_TOPOLOGY_2D, &start, &size); printf("Using team of size %d\n", p_team_size(team)); if (p_error(team)) { fprintf(stderr, "Error opening team\n"); return p_error(team); } prog = p_load(dev, ar.elfFile, 0); eram_base = (unsigned) p_query(dev, P_PROP_MEMBASE); shared_mem = p_map(dev, eram_base, msize); // Clear mailbox contents memset(&Mailbox, 0, sizeof(Mailbox)); p_write(&shared_mem, &Mailbox, 0, sizeof(Mailbox), 0); // Generate operand matrices based on a provided seed matrix_init((int)seed); #ifdef __WIPE_OUT_RESULT_MATRIX__ // Wipe-out any previous remains in result matrix (for verification) addr = offsetof(shared_buf_t, C[0]); sz = sizeof(Mailbox.C); if(verbose){ printf( "Writing C[%uB] to address %08x...\n", (unsigned) sz, addr); } p_write(&shared_mem, (void *) Mailbox.C, addr, sz, 0); #endif /* Wallclock time */ clock_gettime(CLOCK_MONOTONIC, &timer[0]); /* Clock CPUTIME too. We don't want to indicate failure just * because the system was under high load. */ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &timer[4]); // Copy operand matrices to Epiphany system addr = offsetof(shared_buf_t, A[0]); sz = sizeof(Mailbox.A); if(verbose){ printf( "Writing A[%uB] to address %08x...\n", (unsigned) sz, addr); } p_write(&shared_mem, (void *) Mailbox.A, addr, sz, 0); addr = offsetof(shared_buf_t, B[0]); sz = sizeof(Mailbox.B); if(verbose){ printf( "Writing B[%uB] to address %08x...\n", (unsigned) sz, addr); } p_write(&shared_mem, (void *) Mailbox.B, addr, sz, 0); // Call the Epiphany matmul() function if(verbose){ printf( "GO Epiphany! ... "); } if(verbose){ printf("Loading program on Epiphany chip...\n"); } p_arg_t args[] = { &nside, sizeof(nside), true }; if (p_run(prog, "matmul", team, 0, p_team_size(team), 1, args, 0)) { fprintf(stderr, "Error loading Epiphany program.\n"); exit(1); } // Read result matrix and timing addr = offsetof(shared_buf_t, C[0]); sz = sizeof(Mailbox.C); if(verbose){ printf( "Reading result from address %08x...\n", addr); } p_read(&shared_mem, (void *) Mailbox.C, addr, sz, 0); clock_gettime(CLOCK_MONOTONIC, &timer[1]); clock_gettime(CLOCK_THREAD_CPUTIME_ID, &timer[5]); // Calculate a reference result clock_gettime(CLOCK_THREAD_CPUTIME_ID, &timer[2]); #ifndef __DO_STRASSEN__ matmul(Mailbox.A, Mailbox.B, Cref, _Smtx); #else matmul_strassen(Mailbox.A, Mailbox.B, Cref, _Smtx); #endif clock_gettime(CLOCK_THREAD_CPUTIME_ID, &timer[3]); addr = offsetof(shared_buf_t, core.clocks); sz = sizeof(Mailbox.core.clocks); if(verbose){ printf( "Reading time from address %08x...\n", addr); } p_read(&shared_mem, &Mailbox.core.clocks, addr, sizeof(Mailbox.core.clocks), 0); // clocks = Mailbox.core.clocks; // Calculate the difference between the Epiphany result and the reference result matsub(Mailbox.C, Cref, Cdiff, _Smtx); tdiff[0] = (timer[1].tv_sec - timer[0].tv_sec) * 1000 + ((double) (timer[1].tv_nsec - timer[0].tv_nsec) / 1000000.0); // tdiff[0] = ((double) clocks) / eMHz * 1000; tdiff[1] = (timer[3].tv_sec - timer[2].tv_sec) * 1000 + ((double) (timer[3].tv_nsec - timer[2].tv_nsec) / 1000000.0); tdiff[2] = (timer[5].tv_sec - timer[4].tv_sec) * 1000 + ((double) (timer[5].tv_nsec - timer[4].tv_nsec) / 1000000.0); // If the difference is 0, then the matrices are identical and the // calculation was correct if (iszero(Cdiff, _Smtx)) { printf( "Epiphany(time) %9.1f msec (@ %03d MHz)\n", tdiff[0], eMHz); printf( "Host(time) %9.1f msec (@ %03d MHz)\n", tdiff[1], aMHz); printf( "------------------------------------------------------------\n"); printf( "TEST \"matmul-16\" PASSED\n"); retval = 0; } else { printf( "\n\nERROR: C_epiphany is different from C_host !!!\n"); printf( "TEST \"matmul-16\" FAILED\n"); retval = 1; } #if 0 #ifdef __DUMP_MATRICES__ printf( "\n\n\n"); printf( "A[][] = \n"); matprt(Mailbox.A, _Smtx); printf( "B[][] = \n"); matprt(Mailbox.B, _Smtx); printf( "C[][] = \n"); matprt(Mailbox.C, _Smtx); printf( "Cref[][] = \n"); matprt(Cref, _Smtx); int i, j; for (i=0; i<_Nside; i++) for (j=0; j<_Nside; j++) { e_read(pEpiphany, i, j, 0x2000+0*sizeof(float), &Aepi[(i*_Score+0)*_Smtx + j*_Score], 2*sizeof(float)); e_read(pEpiphany, i, j, 0x2000+2*sizeof(float), &Aepi[(i*_Score+1)*_Smtx + j*_Score], 2*sizeof(float)); e_read(pEpiphany, i, j, 0x4000+0*sizeof(float), &Bepi[(i*_Score+0)*_Smtx + j*_Score], 2*sizeof(float)); e_read(pEpiphany, i, j, 0x4000+2*sizeof(float), &Bepi[(i*_Score+1)*_Smtx + j*_Score], 2*sizeof(float)); } printf( "Aepi[][] = \n"); matprt(Aepi, _Smtx); printf( "Bepi[][] = \n"); matprt(Bepi, _Smtx); #endif #endif // p_unmap ... p_close(team); p_finalize(dev); return retval; } // Initialize operand matrices void matrix_init(int seed) { int i, j, p; p = 0; for (i=0; i<_Smtx; i++) for (j=0; j<_Smtx; j++) Mailbox.A[p++] = (i + j + seed) % _MAX_MEMBER_; p = 0; for (i=0; i<_Smtx; i++) for (j=0; j<_Smtx; j++) Mailbox.B[p++] = ((i + j) * 2 + seed) % _MAX_MEMBER_; p = 0; for (i=0; i<_Smtx; i++) for (j=0; j<_Smtx; j++) Mailbox.C[p++] = 0x8dead; return; }