<commit_before>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Steve Reinhardt
 *          Kevin Lim
 */

#ifndef __ARCH_ALPHA_INTERRUPT_HH__
#define __ARCH_ALPHA_INTERRUPT_HH__

#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
#include "cpu/thread_context.hh"

namespace AlphaISA
{
    class Interrupts
    {
      protected:
        uint64_t interrupts[NumInterruptLevels];
        uint64_t intstatus;

      public:
        Interrupts()
        {
            memset(interrupts, 0, sizeof(interrupts));
            intstatus = 0;
            newInfoSet = false;
        }

        void post(int int_num, int index)
        {
            DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);

            if (int_num < 0 || int_num >= NumInterruptLevels)
                panic("int_num out of bounds\n");

            if (index < 0 || index >= sizeof(uint64_t) * 8)
                panic("int_num out of bounds\n");

            interrupts[int_num] |= 1 << index;
            intstatus |= (ULL(1) << int_num);
        }

        void clear(int int_num, int index)
        {
            DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);

            if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
                panic("int_num out of bounds\n");

            if (index < 0 || index >= sizeof(uint64_t) * 8)
                panic("int_num out of bounds\n");

            interrupts[int_num] &= ~(1 << index);
            if (interrupts[int_num] == 0)
                intstatus &= ~(ULL(1) << int_num);
        }

        void clear_all()
        {
            DPRINTF(Interrupt, "Interrupts all cleared\n");

            memset(interrupts, 0, sizeof(interrupts));
            intstatus = 0;
        }

        void serialize(std::ostream &os)
        {
            SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
            SERIALIZE_SCALAR(intstatus);
        }

        void unserialize(Checkpoint *cp, const std::string &section)
        {
            UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
            UNSERIALIZE_SCALAR(intstatus);
        }

        bool check_interrupts(ThreadContext * tc) const
        {
            return (intstatus != 0) && !(tc->readPC() & 0x3);
        }

        Fault getInterrupt(ThreadContext * tc)
        {
            int ipl = 0;
            int summary = 0;

            if (tc->readMiscReg(IPR_ASTRR))
                panic("asynchronous traps not implemented\n");

            if (tc->readMiscReg(IPR_SIRR)) {
                for (int i = INTLEVEL_SOFTWARE_MIN;
                     i < INTLEVEL_SOFTWARE_MAX; i++) {
                    if (tc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
                        // See table 4-19 of 21164 hardware reference
                        ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
                        summary |= (ULL(1) << i);
                    }
                }
            }

            uint64_t interrupts = intstatus;
            if (interrupts) {
                for (int i = INTLEVEL_EXTERNAL_MIN;
                    i < INTLEVEL_EXTERNAL_MAX; i++) {
                    if (interrupts & (ULL(1) << i)) {
                        // See table 4-19 of 21164 hardware reference
                        ipl = i;
                        summary |= (ULL(1) << i);
                    }
                }
            }

            if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) {
//                assert(!newInfoSet);
                newIpl = ipl;
                newSummary = newSummary;
                newInfoSet = true;
                DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
                        tc->readMiscReg(IPR_IPLR), ipl, summary);

                return new InterruptFault;
            } else {
                return NoFault;
            }
        }

        void updateIntrInfo(ThreadContext *tc)
        {
            assert(newInfoSet);
            tc->setMiscReg(IPR_ISR, newSummary);
            tc->setMiscReg(IPR_INTID, newIpl);
            newInfoSet = false;
        }

      private:
        bool newInfoSet;
        int newIpl;
        int newSummary;
    };
}

#endif

<commit_msg>Fix typo.<commit_after>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Steve Reinhardt
 *          Kevin Lim
 */

#ifndef __ARCH_ALPHA_INTERRUPT_HH__
#define __ARCH_ALPHA_INTERRUPT_HH__

#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
#include "cpu/thread_context.hh"

namespace AlphaISA
{
    class Interrupts
    {
      protected:
        uint64_t interrupts[NumInterruptLevels];
        uint64_t intstatus;

      public:
        Interrupts()
        {
            memset(interrupts, 0, sizeof(interrupts));
            intstatus = 0;
            newInfoSet = false;
        }

        void post(int int_num, int index)
        {
            DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);

            if (int_num < 0 || int_num >= NumInterruptLevels)
                panic("int_num out of bounds\n");

            if (index < 0 || index >= sizeof(uint64_t) * 8)
                panic("int_num out of bounds\n");

            interrupts[int_num] |= 1 << index;
            intstatus |= (ULL(1) << int_num);
        }

        void clear(int int_num, int index)
        {
            DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);

            if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
                panic("int_num out of bounds\n");

            if (index < 0 || index >= sizeof(uint64_t) * 8)
                panic("int_num out of bounds\n");

            interrupts[int_num] &= ~(1 << index);
            if (interrupts[int_num] == 0)
                intstatus &= ~(ULL(1) << int_num);
        }

        void clear_all()
        {
            DPRINTF(Interrupt, "Interrupts all cleared\n");

            memset(interrupts, 0, sizeof(interrupts));
            intstatus = 0;
        }

        void serialize(std::ostream &os)
        {
            SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
            SERIALIZE_SCALAR(intstatus);
        }

        void unserialize(Checkpoint *cp, const std::string &section)
        {
            UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
            UNSERIALIZE_SCALAR(intstatus);
        }

        bool check_interrupts(ThreadContext * tc) const
        {
            return (intstatus != 0) && !(tc->readPC() & 0x3);
        }

        Fault getInterrupt(ThreadContext * tc)
        {
            int ipl = 0;
            int summary = 0;

            if (tc->readMiscReg(IPR_ASTRR))
                panic("asynchronous traps not implemented\n");

            if (tc->readMiscReg(IPR_SIRR)) {
                for (int i = INTLEVEL_SOFTWARE_MIN;
                     i < INTLEVEL_SOFTWARE_MAX; i++) {
                    if (tc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
                        // See table 4-19 of 21164 hardware reference
                        ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
                        summary |= (ULL(1) << i);
                    }
                }
            }

            uint64_t interrupts = intstatus;
            if (interrupts) {
                for (int i = INTLEVEL_EXTERNAL_MIN;
                    i < INTLEVEL_EXTERNAL_MAX; i++) {
                    if (interrupts & (ULL(1) << i)) {
                        // See table 4-19 of 21164 hardware reference
                        ipl = i;
                        summary |= (ULL(1) << i);
                    }
                }
            }

            if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) {
                newIpl = ipl;
                newSummary = summary;
                newInfoSet = true;
                DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
                        tc->readMiscReg(IPR_IPLR), ipl, summary);

                return new InterruptFault;
            } else {
                return NoFault;
            }
        }

        void updateIntrInfo(ThreadContext *tc)
        {
            assert(newInfoSet);
            tc->setMiscReg(IPR_ISR, newSummary);
            tc->setMiscReg(IPR_INTID, newIpl);
            newInfoSet = false;
        }

      private:
        bool newInfoSet;
        int newIpl;
        int newSummary;
    };
}

#endif

<|endoftext|>


<commit_before>// Copyright (c) 2012-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>
#include <wallet/wallet.h>
#include <wallet/coinselection.h>

#include <set>

static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<COutput>& vCoins)
{
    int nInput = 0;

    static int nextLockTime = 0;
    CMutableTransaction tx;
    tx.nLockTime = nextLockTime++; // so all transactions get different hashes
    tx.vout.resize(nInput + 1);
    tx.vout[nInput].nValue = nValue;
    CWalletTx* wtx = new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)));

    int nAge = 6 * 24;
    COutput output(wtx, nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */);
    vCoins.push_back(output);
}

// Simple benchmark for wallet coin selection. Note that it maybe be necessary
// to build up more complicated scenarios in order to get meaningful
// measurements of performance. From laanwj, "Wallet coin selection is probably
// the hardest, as you need a wider selection of scenarios, just testing the
// same one over and over isn't too useful. Generating random isn't useful
// either for measurements."
// (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
static void CoinSelection(benchmark::State& state)
{
    const CWallet wallet("dummy", WalletDatabase::CreateDummy());
    std::vector<COutput> vCoins;
    LOCK(wallet.cs_wallet);

    while (state.KeepRunning()) {
        // Add coins.
        for (int i = 0; i < 1000; i++)
            addCoin(1000 * COIN, wallet, vCoins);
        addCoin(3 * COIN, wallet, vCoins);

        std::set<CInputCoin> setCoinsRet;
        CAmount nValueRet;
        bool bnb_used;
        CoinEligibilityFilter filter_standard(1, 6, 0);
        CoinSelectionParams coin_selection_params(false, 34, 148, CFeeRate(0), 0);
        bool success = wallet.SelectCoinsMinConf(1003 * COIN, filter_standard, vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)
                       || wallet.SelectCoinsMinConf(1003 * COIN, filter_standard, vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used);
        assert(success);
        assert(nValueRet == 1003 * COIN);
        assert(setCoinsRet.size() == 2);

        // Empty wallet.
        for (COutput& output : vCoins) {
            delete output.tx;
        }
        vCoins.clear();
    }
}

typedef std::set<CInputCoin> CoinSet;

// Copied from src/wallet/test/coinselector_tests.cpp
static void add_coin(const CAmount& nValue, int nInput, std::vector<CInputCoin>& set)
{
    CMutableTransaction tx;
    tx.vout.resize(nInput + 1);
    tx.vout[nInput].nValue = nValue;
    set.emplace_back(MakeTransactionRef(tx), nInput);
}
// Copied from src/wallet/test/coinselector_tests.cpp
static CAmount make_hard_case(int utxos, std::vector<CInputCoin>& utxo_pool)
{
    utxo_pool.clear();
    CAmount target = 0;
    for (int i = 0; i < utxos; ++i) {
        target += (CAmount)1 << (utxos+i);
        add_coin((CAmount)1 << (utxos+i), 2*i, utxo_pool);
        add_coin(((CAmount)1 << (utxos+i)) + ((CAmount)1 << (utxos-1-i)), 2*i + 1, utxo_pool);
    }
    return target;
}

static void BnBExhaustion(benchmark::State& state)
{
    // Setup
    std::vector<CInputCoin> utxo_pool;
    CoinSet selection;
    CAmount value_ret = 0;
    CAmount not_input_fees = 0;

    while (state.KeepRunning()) {
        // Benchmark
        CAmount target = make_hard_case(17, utxo_pool);
        SelectCoinsBnB(utxo_pool, target, 0, selection, value_ret, not_input_fees); // Should exhaust

        // Cleanup
        utxo_pool.clear();
        selection.clear();
    }
}

BENCHMARK(CoinSelection, 650);
BENCHMARK(BnBExhaustion, 650);
<commit_msg>bench: Simplify CoinSelection<commit_after>// Copyright (c) 2012-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>
#include <wallet/wallet.h>
#include <wallet/coinselection.h>

#include <set>

static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<COutput>& vCoins)
{
    int nInput = 0;

    static int nextLockTime = 0;
    CMutableTransaction tx;
    tx.nLockTime = nextLockTime++; // so all transactions get different hashes
    tx.vout.resize(nInput + 1);
    tx.vout[nInput].nValue = nValue;
    CWalletTx* wtx = new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)));

    int nAge = 6 * 24;
    COutput output(wtx, nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */);
    vCoins.push_back(output);
}

// Simple benchmark for wallet coin selection. Note that it maybe be necessary
// to build up more complicated scenarios in order to get meaningful
// measurements of performance. From laanwj, "Wallet coin selection is probably
// the hardest, as you need a wider selection of scenarios, just testing the
// same one over and over isn't too useful. Generating random isn't useful
// either for measurements."
// (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
static void CoinSelection(benchmark::State& state)
{
    const CWallet wallet("dummy", WalletDatabase::CreateDummy());
    LOCK(wallet.cs_wallet);

    // Add coins.
    std::vector<COutput> vCoins;
    for (int i = 0; i < 1000; ++i) {
        addCoin(1000 * COIN, wallet, vCoins);
    }
    addCoin(3 * COIN, wallet, vCoins);

    const CoinEligibilityFilter filter_standard(1, 6, 0);
    const CoinSelectionParams coin_selection_params(true, 34, 148, CFeeRate(0), 0);
    while (state.KeepRunning()) {
        std::set<CInputCoin> setCoinsRet;
        CAmount nValueRet;
        bool bnb_used;
        bool success = wallet.SelectCoinsMinConf(1003 * COIN, filter_standard, vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used);
        assert(success);
        assert(nValueRet == 1003 * COIN);
        assert(setCoinsRet.size() == 2);
    }
}

typedef std::set<CInputCoin> CoinSet;

// Copied from src/wallet/test/coinselector_tests.cpp
static void add_coin(const CAmount& nValue, int nInput, std::vector<CInputCoin>& set)
{
    CMutableTransaction tx;
    tx.vout.resize(nInput + 1);
    tx.vout[nInput].nValue = nValue;
    set.emplace_back(MakeTransactionRef(tx), nInput);
}
// Copied from src/wallet/test/coinselector_tests.cpp
static CAmount make_hard_case(int utxos, std::vector<CInputCoin>& utxo_pool)
{
    utxo_pool.clear();
    CAmount target = 0;
    for (int i = 0; i < utxos; ++i) {
        target += (CAmount)1 << (utxos+i);
        add_coin((CAmount)1 << (utxos+i), 2*i, utxo_pool);
        add_coin(((CAmount)1 << (utxos+i)) + ((CAmount)1 << (utxos-1-i)), 2*i + 1, utxo_pool);
    }
    return target;
}

static void BnBExhaustion(benchmark::State& state)
{
    // Setup
    std::vector<CInputCoin> utxo_pool;
    CoinSet selection;
    CAmount value_ret = 0;
    CAmount not_input_fees = 0;

    while (state.KeepRunning()) {
        // Benchmark
        CAmount target = make_hard_case(17, utxo_pool);
        SelectCoinsBnB(utxo_pool, target, 0, selection, value_ret, not_input_fees); // Should exhaust

        // Cleanup
        utxo_pool.clear();
        selection.clear();
    }
}

BENCHMARK(CoinSelection, 650);
BENCHMARK(BnBExhaustion, 650);
<|endoftext|>


<commit_before>/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#include <eikenv.h>
#include <e32cmn.h>
#include "base/SymbianLog.h"
#include "base/util/symbianUtils.h"
#include "base/util/stringUtils.h"
#include "base/util/timeUtils.h"
#include "base/globalsdef.h"

USE_NAMESPACE

// Formats for date&time printed into log.
_LIT(KFormatDateAndTime, "%*D%*N%Y%1-%2-%3 %:0%J%:1%T%:2%S");
_LIT(KFormatOnlyTime,    "%:0%J%:1%T%:2%S");

// The name of the semaphore
_LIT(KLogSemaphoreName,  "FLogSemaphore");

SymbianLog::SymbianLog(bool resetLog, const char* path, const char* name)
{
    TInt err = KErrNone;
    iLogName.Assign(charToNewBuf(SYMBIAN_LOG_NAME));

    // Create a semaphore, to avoid accessing the FileSystem at
    // the same time by different threads.
    // The semaphore is global, so that it could be used also by
    // other processes that (in future) will use this Log.
    err = iSemaphore.CreateGlobal(KLogSemaphoreName, 1);
    if (err != KErrNone) {
        setError(ERR_SEMAPHORE_CREATION, ERR_SEMAPHORE_CREATION_MSG);
    }
    iSemaphore.Wait();

    // Connect to the file server session.
    fsSession.Connect();

    if (resetLog) {
        err = file.Replace(fsSession, iLogName, EFileWrite|EFileShareAny);
    }
    else {
        err = file.Open(fsSession, iLogName, EFileWrite|EFileShareAny);
        if (err == KErrNotFound) {
            err = file.Create(fsSession, iLogName, EFileWrite|EFileShareAny);
        }
        else {
            // Log file existing, and not resetted. Will append data.
            TInt pos;
            file.Seek(ESeekEnd, pos);
        }
    }
    if (err != KErrNone) {
        return;
    }

    // Write the Header
    StringBuffer header = createHeader();
    RBuf8 data;
    data.Assign(stringBufferToNewBuf8(header));
    file.Write(data);

    file.Close();
    fsSession.Close();

    iSemaphore.Signal();
    return;
}

SymbianLog::~SymbianLog() {
}

void SymbianLog::setLogPath(const char* configLogPath) {
// TODO: implement
}

void SymbianLog::setLogName(const char* configLogName) {
// TODO: implement
}

StringBuffer SymbianLog::createHeader(const char* title)
{
    const char *t = (title)? title : SYMBIAN_LOG_HEADER;

    StringBuffer header = createCurrentTime(true);      // e.g. "2008/04/02 10:58:03 GMT +2:00"
    header += " - ";
    header += t;
    header += "\n";

    return header;
}

StringBuffer SymbianLog::createCurrentTime(bool complete)
{
    if (iFormattedBias.length() == 0) {
        // Create the string e.g. "GMT +2:00" only once (it's always the same)
        createFormattedBias();
    }

    TTime local;
    local.HomeTime();

    TBuf<50> formattedTime;
    if (complete) { local.FormatL(formattedTime, KFormatDateAndTime); }
    else          { local.FormatL(formattedTime, KFormatOnlyTime);    }

    StringBuffer ret;
    const char* date = bufToNewChar(formattedTime);
    ret.sprintf("%s %s", date, iFormattedBias.c_str());
    delete [] date;
    return ret;
}

void SymbianLog::createFormattedBias()
{
    TTime local, utc;
    TTimeIntervalMinutes bias;

    local.HomeTime();
    utc.UniversalTime();
    local.MinutesFrom(utc, bias);

    TInt totalMinutes = bias.Int();
    TInt hours   = totalMinutes / 60;
    TInt minutes = totalMinutes % 60;

    if (totalMinutes >= 0) { iFormattedBias.sprintf("GMT +%d:%02d", hours, minutes); }
    else                   { iFormattedBias.sprintf("GMT %d:%02d",  hours, minutes); }
}

void SymbianLog::error(const char*  msg, ...)
{
    PLATFORM_VA_LIST argList;
    PLATFORM_VA_START (argList, msg);
    printMessage(LOG_ERROR, msg, argList);
    PLATFORM_VA_END(argList);
}
void SymbianLog::info (const char*  msg, ...)
{
    if (isLoggable(LOG_LEVEL_INFO)) {
        PLATFORM_VA_LIST argList;
        PLATFORM_VA_START (argList, msg);
        printMessage(LOG_INFO, msg, argList);
        PLATFORM_VA_END(argList);
    }
}
void SymbianLog::debug(const char*  msg, ...)
{
    if (isLoggable(LOG_LEVEL_DEBUG)) {
        PLATFORM_VA_LIST argList;
        PLATFORM_VA_START (argList, msg);
        printMessage(LOG_DEBUG, msg, argList);
        PLATFORM_VA_END(argList);
    }
}
void SymbianLog::developer(const char*  msg, ...)
{
    if (isLoggable(LOG_LEVEL_INFO)) {
        PLATFORM_VA_LIST argList;
        PLATFORM_VA_START (argList, msg);
        printMessage(LOG_DEBUG, msg, argList);
        PLATFORM_VA_END(argList);
    }
}

void SymbianLog::printMessage(const char* level, const char* msg, PLATFORM_VA_LIST argList)
{
    iSemaphore.Wait();

    StringBuffer currentTime = createCurrentTime(false);

    fsSession.Connect();
    TInt err = file.Open(fsSession, iLogName, EFileWrite|EFileShareAny);
    if (err != KErrNone) {
        return;
    }

    TInt pos = 0;
    err = file.Seek(ESeekEnd, pos);
    if (err != KErrNone) {
        return;
    }

    // Write the data
    StringBuffer line, data;
    line.sprintf("%s -%s- %s", currentTime.c_str(), level, msg);
    data.vsprintf(line.c_str(), argList);
    data.append("\n");

    RBuf8 buf;
    buf.Assign(stringBufferToNewBuf8(data));
    file.Write(buf);

    file.Close();
    fsSession.Close();
    iSemaphore.Signal();
}

void SymbianLog::reset(const char* title)
{
    iSemaphore.Wait();

    fsSession.Connect();
    TInt err = file.Replace(fsSession, iLogName, EFileWrite|EFileShareAny);
    if (err != KErrNone) {
        return;
    }

    // Write the Header
    StringBuffer header = createHeader(title);
    RBuf8 buf;
    buf.Assign(stringBufferToNewBuf8(header));
    file.Write(buf);

    file.Close();
    fsSession.Close();
    iSemaphore.Signal();
}

size_t SymbianLog::getLogSize()
{
    iSemaphore.Wait();
    fsSession.Connect();

    TInt size = 0;
    TInt err = file.Size(size);
    if (err != KErrNone) {
        return (size_t)-1;
    }

    file.Close();
    fsSession.Close();
    iSemaphore.Signal();

    return (size_t)size;
}

Log *Log::logger;

Log &Log::instance() {
    if (!logger) {
        logger = new SymbianLog();
    }
    return *logger;
}
<commit_msg>- Share the FileServer session (RFs).   So it's not necessary to connect/close RFs every time. - Changed the createCurrentTime(), GMT+xx is appended only when time format is complete (date & time)<commit_after>/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#include <eikenv.h>
#include <e32cmn.h>
#include "base/SymbianLog.h"
#include "base/util/symbianUtils.h"
#include "base/util/stringUtils.h"
#include "base/util/timeUtils.h"
#include "base/globalsdef.h"

USE_NAMESPACE

// Formats for date&time printed into log.
_LIT(KFormatDateAndTime, "%*D%*N%Y%1-%2-%3 %:0%J%:1%T%:2%S");
_LIT(KFormatOnlyTime,    "%:0%J%:1%T%:2%S");

// The name of the semaphore
_LIT(KLogSemaphoreName,  "FLogSemaphore");

SymbianLog::SymbianLog(bool resetLog, const char* path, const char* name)
{
    TInt err = KErrNone;
    iLogName.Assign(charToNewBuf(SYMBIAN_LOG_NAME));

    // Create a semaphore, to avoid accessing the FileSystem at
    // the same time by different threads.
    // The semaphore is global, so that it could be used also by
    // other processes that (in future) will use this Log.
    err = iSemaphore.CreateGlobal(KLogSemaphoreName, 1);
    if (err != KErrNone) {
        setError(ERR_SEMAPHORE_CREATION, ERR_SEMAPHORE_CREATION_MSG);
    }
    iSemaphore.Wait();

    // Connect to the file server session.
    fsSession.Connect();
    err = fsSession.ShareAuto();
    if (err != KErrNone) {
        setErrorF(err, "SymbianLog error: unable to share RFs session (code %d)", err);
        return;
    }

    if (resetLog) {
        err = file.Replace(fsSession, iLogName, EFileWrite|EFileShareAny);
    }
    else {
        err = file.Open(fsSession, iLogName, EFileWrite|EFileShareAny);
        if (err == KErrNotFound) {
            err = file.Create(fsSession, iLogName, EFileWrite|EFileShareAny);
        }
        else {
            // Log file existing, and not resetted. Will append data.
            TInt pos;
            file.Seek(ESeekEnd, pos);
        }
    }
    if (err != KErrNone) {
        setErrorF(err, "SymbianLog: could not open the log file '%ls'", iLogName.Ptr());
        return;
    }

    // Write the Header
    StringBuffer header = createHeader();
    RBuf8 data;
    data.Assign(stringBufferToNewBuf8(header));
    file.Write(data);

    file.Close();
    iSemaphore.Signal();
    return;
}

SymbianLog::~SymbianLog() {
}

void SymbianLog::setLogPath(const char* configLogPath) {
// TODO: implement
}

void SymbianLog::setLogName(const char* configLogName) {
// TODO: implement
}

StringBuffer SymbianLog::createHeader(const char* title)
{
    const char *t = (title)? title : SYMBIAN_LOG_HEADER;

    StringBuffer header = createCurrentTime(true);      // e.g. "2008/04/02 10:58:03 GMT +2:00"
    header += " - ";
    header += t;
    header += "\n";

    return header;
}

StringBuffer SymbianLog::createCurrentTime(bool complete)
{
    if (iFormattedBias.length() == 0) {
        // Create the string e.g. "GMT +2:00" only once (it's always the same)
        createFormattedBias();
    }

    TTime local;
    StringBuffer ret;
    TBuf<50> formattedTime;

    local.HomeTime();

    if (complete) {
        local.FormatL(formattedTime, KFormatDateAndTime);
        StringBuffer date = bufToStringBuffer(formattedTime);
        ret.sprintf("%s %s", date.c_str(), iFormattedBias.c_str());
    }
    else {
        local.FormatL(formattedTime, KFormatOnlyTime);
        ret = bufToStringBuffer(formattedTime);
    }
    return ret;
}

void SymbianLog::createFormattedBias()
{
    TTime local, utc;
    TTimeIntervalMinutes bias;

    local.HomeTime();
    utc.UniversalTime();
    local.MinutesFrom(utc, bias);

    TInt totalMinutes = bias.Int();
    TInt hours   = totalMinutes / 60;
    TInt minutes = totalMinutes % 60;

    if (totalMinutes >= 0) { iFormattedBias.sprintf("GMT +%d:%02d", hours, minutes); }
    else                   { iFormattedBias.sprintf("GMT %d:%02d",  hours, minutes); }
}

void SymbianLog::error(const char*  msg, ...)
{
    PLATFORM_VA_LIST argList;
    PLATFORM_VA_START (argList, msg);
    printMessage(LOG_ERROR, msg, argList);
    PLATFORM_VA_END(argList);
}
void SymbianLog::info (const char*  msg, ...)
{
    if (isLoggable(LOG_LEVEL_INFO)) {
        PLATFORM_VA_LIST argList;
        PLATFORM_VA_START (argList, msg);
        printMessage(LOG_INFO, msg, argList);
        PLATFORM_VA_END(argList);
    }
}
void SymbianLog::debug(const char*  msg, ...)
{
    if (isLoggable(LOG_LEVEL_DEBUG)) {
        PLATFORM_VA_LIST argList;
        PLATFORM_VA_START (argList, msg);
        printMessage(LOG_DEBUG, msg, argList);
        PLATFORM_VA_END(argList);
    }
}
void SymbianLog::developer(const char*  msg, ...)
{
    if (isLoggable(LOG_LEVEL_INFO)) {
        PLATFORM_VA_LIST argList;
        PLATFORM_VA_START (argList, msg);
        printMessage(LOG_DEBUG, msg, argList);
        PLATFORM_VA_END(argList);
    }
}

void SymbianLog::printMessage(const char* level, const char* msg, PLATFORM_VA_LIST argList)
{
    iSemaphore.Wait();

    StringBuffer currentTime = createCurrentTime(false);

    TInt err = file.Open(fsSession, iLogName, EFileWrite|EFileShareAny);
    if (err != KErrNone) {
        setErrorF(err, "SymbianLog: could not open log file (code %d)", err);
        return;
    }

    TInt pos = 0;
    err = file.Seek(ESeekEnd, pos);
    if (err != KErrNone) {
        setErrorF(err, "SymbianLog: seek error on log file (code %d)", err);
        return;
    }

    // Write the data
    StringBuffer line, data;
    line.sprintf("%s -%s- %s", currentTime.c_str(), level, msg);
    data.vsprintf(line.c_str(), argList);
    data.append("\n");

    RBuf8 buf;
    buf.Assign(stringBufferToNewBuf8(data));
    file.Write(buf);

    file.Close();
    iSemaphore.Signal();
}

void SymbianLog::reset(const char* title)
{
    iSemaphore.Wait();

    TInt err = file.Replace(fsSession, iLogName, EFileWrite|EFileShareAny);
    if (err != KErrNone) {
        setErrorF(err, "SymbianLog: error resetting the log file (code %d)", err);
        return;
    }

    // Write the Header
    StringBuffer header = createHeader(title);
    RBuf8 buf;
    buf.Assign(stringBufferToNewBuf8(header));
    file.Write(buf);

    file.Close();
    iSemaphore.Signal();
}

size_t SymbianLog::getLogSize()
{
    iSemaphore.Wait();

    TInt size = 0;
    TInt err = file.Size(size);
    if (err != KErrNone) {
        setErrorF(err, "SymbianLog: error getting the log size (code %d)", err);
        return (size_t)-1;
    }

    file.Close();
    iSemaphore.Signal();

    return (size_t)size;
}

Log *Log::logger;

Log &Log::instance() {
    if (!logger) {
        logger = new SymbianLog();
    }
    return *logger;
}
<|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "classad/common.h"
#include "classad/util.h"
#include <limits.h>

using namespace std;

#if HAVE_LONG_TIMEZONE
extern DLL_IMPORT_MAGIC long timezone;
#endif

BEGIN_NAMESPACE( classad )

#ifdef WIN32
#define BIGGEST_RANDOM_INT RAND_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand(seed);
        initialized = 1;
	}

	return rand();
}
#else
#define BIGGEST_RANDOM_INT INT_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand48(seed);
        initialized = 1;
	}
	return (int) (lrand48() & INT_MAX);
}
#endif

double get_random_real(void)
{
    return (get_random_integer() / (double) BIGGEST_RANDOM_INT);
}

long timezone_offset(void)
{
#if HAVE_LONG_TIMEZONE
    return ::timezone;
#else
    static long tz_offset = 0;
    static bool have_tz_offset = false;

    if (!have_tz_offset) {
        struct tm  *tms;
        time_t     clock;

        time(&clock);
        tms = localtime(&clock);
        tz_offset = -tms->tm_gmtoff;
        if (0 != tms->tm_isdst) {
            tz_offset += 3600;
        }
    }
    return tz_offset;
#endif
}

void convert_escapes(string &text, bool &validStr)
{
	char *copy;
	int  length;
	int  source, dest;

	// We now it will be no longer than the original.
	length = text.length();
	copy = new char[length + 1];

	// We scan up to one less than the length, because we ignore
	// a terminating slash: it can't be an escape.
	dest = 0;
	for (source = 0; source < length - 1; source++) {
		if (text[source] != '\\' || source == length - 1) {
			copy[dest++]= text[source];
		}
		else {
			source++;

			char new_char;
			switch(text[source]) {
			case 'a':	new_char = '\a'; break;
			case 'b':	new_char = '\b'; break;
			case 'f':	new_char = '\f'; break;
			case 'n':	new_char = '\n'; break;
			case 'r':	new_char = '\r'; break;
			case 't':	new_char = '\t'; break;
			case 'v':	new_char = '\v'; break;
			case '\\':	new_char = '\\'; break;
			case '\?':	new_char = '\?'; break;
			case '\'':	new_char = '\''; break;
			case '\"':	new_char = '\"'; break;
			default:
				if (isodigit(text[source])) {
					unsigned int  number;
					// There are three allowed ways to have octal escape characters:
					//  \[0..3]nn or \nn or \n. We check for them in that order.
					if (   source <= length - 3
						&& text[source] >= '0' && text[source] <= '3'
						&& isodigit(text[source+1])
						&& isodigit(text[source+2])) {

						// We have the \[0..3]nn case
						char octal[4];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = text[source+2];
						octal[3] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 2; // to account for the two extra digits
					} else if (   source <= length -2
							   && isodigit(text[source+1])) {

						// We have the \nn case
						char octal[3];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 1; // to account for the extra digit
					} else if (source <= length - 1) {
						char octal[2];
						octal[0] = text[source];
						octal[1] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
					} else {
						new_char = text[source];
					}
					if(number == 0) { // "\\0" is an invalid substring within a string literal
					  validStr = false;
					  delete [] copy;
					  return;
					}
				} else {
					new_char = text[source];
				}
				break;
			}
			copy[dest++] = new_char;
		}
	}
	copy[dest] = 0;
	text = copy;
	delete [] copy;
	return;
}

void
getLocalTime(time_t *now, struct tm *localtm)
{

#ifndef WIN32
	localtime_r( now, localtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *lt_ptr;

	lt_ptr = localtime(now);

	if (localtm == NULL) { return; }

	localtm->tm_sec   = lt_ptr->tm_sec;    /* seconds */
	localtm->tm_min   = lt_ptr->tm_min;    /* minutes */
	localtm->tm_hour  = lt_ptr->tm_hour;   /* hours */
	localtm->tm_mday  = lt_ptr->tm_mday;   /* day of the month */
	localtm->tm_mon   = lt_ptr->tm_mon;    /* month */
	localtm->tm_year  = lt_ptr->tm_year;   /* year */
	localtm->tm_wday  = lt_ptr->tm_wday;   /* day of the week */
	localtm->tm_yday  = lt_ptr->tm_yday;   /* day in the year */
	localtm->tm_isdst = lt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void
getGMTime(time_t *now, struct tm *gtm)
{

#ifndef WIN32
	gmtime_r( now, gtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *gt_ptr;

	gt_ptr = gmtime(now);

	if (gtm == NULL) { return; }

	gtm->tm_sec   = gt_ptr->tm_sec;    /* seconds */
	gtm->tm_min   = gt_ptr->tm_min;    /* minutes */
	gtm->tm_hour  = gt_ptr->tm_hour;   /* hours */
	gtm->tm_mday  = gt_ptr->tm_mday;   /* day of the month */
	gtm->tm_mon   = gt_ptr->tm_mon;    /* month */
	gtm->tm_year  = gt_ptr->tm_year;   /* year */
	gtm->tm_wday  = gt_ptr->tm_wday;   /* day of the week */
	gtm->tm_yday  = gt_ptr->tm_yday;   /* day in the year */
	gtm->tm_isdst = gt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void absTimeToString(const abstime_t &atime, string &buffer)
{
    int       tzsecs;
    time_t    epoch_time;
    char      timebuf[32], sign;
    struct tm tms;

    tzsecs = atime.offset;
    epoch_time = atime.secs;
    if (tzsecs > 0) {
        sign = '+';         // timezone offset's sign
    } else {
        sign = '-';
        tzsecs = -tzsecs;
    }
    getGMTime(&epoch_time, &tms);
    strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", &tms);
    buffer += timebuf;
    sprintf(timebuf, "%c%02d%02d", sign, tzsecs / 3600, (tzsecs / 60) % 60);
    buffer += timebuf;
    return;
}

void relTimeToString(double rsecs, string &buffer)
{
    double  fractional_seconds;
    int     days, hrs, mins;
    double  secs;
    char    timebuf[128];

    if( rsecs < 0 ) {
        buffer += "-";
        rsecs = -rsecs;
    }
    fractional_seconds = rsecs - floor(rsecs);

    days = (int) rsecs;
    hrs  = days % 86400;
    mins = hrs  % 3600;
    secs = (mins % 60) + fractional_seconds;
    days = days / 86400;
    hrs  = hrs  / 3600;
    mins = mins / 60;

    if (days) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%d+%02d:%02d:%02d", days, hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%d+%02d:%02d:%02g", days, hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (hrs) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d:%02d", hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02d:%02g", hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (mins) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d", mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02g", mins, secs);
        }
        buffer += timebuf;
        return;
    } else {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d", (int) secs);
        } else {
            sprintf(timebuf, "%02g", secs);
        }
        buffer += timebuf;
    }
    return;
}

void day_numbers(int year, int month, int day, int &weekday, int &yearday)
{
    int fixed =       fixed_from_gregorian(year, month, day);
    int jan1_fixed =  fixed_from_gregorian(year, 1, 1);
    weekday = fixed % 7;
    yearday = fixed - jan1_fixed;
    return;
}

int fixed_from_gregorian(int year, int month, int day)
{
    int fixed;
    int month_adjustment;

    if (month <= 2) {
        month_adjustment = 0;
    } else if (is_leap_year(year)) {
        month_adjustment = -1;
    } else {
        month_adjustment = -2;
    }
    fixed = 365 * (year -1)
          + ((year - 1) / 4)
          - ((year - 1) / 100)
          + ((year - 1) / 400)
          + ((367 * month - 362) / 12)
          + month_adjustment
          + day;
    return fixed;
}

bool is_leap_year(int year)
{
    int  mod4;
    int  mod400;
    bool leap_year;

    mod4   = year % 4;
    mod400 = year % 400;

    if (mod4 == 0 && mod400 != 100 && mod400 != 200 && mod400 != 300) {
        leap_year = true;
    } else {
        leap_year = false;
    }
    return leap_year;
}

#ifdef WIN32
int classad_isinf(double x)
{

	int result;
	result = _fpclass(x);

	if (result == _FPCLASS_NINF ) {
		/* negative infinity */
		return -1;
	} else if ( result == _FPCLASS_PINF ) {
		/* positive infinity */
		return 1;
	} else {
		/* otherwise */
		return 0;
	}
}
#elif (defined (__SVR4) && defined (__sun)) || defined(__APPLE_CC__)
#ifndef __APPLE_CC__
#include <ieeefp.h>
#endif
int classad_isinf(double x)
{
    if (finite(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#else
int classad_isinf(double x)
{
    if (!isinf(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#endif

#ifdef  __APPLE_CC__
int classad_isnan(double x)
{
    return __isnan(x);
}
#else
int classad_isnan(double x)
{
    return isnan(x);
}
#endif

END_NAMESPACE // classad

<commit_msg>Portable isinf() and isnan() macros, needed for HPUX.<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "classad/common.h"
#include "classad/util.h"
#include <limits.h>
#include <math.h>

using namespace std;

#if HAVE_LONG_TIMEZONE
extern DLL_IMPORT_MAGIC long timezone;
#endif

// The following definitions of isnan() and isinf() are recommended here:
// http://www.gnu.org/software/libtool/manual/autoconf/Function-Portability.html
// We have observed isinf(HUGE_VAL) to return 0 on HPUX, but only apparently
// because of an errant #pragma extern applied to this constant in the system
// header files.  When passed a normal variable assigned to HUGE_VAL, isinf()
// does the right thing on that platform.

#ifndef isnan
# define isnan(x) \
    (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
     : sizeof (x) == sizeof (double) ? isnan_d (x) \
     : isnan_f (x))
static inline int isnan_f  (float       x) { return x != x; }
static inline int isnan_d  (double      x) { return x != x; }
static inline int isnan_ld (long double x) { return x != x; }
#endif

#ifndef isinf
# define isinf(x) \
    (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
     : sizeof (x) == sizeof (double) ? isinf_d (x) \
     : isinf_f (x))
static inline int isinf_f  (float       x) { return isnan (x - x); }
static inline int isinf_d  (double      x) { return isnan (x - x); }
static inline int isinf_ld (long double x) { return isnan (x - x); }
#endif

BEGIN_NAMESPACE( classad )

#ifdef WIN32
#define BIGGEST_RANDOM_INT RAND_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand(seed);
        initialized = 1;
	}

	return rand();
}
#else
#define BIGGEST_RANDOM_INT INT_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand48(seed);
        initialized = 1;
	}
	return (int) (lrand48() & INT_MAX);
}
#endif

double get_random_real(void)
{
    return (get_random_integer() / (double) BIGGEST_RANDOM_INT);
}

long timezone_offset(void)
{
#if HAVE_LONG_TIMEZONE
    return ::timezone;
#else
    static long tz_offset = 0;
    static bool have_tz_offset = false;

    if (!have_tz_offset) {
        struct tm  *tms;
        time_t     clock;

        time(&clock);
        tms = localtime(&clock);
        tz_offset = -tms->tm_gmtoff;
        if (0 != tms->tm_isdst) {
            tz_offset += 3600;
        }
    }
    return tz_offset;
#endif
}

void convert_escapes(string &text, bool &validStr)
{
	char *copy;
	int  length;
	int  source, dest;

	// We now it will be no longer than the original.
	length = text.length();
	copy = new char[length + 1];

	// We scan up to one less than the length, because we ignore
	// a terminating slash: it can't be an escape.
	dest = 0;
	for (source = 0; source < length - 1; source++) {
		if (text[source] != '\\' || source == length - 1) {
			copy[dest++]= text[source];
		}
		else {
			source++;

			char new_char;
			switch(text[source]) {
			case 'a':	new_char = '\a'; break;
			case 'b':	new_char = '\b'; break;
			case 'f':	new_char = '\f'; break;
			case 'n':	new_char = '\n'; break;
			case 'r':	new_char = '\r'; break;
			case 't':	new_char = '\t'; break;
			case 'v':	new_char = '\v'; break;
			case '\\':	new_char = '\\'; break;
			case '\?':	new_char = '\?'; break;
			case '\'':	new_char = '\''; break;
			case '\"':	new_char = '\"'; break;
			default:
				if (isodigit(text[source])) {
					unsigned int  number;
					// There are three allowed ways to have octal escape characters:
					//  \[0..3]nn or \nn or \n. We check for them in that order.
					if (   source <= length - 3
						&& text[source] >= '0' && text[source] <= '3'
						&& isodigit(text[source+1])
						&& isodigit(text[source+2])) {

						// We have the \[0..3]nn case
						char octal[4];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = text[source+2];
						octal[3] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 2; // to account for the two extra digits
					} else if (   source <= length -2
							   && isodigit(text[source+1])) {

						// We have the \nn case
						char octal[3];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 1; // to account for the extra digit
					} else if (source <= length - 1) {
						char octal[2];
						octal[0] = text[source];
						octal[1] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
					} else {
						new_char = text[source];
					}
					if(number == 0) { // "\\0" is an invalid substring within a string literal
					  validStr = false;
					  delete [] copy;
					  return;
					}
				} else {
					new_char = text[source];
				}
				break;
			}
			copy[dest++] = new_char;
		}
	}
	copy[dest] = 0;
	text = copy;
	delete [] copy;
	return;
}

void
getLocalTime(time_t *now, struct tm *localtm)
{

#ifndef WIN32
	localtime_r( now, localtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *lt_ptr;

	lt_ptr = localtime(now);

	if (localtm == NULL) { return; }

	localtm->tm_sec   = lt_ptr->tm_sec;    /* seconds */
	localtm->tm_min   = lt_ptr->tm_min;    /* minutes */
	localtm->tm_hour  = lt_ptr->tm_hour;   /* hours */
	localtm->tm_mday  = lt_ptr->tm_mday;   /* day of the month */
	localtm->tm_mon   = lt_ptr->tm_mon;    /* month */
	localtm->tm_year  = lt_ptr->tm_year;   /* year */
	localtm->tm_wday  = lt_ptr->tm_wday;   /* day of the week */
	localtm->tm_yday  = lt_ptr->tm_yday;   /* day in the year */
	localtm->tm_isdst = lt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void
getGMTime(time_t *now, struct tm *gtm)
{

#ifndef WIN32
	gmtime_r( now, gtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *gt_ptr;

	gt_ptr = gmtime(now);

	if (gtm == NULL) { return; }

	gtm->tm_sec   = gt_ptr->tm_sec;    /* seconds */
	gtm->tm_min   = gt_ptr->tm_min;    /* minutes */
	gtm->tm_hour  = gt_ptr->tm_hour;   /* hours */
	gtm->tm_mday  = gt_ptr->tm_mday;   /* day of the month */
	gtm->tm_mon   = gt_ptr->tm_mon;    /* month */
	gtm->tm_year  = gt_ptr->tm_year;   /* year */
	gtm->tm_wday  = gt_ptr->tm_wday;   /* day of the week */
	gtm->tm_yday  = gt_ptr->tm_yday;   /* day in the year */
	gtm->tm_isdst = gt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void absTimeToString(const abstime_t &atime, string &buffer)
{
    int       tzsecs;
    time_t    epoch_time;
    char      timebuf[32], sign;
    struct tm tms;

    tzsecs = atime.offset;
    epoch_time = atime.secs;
    if (tzsecs > 0) {
        sign = '+';         // timezone offset's sign
    } else {
        sign = '-';
        tzsecs = -tzsecs;
    }
    getGMTime(&epoch_time, &tms);
    strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", &tms);
    buffer += timebuf;
    sprintf(timebuf, "%c%02d%02d", sign, tzsecs / 3600, (tzsecs / 60) % 60);
    buffer += timebuf;
    return;
}

void relTimeToString(double rsecs, string &buffer)
{
    double  fractional_seconds;
    int     days, hrs, mins;
    double  secs;
    char    timebuf[128];

    if( rsecs < 0 ) {
        buffer += "-";
        rsecs = -rsecs;
    }
    fractional_seconds = rsecs - floor(rsecs);

    days = (int) rsecs;
    hrs  = days % 86400;
    mins = hrs  % 3600;
    secs = (mins % 60) + fractional_seconds;
    days = days / 86400;
    hrs  = hrs  / 3600;
    mins = mins / 60;

    if (days) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%d+%02d:%02d:%02d", days, hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%d+%02d:%02d:%02g", days, hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (hrs) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d:%02d", hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02d:%02g", hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (mins) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d", mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02g", mins, secs);
        }
        buffer += timebuf;
        return;
    } else {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d", (int) secs);
        } else {
            sprintf(timebuf, "%02g", secs);
        }
        buffer += timebuf;
    }
    return;
}

void day_numbers(int year, int month, int day, int &weekday, int &yearday)
{
    int fixed =       fixed_from_gregorian(year, month, day);
    int jan1_fixed =  fixed_from_gregorian(year, 1, 1);
    weekday = fixed % 7;
    yearday = fixed - jan1_fixed;
    return;
}

int fixed_from_gregorian(int year, int month, int day)
{
    int fixed;
    int month_adjustment;

    if (month <= 2) {
        month_adjustment = 0;
    } else if (is_leap_year(year)) {
        month_adjustment = -1;
    } else {
        month_adjustment = -2;
    }
    fixed = 365 * (year -1)
          + ((year - 1) / 4)
          - ((year - 1) / 100)
          + ((year - 1) / 400)
          + ((367 * month - 362) / 12)
          + month_adjustment
          + day;
    return fixed;
}

bool is_leap_year(int year)
{
    int  mod4;
    int  mod400;
    bool leap_year;

    mod4   = year % 4;
    mod400 = year % 400;

    if (mod4 == 0 && mod400 != 100 && mod400 != 200 && mod400 != 300) {
        leap_year = true;
    } else {
        leap_year = false;
    }
    return leap_year;
}

#ifdef WIN32
int classad_isinf(double x)
{

	int result;
	result = _fpclass(x);

	if (result == _FPCLASS_NINF ) {
		/* negative infinity */
		return -1;
	} else if ( result == _FPCLASS_PINF ) {
		/* positive infinity */
		return 1;
	} else {
		/* otherwise */
		return 0;
	}
}
#elif (defined (__SVR4) && defined (__sun)) || defined(__APPLE_CC__)
#ifndef __APPLE_CC__
#include <ieeefp.h>
#endif
int classad_isinf(double x)
{
    if (finite(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#else
int classad_isinf(double x)
{
    if (!isinf(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#endif

#ifdef  __APPLE_CC__
int classad_isnan(double x)
{
    return __isnan(x);
}
#else
int classad_isnan(double x)
{
    return isnan(x);
}
#endif

END_NAMESPACE // classad

<|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/wait.h>

#include "condor_debug.h"
#include "condor_types.h"
#include "condor_expressions.h"
#include "condor_mach_status.h"
#include "sched.h"

#include "cdefs.h"
#include "event.h"
#include "state.h"
#include "resource.h"
#include "resmgr.h"

#include "CondorPrefExps.h"
#include "CondorPendingJobs.h"

/*
 * Handle async events coming in to the startd.
 */

int command_startjob(Sock *, struct sockaddr_in *, resource_id_t,bool JobAlreadyGot=false);
int command_reqservice __P((Sock *, struct sockaddr_in *, resource_id_t));
int MatchInfo(resource_info_t* rip, char* str);

extern int polls_per_update;
extern int last_timeout;
extern int capab_timeout;
extern char *collector_host;
extern char *alt_collector_host;
extern int coll_sock;

// CHANGE -> N ANANd
//extern CONTEXT *template_context;
extern ClassAd* template_ClassAd;

extern ClassAd *resource_context __P((resource_info_t *));

extern "C" void event_timeout(int sig);

volatile int want_reconfig = 0;
int polls = 0;

static char *_FileName_ = __FILE__;

void update_central_mgr __P((void));

static int eval_state(resource_info_t* rip)
{
  int start = FALSE, tmp;
  resource_context(rip);
  if (rip->r_state == SYSTEM)
    resmgr_changestate(rip->r_rid, NO_JOB);
  if (rip->r_state == NO_JOB)
  {
    (rip->r_context)->EvalBool("START",template_ClassAd,start);
    if(CondorPendingJobs::AreTherePendingJobs(rip->r_rid))
    {
      dprintf(D_ALWAYS,"Identified a pending job\n");
      if(MatchInfo(rip,CondorPendingJobs::CapabString(rip->r_rid)))
	dprintf(D_ALWAYS,"Match Info FAILED!!!\n");
      else
      {
	Sock* sock=CondorPendingJobs::RetSock(rip->r_rid);
	struct sockaddr_in* from = CondorPendingJobs::RespondAddr(rip->r_rid);
	CondorPendingJobs::Status status =
	  CondorPendingJobs::Client(rip->r_rid,rip->r_client);
	CondorPendingJobs::Status status1 =
	  CondorPendingJobs::ScheddInterval(rip->r_rid,rip->r_interval);

	if((status!=CondorPendingJobs::eOK)||(status1!=CondorPendingJobs::eOK))
	  dprintf(D_ALWAYS,"Simulated Request Service FAILED!!!\n");
	else
	  dprintf(D_ALWAYS,"Simulated Request Service succeeded!\n");

	CondorPendingJobs::ClientMachine(rip->r_rid,rip->r_clientmachine);
	command_startjob(sock,from,rip->r_rid, true);
      }
    }
  }
  if (rip->r_pid != NO_PID && !rip->r_jobcontext)
  {
    EXCEPT("resource allocated, but no job context.\n");
  }

  if (!rip->r_jobcontext)
    return 0;

  if (rip->r_state == CHECKPOINTING)
  {
    if (rip->r_universe == VANILLA)
    {
      if(((rip->r_context)->EvalBool("KILL_VANILLA",rip->r_jobcontext,tmp))==0
	 &&((rip->r_context)->EvalBool("KILL",rip->r_context,tmp))==0 )
      {
	EXCEPT("Can't evaluate KILL\n");
      }
    }
    else
    {
      if(((rip->r_context)->EvalBool("KILL",rip->r_jobcontext,tmp))==0)
      {
	EXCEPT("Can't evaluate KILL\n");
      }
    }
    if (tmp)
    {
      event_killall(rip->r_rid, NO_JID, NO_TID);
      return 0;
    }
  }

  if (rip->r_state == SUSPENDED)
  {
    if (rip->r_universe == VANILLA)
    {
      if(((((rip->r_context)->EvalBool("VACATE_VANILLA",rip->r_jobcontext,tmp))==0))&&(((rip->r_context)->EvalBool("VACATE",rip->r_jobcontext,tmp))==0))
      {
	EXCEPT("Can't evaluate VACATE\n");
      }
    }
    else
    {
      if (((rip->r_context)->EvalBool("VACATE",rip->r_jobcontext,tmp))==0)
      {
	EXCEPT("Can't evaluate VACATE\n");
      }
    }
    if (tmp)
    {
      event_vacate(rip->r_rid, NO_JID, NO_TID);
      return 0;
    }
  }

  if (rip->r_state == JOB_RUNNING)
  {
    if (rip->r_universe == VANILLA)
    {
      if((((rip->r_context)->EvalBool("SUSPEND_VANILLA",rip->r_jobcontext,tmp))==0)&&((rip->r_context)->EvalBool("SUSPEND",rip->r_jobcontext,tmp))==0)
      {
		  EXCEPT("Can't evaluate SUSPEND\n");
      }
    }
    else
    {
      if(((rip->r_context)->EvalBool("SUSPEND",rip->r_jobcontext,tmp))==0)
      {
		  EXCEPT("Can't evaluate SUSPEND\n");
      }
    }
    if (tmp)
    {
#if 0
      if (rip->r_claimed)		/* Why call vacate_client here? */
		  vacate_client(rip->r_rid);
#endif
      event_suspend(rip->r_rid, NO_JID, NO_TID);
      return 0;
    }
  }

  if (rip->r_state == SUSPENDED)
  {
    if (rip->r_universe == VANILLA)
    {
      if((((rip->r_context)->EvalBool("CONTINUE_VANILLA",rip->r_jobcontext,tmp))==0)&&((rip->r_context)->EvalBool("CONTINUE",rip->r_jobcontext,tmp))==0)
      {
	EXCEPT("Can't evaluate CONTINUE\n");
      }
    }
    else
    {
      if(((rip->r_context)->EvalBool("CONTINUE",rip->r_jobcontext,tmp))==0)
      {
	EXCEPT("Can't evaluate CONTINUE\n");
      }
    }
    if (tmp)
    {
      event_continue(rip->r_rid, NO_JID, NO_TID);
      return 0;
    }
  }
  return 0;
}

static int
check_claims(resource_info_t* rip)
{
	if (rip->r_claimed == TRUE) {
		if ((time(NULL) - rip->r_receivetime) > 2 * rip->r_interval) {
			dprintf(D_ALWAYS, "Capability (%s) timed out\n",
				rip->r_capab);
			rip->r_claimed = FALSE;
			free(rip->r_capab);
			free(rip->r_client);
			rip->r_capab = NULL;
			rip->r_client = NULL;
		}
	} else if (rip->r_capab) {
		if (time(NULL) - rip->r_captime > capab_timeout) {
			dprintf(D_ALWAYS, "Capability (%s) timed out\n",
				rip->r_capab);
			rip->r_claimed = FALSE;
			free(rip->r_capab);
			free(rip->r_client);
			rip->r_capab = NULL;
			rip->r_client = NULL;
		}
	}
	return 0;
}

void
event_timeout(int sig)
{
	resmgr_walk(eval_state);
	resmgr_walk(check_claims);
	if (polls == 0)
		update_central_mgr();
	if (++polls >= polls_per_update)
		polls = 0;
	last_timeout = (int)time((time_t *)0);
}

void
event_sigchld(int sig)
{
	int pid, status;
	resource_id_t rid;
	resource_info_t *rip;
	char tmp[80];
	dprintf(D_ALWAYS,"Handling SIGCHLD\n");

	while ((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0 ) {
		if (WIFSTOPPED(status)) {
			dprintf(D_ALWAYS, "pid %d stopped.\n", pid);
			continue;
		}
		rip = resmgr_getbypid(pid);
		if (rip == NULL) {
			EXCEPT("SIGCHLD from job on non-existing resource??");
		}
		if (WIFSIGNALED(status))
			dprintf(D_ALWAYS, "pid %d died on signal %d\n",
				pid, WTERMSIG(status));
		else
			dprintf(D_ALWAYS, "pid %d exitex with status %d\n",
				pid, WEXITSTATUS(status));
		sprintf(tmp,"RemoteUser=%s",(rip->r_user));
		(rip->r_context)->Insert(tmp);
		resmgr_changestate(rip->r_rid, NO_JOB);
		event_exited(rip->r_rid, NO_JID, NO_TID);
	}
}

// void
// event_sigchld(sig)
// 	int sig;
// {
// 	int pid, status;
// 	resource_id_t rid;
// 	resource_info_t *rip;
// 	ELEM tmp;

// 	while ((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0 ) {
// 		if (WIFSTOPPED(status)) {
// 			dprintf(D_ALWAYS, "pid %d stopped.\n", pid);
// 			continue;
// 		}
// 		rip = resmgr_getbypid(pid);
// 		if (rip == NULL) {
// 			EXCEPT("SIGCHLD from job on non-existing resource??");
// 		}
// 		if (WIFSIGNALED(status))
// 			dprintf(D_ALWAYS, "pid %d died on signal %d\n",
// 				pid, WTERMSIG(status));
// 		else
// 			dprintf(D_ALWAYS, "pid %d exitex with status %d\n",
// 				pid, WEXITSTATUS(status));
// 		tmp.type = STRING;
// 		rip->r_user = "";
// 		tmp.s_val = rip->r_user;
// 		store_stmt(build_expr("RemoteUser", &tmp), rip->r_context);
// 		resmgr_changestate(rip->r_rid, NO_JOB);
// 		event_exited(rip->r_rid, NO_JID, NO_TID);
// 	}
// }

void
event_sighup(int sig)
{
	want_reconfig = 1;
}

void
event_sigterm(int sig)
{
	dprintf(D_ALWAYS, "Got SIGTERM. Freeing resources and exiting.\n");
	resmgr_vacateall();
}

void event_sigint(int sig)	/* sigint_handler */
{
	dprintf(D_ALWAYS, "Killed by SIGINT\n");
	exit(0);
}

void AccountForPrefExps(resource_info_t* rip)
{
  if(rip->r_state!=JOB_RUNNING)
  {
    // nothing to be done: possibly restore the
    // Requirements expression
    CondorPrefExps::RestoreReqEx(rip->r_context);
    return;
  }

  // A job is running, we need to modify the Requirements expression of
  // our ad suitably

  ClassAd* job = rip->r_jobcontext;
  ClassAd* mc = rip->r_context;

  CondorPrefExps::ModifyReqEx(mc,job);
}

static int send_resource_context(resource_info_t* rip)
{
	ClassAd *cp;

	dprintf(D_ALWAYS, "send_resource_context called.\n");
	AccountForPrefExps(rip);
	/*ForDebugging(rip);*/
	cp = resource_context(rip);
	send_classad_to_machine(collector_host, COLLECTOR_UDP_COMM_PORT,
							coll_sock, cp);
	if (alt_collector_host)
		send_classad_to_machine(alt_collector_host, COLLECTOR_UDP_COMM_PORT,
								coll_sock, cp);
	return 0;
}

void update_central_mgr()
{
	dprintf(D_ALWAYS, "update_central_manager called.\n");
	resmgr_walk(send_resource_context);
}
<commit_msg>use constants from condor_attributes.h; evaluate Requirements rather than START; don't update RemoteUser when it can be NULL<commit_after>#include <sys/types.h>
#include <sys/wait.h>

#include "condor_debug.h"
#include "condor_types.h"
#include "condor_attributes.h"
#include "condor_expressions.h"
#include "condor_mach_status.h"
#include "sched.h"

#include "cdefs.h"
#include "event.h"
#include "state.h"
#include "resource.h"
#include "resmgr.h"

#include "CondorPrefExps.h"
#include "CondorPendingJobs.h"

/*
 * Handle async events coming in to the startd.
 */

int command_startjob(Sock *, struct sockaddr_in *, resource_id_t,bool JobAlreadyGot=false);
int command_reqservice __P((Sock *, struct sockaddr_in *, resource_id_t));
int MatchInfo(resource_info_t* rip, char* str);

extern int polls_per_update;
extern int last_timeout;
extern int capab_timeout;
extern char *collector_host;
extern char *alt_collector_host;
extern int coll_sock;

// CHANGE -> N ANANd
//extern CONTEXT *template_context;
extern ClassAd* template_ClassAd;

extern ClassAd *resource_context __P((resource_info_t *));

extern "C" void event_timeout(int sig);

volatile int want_reconfig = 0;
int polls = 0;

static char *_FileName_ = __FILE__;

void update_central_mgr __P((void));

static int eval_state(resource_info_t* rip)
{
  int start = FALSE, tmp;
  resource_context(rip);
  if (rip->r_state == SYSTEM)
    resmgr_changestate(rip->r_rid, NO_JOB);
  if (rip->r_state == NO_JOB)
  {
    (rip->r_context)->EvalBool(ATTR_REQUIREMENTS,template_ClassAd,start);
    if(CondorPendingJobs::AreTherePendingJobs(rip->r_rid))
    {
      dprintf(D_ALWAYS,"Identified a pending job\n");
      if(MatchInfo(rip,CondorPendingJobs::CapabString(rip->r_rid)))
	dprintf(D_ALWAYS,"Match Info FAILED!!!\n");
      else
      {
	Sock* sock=CondorPendingJobs::RetSock(rip->r_rid);
	struct sockaddr_in* from = CondorPendingJobs::RespondAddr(rip->r_rid);
	CondorPendingJobs::Status status =
	  CondorPendingJobs::Client(rip->r_rid,rip->r_client);
	CondorPendingJobs::Status status1 =
	  CondorPendingJobs::ScheddInterval(rip->r_rid,rip->r_interval);

	if((status!=CondorPendingJobs::eOK)||(status1!=CondorPendingJobs::eOK))
	  dprintf(D_ALWAYS,"Simulated Request Service FAILED!!!\n");
	else
	  dprintf(D_ALWAYS,"Simulated Request Service succeeded!\n");

	CondorPendingJobs::ClientMachine(rip->r_rid,rip->r_clientmachine);
	command_startjob(sock,from,rip->r_rid, true);
      }
    }
  }
  if (rip->r_pid != NO_PID && !rip->r_jobcontext)
  {
    EXCEPT("resource allocated, but no job context.\n");
  }

  if (!rip->r_jobcontext)
    return 0;

  if (rip->r_state == CHECKPOINTING)
  {
    if (rip->r_universe == VANILLA)
    {
      if(((rip->r_context)->EvalBool("KILL_VANILLA",rip->r_jobcontext,tmp))==0
	 &&((rip->r_context)->EvalBool("KILL",rip->r_context,tmp))==0 )
      {
	EXCEPT("Can't evaluate KILL\n");
      }
    }
    else
    {
      if(((rip->r_context)->EvalBool("KILL",rip->r_jobcontext,tmp))==0)
      {
	EXCEPT("Can't evaluate KILL\n");
      }
    }
    if (tmp)
    {
      event_killall(rip->r_rid, NO_JID, NO_TID);
      return 0;
    }
  }

  if (rip->r_state == SUSPENDED)
  {
    if (rip->r_universe == VANILLA)
    {
      if(((((rip->r_context)->EvalBool("VACATE_VANILLA",rip->r_jobcontext,tmp))==0))&&(((rip->r_context)->EvalBool("VACATE",rip->r_jobcontext,tmp))==0))
      {
	EXCEPT("Can't evaluate VACATE\n");
      }
    }
    else
    {
      if (((rip->r_context)->EvalBool("VACATE",rip->r_jobcontext,tmp))==0)
      {
	EXCEPT("Can't evaluate VACATE\n");
      }
    }
    if (tmp)
    {
      event_vacate(rip->r_rid, NO_JID, NO_TID);
      return 0;
    }
  }

  if (rip->r_state == JOB_RUNNING)
  {
    if (rip->r_universe == VANILLA)
    {
      if((((rip->r_context)->EvalBool("SUSPEND_VANILLA",rip->r_jobcontext,tmp))==0)&&((rip->r_context)->EvalBool("SUSPEND",rip->r_jobcontext,tmp))==0)
      {
		  EXCEPT("Can't evaluate SUSPEND\n");
      }
    }
    else
    {
      if(((rip->r_context)->EvalBool("SUSPEND",rip->r_jobcontext,tmp))==0)
      {
		  EXCEPT("Can't evaluate SUSPEND\n");
      }
    }
    if (tmp)
    {
#if 0
      if (rip->r_claimed)		/* Why call vacate_client here? */
		  vacate_client(rip->r_rid);
#endif
      event_suspend(rip->r_rid, NO_JID, NO_TID);
      return 0;
    }
  }

  if (rip->r_state == SUSPENDED)
  {
    if (rip->r_universe == VANILLA)
    {
      if((((rip->r_context)->EvalBool("CONTINUE_VANILLA",rip->r_jobcontext,tmp))==0)&&((rip->r_context)->EvalBool("CONTINUE",rip->r_jobcontext,tmp))==0)
      {
	EXCEPT("Can't evaluate CONTINUE\n");
      }
    }
    else
    {
      if(((rip->r_context)->EvalBool("CONTINUE",rip->r_jobcontext,tmp))==0)
      {
	EXCEPT("Can't evaluate CONTINUE\n");
      }
    }
    if (tmp)
    {
      event_continue(rip->r_rid, NO_JID, NO_TID);
      return 0;
    }
  }
  return 0;
}

static int
check_claims(resource_info_t* rip)
{
	if (rip->r_claimed == TRUE) {
		if ((time(NULL) - rip->r_receivetime) > 2 * rip->r_interval) {
			dprintf(D_ALWAYS, "Capability (%s) timed out\n",
				rip->r_capab);
			rip->r_claimed = FALSE;
			free(rip->r_capab);
			free(rip->r_client);
			rip->r_capab = NULL;
			rip->r_client = NULL;
		}
	} else if (rip->r_capab) {
		if (time(NULL) - rip->r_captime > capab_timeout) {
			dprintf(D_ALWAYS, "Capability (%s) timed out\n",
				rip->r_capab);
			rip->r_claimed = FALSE;
			free(rip->r_capab);
			free(rip->r_client);
			rip->r_capab = NULL;
			rip->r_client = NULL;
		}
	}
	return 0;
}

void
event_timeout(int sig)
{
	resmgr_walk(eval_state);
	resmgr_walk(check_claims);
	if (polls == 0)
		update_central_mgr();
	if (++polls >= polls_per_update)
		polls = 0;
	last_timeout = (int)time((time_t *)0);
}

void
event_sigchld(int sig)
{
	int pid, status;
	resource_id_t rid;
	resource_info_t *rip;
	char tmp[80];
	dprintf(D_ALWAYS,"Handling SIGCHLD\n");

	while ((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0 ) {
		if (WIFSTOPPED(status)) {
			dprintf(D_ALWAYS, "pid %d stopped.\n", pid);
			continue;
		}
		rip = resmgr_getbypid(pid);
		if (rip == NULL) {
			EXCEPT("SIGCHLD from job on non-existing resource??");
		}
		if (WIFSIGNALED(status))
			dprintf(D_ALWAYS, "pid %d died on signal %d\n",
				pid, WTERMSIG(status));
		else
			dprintf(D_ALWAYS, "pid %d exitex with status %d\n",
				pid, WEXITSTATUS(status));
#if 0
		// ??? Why update RemoteUser here?  rip->r_user could be NULL!
		sprintf(tmp,"RemoteUser=%s",(rip->r_user));
		(rip->r_context)->Insert(tmp);
#endif
		resmgr_changestate(rip->r_rid, NO_JOB);
		event_exited(rip->r_rid, NO_JID, NO_TID);
	}
}

// void
// event_sigchld(sig)
// 	int sig;
// {
// 	int pid, status;
// 	resource_id_t rid;
// 	resource_info_t *rip;
// 	ELEM tmp;

// 	while ((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0 ) {
// 		if (WIFSTOPPED(status)) {
// 			dprintf(D_ALWAYS, "pid %d stopped.\n", pid);
// 			continue;
// 		}
// 		rip = resmgr_getbypid(pid);
// 		if (rip == NULL) {
// 			EXCEPT("SIGCHLD from job on non-existing resource??");
// 		}
// 		if (WIFSIGNALED(status))
// 			dprintf(D_ALWAYS, "pid %d died on signal %d\n",
// 				pid, WTERMSIG(status));
// 		else
// 			dprintf(D_ALWAYS, "pid %d exitex with status %d\n",
// 				pid, WEXITSTATUS(status));
// 		tmp.type = STRING;
// 		rip->r_user = "";
// 		tmp.s_val = rip->r_user;
// 		store_stmt(build_expr("RemoteUser", &tmp), rip->r_context);
// 		resmgr_changestate(rip->r_rid, NO_JOB);
// 		event_exited(rip->r_rid, NO_JID, NO_TID);
// 	}
// }

void
event_sighup(int sig)
{
	want_reconfig = 1;
}

void
event_sigterm(int sig)
{
	dprintf(D_ALWAYS, "Got SIGTERM. Freeing resources and exiting.\n");
	resmgr_vacateall();
}

void event_sigint(int sig)	/* sigint_handler */
{
	dprintf(D_ALWAYS, "Killed by SIGINT\n");
	exit(0);
}

void AccountForPrefExps(resource_info_t* rip)
{
  if(rip->r_state!=JOB_RUNNING)
  {
    // nothing to be done: possibly restore the
    // Requirements expression
    CondorPrefExps::RestoreReqEx(rip->r_context);
    return;
  }

  // A job is running, we need to modify the Requirements expression of
  // our ad suitably

  ClassAd* job = rip->r_jobcontext;
  ClassAd* mc = rip->r_context;

  CondorPrefExps::ModifyReqEx(mc,job);
}

static int send_resource_context(resource_info_t* rip)
{
	ClassAd *cp;

	dprintf(D_ALWAYS, "send_resource_context called.\n");
	AccountForPrefExps(rip);
	/*ForDebugging(rip);*/
	cp = resource_context(rip);
	send_classad_to_machine(collector_host, COLLECTOR_UDP_COMM_PORT,
							coll_sock, cp);
	if (alt_collector_host)
		send_classad_to_machine(alt_collector_host, COLLECTOR_UDP_COMM_PORT,
								coll_sock, cp);
	return 0;
}

void update_central_mgr()
{
	dprintf(D_ALWAYS, "update_central_manager called.\n");
	resmgr_walk(send_resource_context);
}
<|endoftext|>


<commit_before>#pragma once

#if defined(_WIN32)
#include <windows.h>
#elif !defined(EMSCRIPTEN)
#include <dlfcn.h>
#endif

#include <string>

#ifndef EMSCRIPTEN
namespace processwarp {
namespace DynamicLibrary {

/** Type for dynamic link library handler. */
#ifdef _WIN32
typedef HMODULE lib_handler_t;
#else
typedef void* lib_handler_t;
#endif
/** Type for external function pointer. */
typedef void (*external_func_t)();

lib_handler_t open_lib(const std::string& name);
external_func_t get_func(lib_handler_t handler, const std::string& name);
void close_lib(lib_handler_t handler);

}  // namespace DynamicLibrary
}  // namespace processwarp
#endif
<commit_msg>fix a wrong parameter name<commit_after>#pragma once

#if defined(_WIN32)
#include <windows.h>
#elif !defined(EMSCRIPTEN)
#include <dlfcn.h>
#endif

#include <string>

#ifndef EMSCRIPTEN
namespace processwarp {
namespace DynamicLibrary {

/** Type for dynamic link library handler. */
#ifdef _WIN32
typedef HMODULE lib_handler_t;
#else
typedef void* lib_handler_t;
#endif
/** Type for external function pointer. */
typedef void (*external_func_t)();

lib_handler_t open_lib(const std::string& fname);
external_func_t get_func(lib_handler_t handler, const std::string& name);
void close_lib(lib_handler_t handler);

}  // namespace DynamicLibrary
}  // namespace processwarp
#endif
<|endoftext|>


<commit_before>#include <fstream>
#include <json/json.h>
#include "GraphSerializer.hpp"

namespace tsp
{
    static bool validateGraph(const Json::Value &root)
    {
        return root.isObject() && root["nodes"].isArray() && root["edges"].isArray();
    }

    bool GraphSerializer::deserialize(Graph &graph, std::istream& is)
    {
        Json::Value root;
        Json::Reader reader;

        if(!reader.parse(is, root, false))
            return false;
        if(!validateGraph(root))
            return false;

        // deserialize nodes
        Json::Value &nodes = root["nodes"];
        graph.resize(nodes.size());
        for(unsigned int i = 0; nodes.size(); ++i)
            graph[i] = Node(nodes[i]["id"].asInt(), nodes[i]["x"].asInt(), nodes[i]["y"].asInt());

        return true;
    }

    bool GraphSerializer::serialize(Graph &graph, std::ostream& os)
    {
        Json::StyledStreamWriter writer;
        Json::Value root;

        root["nodes"] = Json::Value(Json::arrayValue);
        // serialize nodes
        root["nodes"].resize(graph.size());
        Json::Value &nodes = root["nodes"];
        for(unsigned int i = 0; i < nodes.size(); ++i)
        {
            nodes[i]["id"] = graph[i].id();
            nodes[i]["x"] = graph[i].x();
            nodes[i]["y"] = graph[i].y();
        }

        writer.write(os, root);

        return true;
    }

    bool GraphSerializer::load(Graph &graph, const std::string& file)
    {
        std::ifstream is(file);
        return deserialize(graph, is);
    }

    bool GraphSerializer::save(Graph &graph, const std::string& file)
    {
        std::ofstream os(file);
        return serialize(graph, os);
    }
}

<commit_msg>Fix Graph validation<commit_after>#include <fstream>
#include <json/json.h>
#include "GraphSerializer.hpp"

namespace tsp
{
    static bool validateGraph(const Json::Value &root)
    {
        return root.isObject() && root["nodes"].isArray();
    }

    bool GraphSerializer::deserialize(Graph &graph, std::istream& is)
    {
        Json::Value root;
        Json::Reader reader;

        if(!reader.parse(is, root, false))
            return false;
        if(!validateGraph(root))
            return false;

        // deserialize nodes
        Json::Value &nodes = root["nodes"];
        graph.resize(nodes.size());
        for(unsigned int i = 0; nodes.size(); ++i)
            graph[i] = Node(nodes[i]["id"].asInt(), nodes[i]["x"].asInt(), nodes[i]["y"].asInt());

        return true;
    }

    bool GraphSerializer::serialize(Graph &graph, std::ostream& os)
    {
        Json::StyledStreamWriter writer;
        Json::Value root;

        root["nodes"] = Json::Value(Json::arrayValue);
        // serialize nodes
        root["nodes"].resize(graph.size());
        Json::Value &nodes = root["nodes"];
        for(unsigned int i = 0; i < nodes.size(); ++i)
        {
            nodes[i]["id"] = graph[i].id();
            nodes[i]["x"] = graph[i].x();
            nodes[i]["y"] = graph[i].y();
        }

        writer.write(os, root);

        return true;
    }

    bool GraphSerializer::load(Graph &graph, const std::string& file)
    {
        std::ifstream is(file);
        return deserialize(graph, is);
    }

    bool GraphSerializer::save(Graph &graph, const std::string& file)
    {
        std::ofstream os(file);
        return serialize(graph, os);
    }
}

<|endoftext|>


<commit_before>/*

  This macro will add histograms from a list of root files and write them
  to a target root file. The target file is newly created and must not be
  identical to one of the source files.

  Syntax:

  hist_add targetfile source1 source2 ...

  Author: Sven A. Schmidt, sven.schmidt@cern.ch
  Date:   13.2.2001

  This code is based on the hadd.C example by Rene Brun and Dirk Geppert,
  which had a problem with directories more than one level deep.
  (see macro hadd_old.C for this previous implementation).

  I have tested this macro on rootfiles with one and two dimensional
  histograms, and two levels of subdirectories. Feel free to send comments
  or bug reports to me.

 */

#include <TROOT.h>
#include "TFile.h"
#include "TH1.h"
#include "TTree.h"
#include "TKey.h"
#include <string.h>
#include <iostream.h>

TROOT Root( "hist_add", "Histogram Merger" );

TList *FileList;
TFile *Target;

void MergeRootfile( TDirectory *target, TList *sourcelist );

int main( int argc, char **argv ) {

  FileList = new TList();

  if ( argc < 4 ) {
    cout << "Usage: " << argv[0] << " <target> <source1> <source2> ...\n";
    cout << "supply at least two source files for this to make sense... ;-)\n";
    exit( -1 );
  }

  cout << "Target file: " << argv[1] << endl;
  Target = TFile::Open( argv[1], "RECREATE" );

  for ( int i = 2; i < argc; i++ ) {
    cout << "Source file " << i-1 << ": " << argv[i] << endl;
    FileList->Add( TFile::Open( argv[i] ) );
  }

  MergeRootfile( Target, FileList );

}

// Merge all files from sourcelist into the target directory.
// The directory level (depth) is determined by the target directory's
// current level
void MergeRootfile( TDirectory *target, TList *sourcelist ) {

  //  cout << "Target path: " << target->GetPath() << endl;
  TString path( (char*)strstr( target->GetPath(), ":" ) );
  path.Remove( 0, 2 );

  TFile *first_source = (TFile*)sourcelist->First();
  first_source->cd( path );
  TDirectory *current_sourcedir = gDirectory;

  // loop over all keys in this directory
  TIter nextkey( current_sourcedir->GetListOfKeys() );
  while ( TKey *key = (TKey*)nextkey() ) {

    // read object from first source file
    first_source->cd( path );
    TObject *obj = key->ReadObj();

    if ( obj->IsA()->InheritsFrom( "TH1" ) ) {
      // descendant of TH1 -> merge it

      //      cout << "Merging histogram " << obj->GetName() << endl;
      TH1 *h1 = (TH1*)obj;

      // loop over all source files and add the content of the
      // correspondant histogram to the one pointed to by "h1"
      TFile *nextsource = (TFile*)sourcelist->After( first_source );
      while ( nextsource ) {

        // make sure we are at the correct directory level by cd'ing to path
        nextsource->cd( path );
        TH1 *h2 = (TH1*)gDirectory->Get( h1->GetName() );
        if ( h2 ) {
          h1->Add( h2 );
          delete h2; // don't know if this is necessary, i.e. if
                     // h2 is created by the call to gDirectory above.
        }

        nextsource = (TFile*)sourcelist->After( nextsource );
      }

    } else if ( obj->IsA()->InheritsFrom( "TDirectory" ) ) {
      // it's a subdirectory

      cout << "Found subdirectory " << obj->GetName() << endl;

      // create a new subdir of same name and title in the target file
      target->cd();
      TDirectory *newdir = target->mkdir( obj->GetName(), obj->GetTitle() );

      // newdir is now the starting point of another round of merging
      // newdir still knows its depth within the target file via
      // GetPath(), so we can still figure out where we are in the recursion
      MergeRootfile( newdir, sourcelist );

    } else {
      // object is of no type that we know or can handle
      cout << "Unknown object type, name: "
           << obj->GetName() << " title: " << obj->GetTitle() << endl;
    }

    // now write the merged histogram (which is "in" obj) to the target file
    // note that this will just store obj in the current directory level,
    // which is not persistent until the complete directory itself is stored
    // by "target->Write()" below
    if ( obj ) {
      target->cd();
      obj->Write( key->GetName() );
    }

  } // while ( ( TKey *key = (TKey*)nextkey() ) )

  // save modifications to target file
  target->Write();

}
<commit_msg>Remove the statement calling the TROOT constructor.<commit_after>/*

  This macro will add histograms from a list of root files and write them
  to a target root file. The target file is newly created and must not be
  identical to one of the source files.

  Syntax:

  hist_add targetfile source1 source2 ...

  Author: Sven A. Schmidt, sven.schmidt@cern.ch
  Date:   13.2.2001

  This code is based on the hadd.C example by Rene Brun and Dirk Geppert,
  which had a problem with directories more than one level deep.
  (see macro hadd_old.C for this previous implementation).

  I have tested this macro on rootfiles with one and two dimensional
  histograms, and two levels of subdirectories. Feel free to send comments
  or bug reports to me.

 */

#include "TFile.h"
#include "TH1.h"
#include "TTree.h"
#include "TKey.h"
#include <string.h>
#include <iostream.h>

TList *FileList;
TFile *Target;

void MergeRootfile( TDirectory *target, TList *sourcelist );

int main( int argc, char **argv ) {

  FileList = new TList();

  if ( argc < 4 ) {
    cout << "Usage: " << argv[0] << " <target> <source1> <source2> ...\n";
    cout << "supply at least two source files for this to make sense... ;-)\n";
    exit( -1 );
  }

  cout << "Target file: " << argv[1] << endl;
  Target = TFile::Open( argv[1], "RECREATE" );

  for ( int i = 2; i < argc; i++ ) {
    cout << "Source file " << i-1 << ": " << argv[i] << endl;
    FileList->Add( TFile::Open( argv[i] ) );
  }

  MergeRootfile( Target, FileList );

}

// Merge all files from sourcelist into the target directory.
// The directory level (depth) is determined by the target directory's
// current level
void MergeRootfile( TDirectory *target, TList *sourcelist ) {

  //  cout << "Target path: " << target->GetPath() << endl;
  TString path( (char*)strstr( target->GetPath(), ":" ) );
  path.Remove( 0, 2 );

  TFile *first_source = (TFile*)sourcelist->First();
  first_source->cd( path );
  TDirectory *current_sourcedir = gDirectory;

  // loop over all keys in this directory
  TIter nextkey( current_sourcedir->GetListOfKeys() );
  while ( TKey *key = (TKey*)nextkey() ) {

    // read object from first source file
    first_source->cd( path );
    TObject *obj = key->ReadObj();

    if ( obj->IsA()->InheritsFrom( "TH1" ) ) {
      // descendant of TH1 -> merge it

      //      cout << "Merging histogram " << obj->GetName() << endl;
      TH1 *h1 = (TH1*)obj;

      // loop over all source files and add the content of the
      // correspondant histogram to the one pointed to by "h1"
      TFile *nextsource = (TFile*)sourcelist->After( first_source );
      while ( nextsource ) {

        // make sure we are at the correct directory level by cd'ing to path
        nextsource->cd( path );
        TH1 *h2 = (TH1*)gDirectory->Get( h1->GetName() );
        if ( h2 ) {
          h1->Add( h2 );
          delete h2; // don't know if this is necessary, i.e. if
                     // h2 is created by the call to gDirectory above.
        }

        nextsource = (TFile*)sourcelist->After( nextsource );
      }

    } else if ( obj->IsA()->InheritsFrom( "TDirectory" ) ) {
      // it's a subdirectory

      cout << "Found subdirectory " << obj->GetName() << endl;

      // create a new subdir of same name and title in the target file
      target->cd();
      TDirectory *newdir = target->mkdir( obj->GetName(), obj->GetTitle() );

      // newdir is now the starting point of another round of merging
      // newdir still knows its depth within the target file via
      // GetPath(), so we can still figure out where we are in the recursion
      MergeRootfile( newdir, sourcelist );

    } else {
      // object is of no type that we know or can handle
      cout << "Unknown object type, name: "
           << obj->GetName() << " title: " << obj->GetTitle() << endl;
    }

    // now write the merged histogram (which is "in" obj) to the target file
    // note that this will just store obj in the current directory level,
    // which is not persistent until the complete directory itself is stored
    // by "target->Write()" below
    if ( obj ) {
      target->cd();
      obj->Write( key->GetName() );
    }

  } // while ( ( TKey *key = (TKey*)nextkey() ) )

  // save modifications to target file
  target->Write();

}
<|endoftext|>