<commit_before>#define PUT(x) std::cout << #x "=" << (x) << std::endl;
#include <mcl/fp.hpp>
#include <mcl/ecparam.hpp>
#include <cybozu/xorshift.hpp>
#include <cybozu/test.hpp>
#include <cybozu/benchmark.hpp>

struct FpTag;
typedef mcl::FpT<FpTag, 384> Fp;

void put(const void *buf, size_t bufSize)
{
	const unsigned char* p = (const unsigned char*)buf;
	for (size_t i = 0; i < bufSize; i++) {
		printf("%02x", p[i]);
	}
	printf("\n");
}

template<class F, typename T>
void powC(F& z, const F& x, const T *yTbl, size_t yn)
{
	const size_t w = 4;
	const size_t N = 1 << w;
	uint8_t idxTbl[256/w];
	mcl::fp::ArrayIterator<T> iter(yTbl, sizeof(T) * 8 * yn, w);
	size_t idxN = 0;
	while (iter.hasNext()) {
		assert(idxN < sizeof(idxTbl));
		idxTbl[idxN++] = iter.getNext();
	}
	assert(idxN > 0);
	F tbl[N];
	tbl[1] = x;
	for (size_t i = 2; i < N; i++) {
		tbl[i] = tbl[i-1] * x;
	}
	z = tbl[idxTbl[idxN - 1]];
	for (size_t i = 1; i < idxN; i++) {
		for (size_t j = 0; j < w; j++) {
			F::sqr(z, z);
		}
		uint32_t idx = idxTbl[idxN - 1 - i];
		if (idx) z *= tbl[idx];
	}
}

inline size_t getBinary(uint8_t *bin, size_t maxBinN, mpz_class x, size_t w)
{
	if (w == 0 || w >= 8) return 0;
	size_t binN = 0;
	size_t zeroNum = 0;
	const size_t maskW = (1u << w) - 1;
	using namespace mcl::gmp;
	while (!isZero(x)) {
		size_t z = getLowerZeroBitNum(x);
		if (z) {
			x >>= z;
			zeroNum += z;
		}
		for (size_t i = 0; i < zeroNum; i++) {
			if (binN == maxBinN) return 0;
			bin[binN++] = 0;
		}
		int v = getUnit(x)[0] & maskW;
		x >>= w;
		if (binN == maxBinN) return 0;
		bin[binN++] = v;
		zeroNum = w - 1;
	}
	return binN;
}

template<class F, size_t w = 5>
void pow3(F& z, const F& x, const mpz_class& y)
{
	assert(y >= 0);
	assert(w > 0);
	if (y == 0) {
		z = 1;
		return;
	}
	const size_t tblSize = 1 << (w - 1);
	uint8_t bin[sizeof(F) * 8];
	F tbl[tblSize];
	mpz_class u;
	size_t binN = getBinary(bin, sizeof(bin), y, w);

	F x2;
	F::sqr(x2, x);
	tbl[0] = x;
	for (size_t i = 1; i < tblSize; i++) {
		F::mul(tbl[i], tbl[i - 1], x2);
	}
	z = 1;
	for (size_t i = 0; i < binN; i++) {
		const size_t bit = binN - 1 - i;
		F::sqr(z, z);
		uint8_t n = bin[bit];
		if (n > 0) {
			z *= tbl[(n - 1) >> 1];
		}
	}
}

template<class T>
void pow2(T& z, const T& x, const mpz_class& y)
{
	powC(z, x, mcl::gmp::getUnit(y), mcl::gmp::getUnitSize(y));
}

template<class T, class F>
void pow2(T& z, const T& x, const F& y_)
{
	mpz_class y = y_.getMpz();
	powC(z, x, mcl::gmp::getUnit(y), mcl::gmp::getUnitSize(y));
}

void bench(const char *name, const char *pStr)
{
	printf("bench name=%s\n", name);
	Fp::init(pStr);
	const int C = 100000;
	cybozu::XorShift rg;
	Fp x, y;
	for (int i = 0; i < 100; i++) {
		x.setByCSPRNG(rg);
		y.setByCSPRNG(rg);
		Fp t1, t2;
		Fp::pow(t1, x, y);
		pow3(t2, x, y.getMpz());
		CYBOZU_TEST_EQUAL(t1, t2);
	}
	CYBOZU_BENCH_C("Fp::add", C, Fp::add, x, x, y);
	CYBOZU_BENCH_C("Fp::sub", C, Fp::sub, x, x, y);
	CYBOZU_BENCH_C("Fp::mul", C, Fp::mul, x, x, y);
	CYBOZU_BENCH_C("Fp::sqr", C, Fp::sqr, x, x);
	CYBOZU_BENCH_C("Fp::inv", C, Fp::inv, x, x);
	CYBOZU_BENCH_C("Fp::pow", C, Fp::pow, x, x, y);
	mpz_class my = y.getMpz();
	CYBOZU_BENCH_C("pow3", C, pow3, x, x, my);
	CYBOZU_BENCH_C("pow2", C, pow2, x, x, y);
}

CYBOZU_TEST_AUTO(main)
{
	const struct {
		const char *name;
		const char *pStr;
	} tbl[] = {
		{ "secp256k1p", mcl::ecparam::secp256k1.p },
		{ "secp256k1r", mcl::ecparam::secp256k1.n },
		{ "bn254r", "0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d" },
		{ "bn254p", "0x2523648240000001ba344d80000000086121000000000013a700000000000013" },
		{ "bls12_381p", "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" },
		{ "bls12_381r", "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab" },
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		bench(tbl[i].name, tbl[i].pStr);
	}
}

<commit_msg>[skip ci] count mul/sqr<commit_after>#define PUT(x) std::cout << #x "=" << (x) << std::endl;
#include <mcl/fp.hpp>
#include <mcl/ecparam.hpp>
#include <cybozu/xorshift.hpp>
#include <cybozu/test.hpp>
#include <cybozu/benchmark.hpp>

struct FpTag;
typedef mcl::FpT<FpTag, 384> Fp;

void put(const void *buf, size_t bufSize)
{
	const unsigned char* p = (const unsigned char*)buf;
	for (size_t i = 0; i < bufSize; i++) {
		printf("%02x", p[i]);
	}
	printf("\n");
}

static int ccc_mul;
static int ccc_sqr;

template<class F, typename T>
void powC(F& z, const F& x, const T *yTbl, size_t yn)
{
	const size_t w = 4;
	const size_t N = 1 << w;
	uint8_t idxTbl[256/w];
	mcl::fp::ArrayIterator<T> iter(yTbl, sizeof(T) * 8 * yn, w);
	size_t idxN = 0;
	while (iter.hasNext()) {
		assert(idxN < sizeof(idxTbl));
		idxTbl[idxN++] = iter.getNext();
	}
	assert(idxN > 0);
	F tbl[N];
	tbl[1] = x;
	for (size_t i = 2; i < N; i++) {
		tbl[i] = tbl[i-1] * x;
ccc_mul++;
	}
	z = tbl[idxTbl[idxN - 1]];
	for (size_t i = 1; i < idxN; i++) {
		for (size_t j = 0; j < w; j++) {
			F::sqr(z, z);
ccc_sqr++;
		}
		uint32_t idx = idxTbl[idxN - 1 - i];
		if (idx) {
			z *= tbl[idx];
ccc_mul++;
		}
	}
}

inline size_t getBinary(uint8_t *bin, size_t maxBinN, mpz_class x, size_t w)
{
	if (w == 0 || w >= 8) return 0;
	size_t binN = 0;
	size_t zeroNum = 0;
	const size_t maskW = (1u << w) - 1;
	using namespace mcl::gmp;
	while (!isZero(x)) {
		size_t z = getLowerZeroBitNum(x);
		if (z) {
			x >>= z;
			zeroNum += z;
		}
		for (size_t i = 0; i < zeroNum; i++) {
			if (binN == maxBinN) return 0;
			bin[binN++] = 0;
		}
		int v = getUnit(x)[0] & maskW;
		x >>= w;
		if (binN == maxBinN) return 0;
		bin[binN++] = v;
		zeroNum = w - 1;
	}
	return binN;
}

template<class F, size_t w = 5>
void pow3(F& z, const F& x, const mpz_class& y)
{
	assert(y >= 0);
	assert(w > 0);
	if (y == 0) {
		z = 1;
		return;
	}
	const size_t tblSize = 1 << (w - 1);
	uint8_t bin[sizeof(F) * 8];
	F tbl[tblSize];
	mpz_class u;
	size_t binN = getBinary(bin, sizeof(bin), y, w);

	F x2;
	F::sqr(x2, x);
ccc_sqr++;
	tbl[0] = x;
	for (size_t i = 1; i < tblSize; i++) {
		F::mul(tbl[i], tbl[i - 1], x2);
ccc_mul++;
	}
	z = 1;
	for (size_t i = 0; i < binN; i++) {
		const size_t bit = binN - 1 - i;
		F::sqr(z, z);
ccc_sqr++;
		uint8_t n = bin[bit];
		if (n > 0) {
			z *= tbl[(n - 1) >> 1];
ccc_mul++;
		}
	}
}

template<class T>
void pow2(T& z, const T& x, const mpz_class& y)
{
	powC(z, x, mcl::gmp::getUnit(y), mcl::gmp::getUnitSize(y));
}

template<class T, class F>
void pow2(T& z, const T& x, const F& y_)
{
	mpz_class y = y_.getMpz();
	powC(z, x, mcl::gmp::getUnit(y), mcl::gmp::getUnitSize(y));
}

template<class T, class F>
void pow3(T& z, const T& x, const F& y_)
{
	mpz_class y = y_.getMpz();
	pow3(z, x, y);
}

void bench(const char *name, const char *pStr)
{
	printf("bench name=%s\n", name);
	Fp::init(pStr);
	const int C = 10000;
	cybozu::XorShift rg;
	Fp x, y;
	for (int i = 0; i < 100; i++) {
		x.setByCSPRNG(rg);
		y.setByCSPRNG(rg);
		Fp t1, t2;
		Fp::pow(t1, x, y);
		pow3(t2, x, y.getMpz());
		CYBOZU_TEST_EQUAL(t1, t2);
	}
	CYBOZU_BENCH_C("Fp::add", C, Fp::add, x, x, y);
	CYBOZU_BENCH_C("Fp::sub", C, Fp::sub, x, x, y);
	CYBOZU_BENCH_C("Fp::mul", C, Fp::mul, x, x, y);
	CYBOZU_BENCH_C("Fp::sqr", C, Fp::sqr, x, x);
	CYBOZU_BENCH_C("Fp::inv", C, Fp::inv, x, x);
	CYBOZU_BENCH_C("Fp::pow", C, Fp::pow, x, x, x);
ccc_mul=0;
ccc_sqr=0;
	CYBOZU_BENCH_C("pow2", C, pow2, x, x, x);
printf("mul=%d sqr=%d\n", ccc_mul, ccc_sqr);
ccc_mul=0;
ccc_sqr=0;
	CYBOZU_BENCH_C("pow3", C, pow3, x, x, x);
printf("mul=%d sqr=%d\n", ccc_mul, ccc_sqr);
}

CYBOZU_TEST_AUTO(main)
{
	const struct {
		const char *name;
		const char *pStr;
	} tbl[] = {
		{ "secp256k1p", mcl::ecparam::secp256k1.p },
		{ "secp256k1r", mcl::ecparam::secp256k1.n },
		{ "bn254r", "0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d" },
		{ "bn254p", "0x2523648240000001ba344d80000000086121000000000013a700000000000013" },
		{ "bls12_381p", "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" },
		{ "bls12_381r", "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab" },
	};
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
		bench(tbl[i].name, tbl[i].pStr);
	}
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _CHART2_DLG_INSERT_ERRORBARS_HXX
#define _CHART2_DLG_INSERT_ERRORBARS_HXX

#include <vcl/dialog.hxx>
#include <vcl/button.hxx>
#include <svl/itemset.hxx>
#include <memory>
#include <com/sun/star/frame/XModel.hpp>

#include "res_ErrorBar.hxx"

//.............................................................................
namespace chart
{
//.............................................................................

class InsertErrorBarsDialog : public ModalDialog
{
public:
    InsertErrorBarsDialog( Window* pParent, const SfxItemSet& rMyAttrs,
                           const ::com::sun::star::uno::Reference<
                               ::com::sun::star::chart2::XChartDocument > & xChartDocument,
                           ErrorBarResources::tErrorBarType eType = ErrorBarResources::ERROR_BAR_Y );
    virtual ~InsertErrorBarsDialog();

    void SetAxisMinorStepWidthForErrorBarDecimals( double fMinorStepWidth );

    static double getAxisMinorStepWidthForErrorBarDecimals(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::frame::XModel >& xChartModel,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XInterface >& xChartView,
        const ::rtl::OUString& rSelectedObjectCID );

    void FillItemSet( SfxItemSet& rOutAttrs );
    virtual void DataChanged( const DataChangedEvent& rDCEvt );

private:
    const SfxItemSet & rInAttrs;

    OKButton          aBtnOK;
    CancelButton      aBtnCancel;
    HelpButton        aBtnHelp;

    ::std::auto_ptr< ErrorBarResources >    m_apErrorBarResources;
};

//.............................................................................
} //namespace chart
//.............................................................................

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Remove default values in InsertErrorBarsDialog constructor.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _CHART2_DLG_INSERT_ERRORBARS_HXX
#define _CHART2_DLG_INSERT_ERRORBARS_HXX

#include <vcl/dialog.hxx>
#include <vcl/button.hxx>
#include <svl/itemset.hxx>
#include <memory>
#include <com/sun/star/frame/XModel.hpp>

#include "res_ErrorBar.hxx"

//.............................................................................
namespace chart
{
//.............................................................................

class InsertErrorBarsDialog : public ModalDialog
{
public:
    InsertErrorBarsDialog( Window* pParent, const SfxItemSet& rMyAttrs,
                           const ::com::sun::star::uno::Reference<
                               ::com::sun::star::chart2::XChartDocument > & xChartDocument,
                           ErrorBarResources::tErrorBarType eType );
    virtual ~InsertErrorBarsDialog();

    void SetAxisMinorStepWidthForErrorBarDecimals( double fMinorStepWidth );

    static double getAxisMinorStepWidthForErrorBarDecimals(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::frame::XModel >& xChartModel,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XInterface >& xChartView,
        const ::rtl::OUString& rSelectedObjectCID );

    void FillItemSet( SfxItemSet& rOutAttrs );
    virtual void DataChanged( const DataChangedEvent& rDCEvt );

private:
    const SfxItemSet & rInAttrs;

    OKButton          aBtnOK;
    CancelButton      aBtnCancel;
    HelpButton        aBtnHelp;

    ::std::auto_ptr< ErrorBarResources >    m_apErrorBarResources;
};

//.............................................................................
} //namespace chart
//.............................................................................

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*
 * Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
 * and other libmdbx authors: please see AUTHORS file.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
 */

#include "test.h"

#include <pthread.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

struct shared_t {
  pthread_barrier_t barrier;
  pthread_mutex_t mutex;
  size_t conds_size;
  pthread_cond_t conds[1];
};

static shared_t *shared;

void osal_wait4barrier(void) {
  assert(shared != nullptr && shared != MAP_FAILED);
  int rc = pthread_barrier_wait(&shared->barrier);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    failure_perror("pthread_barrier_wait(shared)", rc);
  }
}

void osal_setup(const std::vector<actor_config> &actors) {
  assert(shared == nullptr);

  pthread_mutexattr_t mutexattr;
  int rc = pthread_mutexattr_init(&mutexattr);
  if (rc)
    failure_perror("pthread_mutexattr_init()", rc);
  rc = pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
  if (rc)
    failure_perror("pthread_mutexattr_setpshared()", rc);

  pthread_barrierattr_t barrierattr;
  rc = pthread_barrierattr_init(&barrierattr);
  if (rc)
    failure_perror("pthread_barrierattr_init()", rc);
  rc = pthread_barrierattr_setpshared(&barrierattr, PTHREAD_PROCESS_SHARED);
  if (rc)
    failure_perror("pthread_barrierattr_setpshared()", rc);

  pthread_condattr_t condattr;
  rc = pthread_condattr_init(&condattr);
  if (rc)
    failure_perror("pthread_condattr_init()", rc);
  rc = pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED);
  if (rc)
    failure_perror("pthread_condattr_setpshared()", rc);

  shared = (shared_t *)mmap(
      nullptr, sizeof(shared_t) + actors.size() * sizeof(pthread_cond_t),
      PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  if (MAP_FAILED == (void *)shared)
    failure_perror("mmap(shared_conds)", errno);

  rc = pthread_mutex_init(&shared->mutex, &mutexattr);
  if (rc)
    failure_perror("pthread_mutex_init(shared)", rc);

  rc = pthread_barrier_init(&shared->barrier, &barrierattr, actors.size() + 1);
  if (rc)
    failure_perror("pthread_barrier_init(shared)", rc);

  const size_t n = actors.size() + 1;
  for (size_t i = 0; i < n; ++i) {
    pthread_cond_t *event = &shared->conds[i];
    rc = pthread_cond_init(event, &condattr);
    if (rc)
      failure_perror("pthread_cond_init(shared)", rc);
    log_trace("osal_setup: event(shared pthread_cond) %" PRIuPTR " -> %p", i,
              event);
  }
  shared->conds_size = actors.size() + 1;

  pthread_barrierattr_destroy(&barrierattr);
  pthread_condattr_destroy(&condattr);
  pthread_mutexattr_destroy(&mutexattr);
}

void osal_broadcast(unsigned id) {
  assert(shared != nullptr && shared != MAP_FAILED);
  log_trace("osal_broadcast: event %u", id);
  if (id >= shared->conds_size)
    failure("osal_broadcast: id > limit");
  int rc = pthread_cond_broadcast(shared->conds + id);
  if (rc)
    failure_perror("sem_post(shared)", rc);
}

int osal_waitfor(unsigned id) {
  assert(shared != nullptr && shared != MAP_FAILED);

  log_trace("osal_waitfor: event %u", id);
  if (id >= shared->conds_size)
    failure("osal_waitfor: id > limit");

  int rc = pthread_mutex_lock(&shared->mutex);
  if (rc != 0)
    failure_perror("pthread_mutex_lock(shared)", rc);

  rc = pthread_cond_wait(shared->conds + id, &shared->mutex);
  if (rc && rc != EINTR)
    failure_perror("pthread_cond_wait(shared)", rc);

  rc = pthread_mutex_unlock(&shared->mutex);
  if (rc != 0)
    failure_perror("pthread_mutex_unlock(shared)", rc);

  return (rc == 0) ? true : false;
}

//-----------------------------------------------------------------------------

const std::string
actor_config::osal_serialize(simple_checksum &checksum) const {
  (void)checksum;
  /* not used in workload, but just for testing */
  return "unix.fork";
}

bool actor_config::osal_deserialize(const char *str, const char *end,
                                    simple_checksum &checksum) {
  (void)checksum;
  /* not used in workload, but just for testing */
  return strncmp(str, "unix.fork", 9) == 0 && str + 9 == end;
}

//-----------------------------------------------------------------------------

static std::unordered_map<pid_t, actor_status> childs;

static void handler_SIGCHLD(int unused) { (void)unused; }

mdbx_pid_t osal_getpid(void) { return getpid(); }

int osal_delay(unsigned seconds) { return sleep(seconds) ? errno : 0; }

int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) {
  if (childs.empty())
    signal(SIGCHLD, handler_SIGCHLD);

  pid = fork();

  if (pid == 0) {
    const bool result = test_execute(config);
    exit(result ? EXIT_SUCCESS : EXIT_FAILURE);
  }

  if (pid < 0)
    return errno;

  log_trace("osal_actor_start: fork pid %i for %u", pid, config.actor_id);
  childs[pid] = as_running;
  return 0;
}

actor_status osal_actor_info(const mdbx_pid_t pid) { return childs.at(pid); }

void osal_killall_actors(void) {
  for (auto &pair : childs) {
    kill(pair.first, SIGKILL);
    pair.second = as_killed;
  }
}

int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) {
retry:
  int status, options = WNOHANG;
#ifdef WUNTRACED
  options |= WUNTRACED;
#endif
#ifdef WCONTINUED
  options |= WCONTINUED;
#endif
  pid = waitpid(0, &status, options);

  if (pid > 0) {
    if (WIFEXITED(status))
      childs[pid] =
          (WEXITSTATUS(status) == EXIT_SUCCESS) ? as_successful : as_failed;
    else if (WIFSIGNALED(status) || WCOREDUMP(status))
      childs[pid] = as_killed;
    else if (WIFSTOPPED(status))
      childs[pid] = as_debuging;
    else if (WIFCONTINUED(status))
      childs[pid] = as_running;
    else {
      assert(false);
    }
    return 0;
  }

  if (pid == 0) {
    if (timeout && sleep(timeout))
      goto retry;
    return 0;
  }

  switch (errno) {
  case EINTR:
    pid = 0;
    return 0;

  case ECHILD:
  default:
    pid = 0;
    return errno;
  }
}

void osal_yield(void) {
  if (sched_yield())
    failure_perror("sched_yield()", errno);
}

void osal_udelay(unsigned us) {
  chrono::time until, now = chrono::now_motonic();
  until.fixedpoint = now.fixedpoint + chrono::from_us(us).fixedpoint;
  struct timespec ts;

  static unsigned threshold_us;
  if (threshold_us == 0) {
    if (clock_getres(CLOCK_PROCESS_CPUTIME_ID, &ts)) {
      int rc = errno;
      failure_perror("clock_getres(CLOCK_PROCESS_CPUTIME_ID)", rc);
    }
    chrono::time threshold = chrono::from_timespec(ts);
    assert(threshold.seconds() == 0);

    threshold_us = chrono::fractional2us(threshold.fractional);
    if (threshold_us < 1000)
      threshold_us = 1000;
  }

  ts.tv_sec = ts.tv_nsec = 0;
  if (us > threshold_us) {
    ts.tv_sec = us / 1000000u;
    ts.tv_nsec = (us % 1000000u) * 1000u;
  }

  do {
    if (us > threshold_us) {
      if (nanosleep(&ts, &ts)) {
        int rc = errno;
        /* if (rc == EINTR) { ... } ? */
        failure_perror("usleep()", rc);
      }
      us = ts.tv_sec * 1000000u + ts.tv_nsec / 1000u;
    }
    cpu_relax();

    now = chrono::now_motonic();
  } while (until.fixedpoint > now.fixedpoint);
}

bool osal_istty(int fd) { return isatty(fd) == 1; }

std::string osal_tempdir(void) {
  const char *tempdir = getenv("TMPDIR");
  if (!tempdir)
    tempdir = getenv("TMP");
  if (!tempdir)
    tempdir = getenv("TEMPDIR");
  if (!tempdir)
    tempdir = getenv("TEMP");
  if (tempdir) {
    std::string dir(tempdir);
    if (!dir.empty() && dir.at(dir.length() - 1) != '/')
      dir.append("/");
    return dir;
  }
  if (access("/dev/shm/", R_OK | W_OK | X_OK) == 0)
    return "/dev/shm/";
  return "";
}
<commit_msg>mdbx-test: fix sleep/child-signal handling.<commit_after>/*
 * Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
 * and other libmdbx authors: please see AUTHORS file.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
 */

#include "test.h"

#include <pthread.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

struct shared_t {
  pthread_barrier_t barrier;
  pthread_mutex_t mutex;
  size_t conds_size;
  pthread_cond_t conds[1];
};

static shared_t *shared;

void osal_wait4barrier(void) {
  assert(shared != nullptr && shared != MAP_FAILED);
  int rc = pthread_barrier_wait(&shared->barrier);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    failure_perror("pthread_barrier_wait(shared)", rc);
  }
}

void osal_setup(const std::vector<actor_config> &actors) {
  assert(shared == nullptr);

  pthread_mutexattr_t mutexattr;
  int rc = pthread_mutexattr_init(&mutexattr);
  if (rc)
    failure_perror("pthread_mutexattr_init()", rc);
  rc = pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
  if (rc)
    failure_perror("pthread_mutexattr_setpshared()", rc);

  pthread_barrierattr_t barrierattr;
  rc = pthread_barrierattr_init(&barrierattr);
  if (rc)
    failure_perror("pthread_barrierattr_init()", rc);
  rc = pthread_barrierattr_setpshared(&barrierattr, PTHREAD_PROCESS_SHARED);
  if (rc)
    failure_perror("pthread_barrierattr_setpshared()", rc);

  pthread_condattr_t condattr;
  rc = pthread_condattr_init(&condattr);
  if (rc)
    failure_perror("pthread_condattr_init()", rc);
  rc = pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED);
  if (rc)
    failure_perror("pthread_condattr_setpshared()", rc);

  shared = (shared_t *)mmap(
      nullptr, sizeof(shared_t) + actors.size() * sizeof(pthread_cond_t),
      PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  if (MAP_FAILED == (void *)shared)
    failure_perror("mmap(shared_conds)", errno);

  rc = pthread_mutex_init(&shared->mutex, &mutexattr);
  if (rc)
    failure_perror("pthread_mutex_init(shared)", rc);

  rc = pthread_barrier_init(&shared->barrier, &barrierattr, actors.size() + 1);
  if (rc)
    failure_perror("pthread_barrier_init(shared)", rc);

  const size_t n = actors.size() + 1;
  for (size_t i = 0; i < n; ++i) {
    pthread_cond_t *event = &shared->conds[i];
    rc = pthread_cond_init(event, &condattr);
    if (rc)
      failure_perror("pthread_cond_init(shared)", rc);
    log_trace("osal_setup: event(shared pthread_cond) %" PRIuPTR " -> %p", i,
              event);
  }
  shared->conds_size = actors.size() + 1;

  pthread_barrierattr_destroy(&barrierattr);
  pthread_condattr_destroy(&condattr);
  pthread_mutexattr_destroy(&mutexattr);
}

void osal_broadcast(unsigned id) {
  assert(shared != nullptr && shared != MAP_FAILED);
  log_trace("osal_broadcast: event %u", id);
  if (id >= shared->conds_size)
    failure("osal_broadcast: id > limit");
  int rc = pthread_cond_broadcast(shared->conds + id);
  if (rc)
    failure_perror("sem_post(shared)", rc);
}

int osal_waitfor(unsigned id) {
  assert(shared != nullptr && shared != MAP_FAILED);

  log_trace("osal_waitfor: event %u", id);
  if (id >= shared->conds_size)
    failure("osal_waitfor: id > limit");

  int rc = pthread_mutex_lock(&shared->mutex);
  if (rc != 0)
    failure_perror("pthread_mutex_lock(shared)", rc);

  rc = pthread_cond_wait(shared->conds + id, &shared->mutex);
  if (rc && rc != EINTR)
    failure_perror("pthread_cond_wait(shared)", rc);

  rc = pthread_mutex_unlock(&shared->mutex);
  if (rc != 0)
    failure_perror("pthread_mutex_unlock(shared)", rc);

  return (rc == 0) ? true : false;
}

//-----------------------------------------------------------------------------

const std::string
actor_config::osal_serialize(simple_checksum &checksum) const {
  (void)checksum;
  /* not used in workload, but just for testing */
  return "unix.fork";
}

bool actor_config::osal_deserialize(const char *str, const char *end,
                                    simple_checksum &checksum) {
  (void)checksum;
  /* not used in workload, but just for testing */
  return strncmp(str, "unix.fork", 9) == 0 && str + 9 == end;
}

//-----------------------------------------------------------------------------

static std::unordered_map<pid_t, actor_status> childs;

static void handler_SIGCHLD(int unused) { (void)unused; }

mdbx_pid_t osal_getpid(void) { return getpid(); }

int osal_delay(unsigned seconds) { return sleep(seconds) ? errno : 0; }

int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) {
  if (childs.empty())
    signal(SIGCHLD, handler_SIGCHLD);

  pid = fork();

  if (pid == 0) {
    const bool result = test_execute(config);
    exit(result ? EXIT_SUCCESS : EXIT_FAILURE);
  }

  if (pid < 0)
    return errno;

  log_trace("osal_actor_start: fork pid %i for %u", pid, config.actor_id);
  childs[pid] = as_running;
  return 0;
}

actor_status osal_actor_info(const mdbx_pid_t pid) { return childs.at(pid); }

void osal_killall_actors(void) {
  for (auto &pair : childs) {
    kill(pair.first, SIGKILL);
    pair.second = as_killed;
  }
}

int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) {
  struct timespec ts;
  ts.tv_nsec = 0;
  ts.tv_sec = timeout;
retry:
  int status, options = WNOHANG;
#ifdef WUNTRACED
  options |= WUNTRACED;
#endif
#ifdef WCONTINUED
  options |= WCONTINUED;
#endif
  pid = waitpid(0, &status, options);

  if (pid > 0) {
    if (WIFEXITED(status))
      childs[pid] =
          (WEXITSTATUS(status) == EXIT_SUCCESS) ? as_successful : as_failed;
    else if (WIFSIGNALED(status) || WCOREDUMP(status))
      childs[pid] = as_killed;
    else if (WIFSTOPPED(status))
      childs[pid] = as_debuging;
    else if (WIFCONTINUED(status))
      childs[pid] = as_running;
    else {
      assert(false);
    }
    return 0;
  }

  if (pid == 0) {
    /* child still running */
    if (ts.tv_sec == 0 && ts.tv_nsec == 0)
      ts.tv_nsec = 1;
    if (nanosleep(&ts, &ts) == 0) {
      /* timeout and no signal fomr child */
      pid = 0;
      return 0;
    }
    if (errno == EINTR)
      goto retry;
  }

  switch (errno) {
  case EINTR:
    pid = 0;
    return 0;

  case ECHILD:
  default:
    pid = 0;
    return errno;
  }
}

void osal_yield(void) {
  if (sched_yield())
    failure_perror("sched_yield()", errno);
}

void osal_udelay(unsigned us) {
  chrono::time until, now = chrono::now_motonic();
  until.fixedpoint = now.fixedpoint + chrono::from_us(us).fixedpoint;
  struct timespec ts;

  static unsigned threshold_us;
  if (threshold_us == 0) {
    if (clock_getres(CLOCK_PROCESS_CPUTIME_ID, &ts)) {
      int rc = errno;
      failure_perror("clock_getres(CLOCK_PROCESS_CPUTIME_ID)", rc);
    }
    chrono::time threshold = chrono::from_timespec(ts);
    assert(threshold.seconds() == 0);

    threshold_us = chrono::fractional2us(threshold.fractional);
    if (threshold_us < 1000)
      threshold_us = 1000;
  }

  ts.tv_sec = ts.tv_nsec = 0;
  if (us > threshold_us) {
    ts.tv_sec = us / 1000000u;
    ts.tv_nsec = (us % 1000000u) * 1000u;
  }

  do {
    if (us > threshold_us) {
      if (nanosleep(&ts, &ts)) {
        int rc = errno;
        /* if (rc == EINTR) { ... } ? */
        failure_perror("usleep()", rc);
      }
      us = ts.tv_sec * 1000000u + ts.tv_nsec / 1000u;
    }
    cpu_relax();

    now = chrono::now_motonic();
  } while (until.fixedpoint > now.fixedpoint);
}

bool osal_istty(int fd) { return isatty(fd) == 1; }

std::string osal_tempdir(void) {
  const char *tempdir = getenv("TMPDIR");
  if (!tempdir)
    tempdir = getenv("TMP");
  if (!tempdir)
    tempdir = getenv("TEMPDIR");
  if (!tempdir)
    tempdir = getenv("TEMP");
  if (tempdir) {
    std::string dir(tempdir);
    if (!dir.empty() && dir.at(dir.length() - 1) != '/')
      dir.append("/");
    return dir;
  }
  if (access("/dev/shm/", R_OK | W_OK | X_OK) == 0)
    return "/dev/shm/";
  return "";
}
<|endoftext|>


<commit_before><commit_msg>Protect against setting an iterator before begin().<commit_after><|endoftext|>


<commit_before>#include <iostream>
#include <CL/cl.hpp>
#include <string>
#include <vector>

using namespace std;

int main (int argc, char* argv[])
{
    //read input commandline arguments
    for (int i = 1; i < argc; ++i)
    {
        if (std::string(argv[i]) == "-a")
            {
                //initialise desired accuracy variable according to commandline argument -a
                //or if no argument is given, set default value
                int accuracy = 90;
            }
        if (std::string(argv[i]) == "-p")
            {
                //initialise maximum polygons variable according to commandline argument -p
                //or if no argument is given, set default value
                int polygons = 50;
            }
        if (std::string(argv[i]) == "-v")
            {
                //initialise maximum verices per polygon variable according to commandline argument -v
                //or if no argument is given, set default value
                int vertices = 6;
            }
    }

    //read specified input image file

    //initialise variables
	class DNA
	{
		public:
		string genome;
        int polygons;
        int vertices;
        polygon[polygons];

	}
    class polygon;
    {
        public:
        int x[vertices];
        int y[vertices];
        int R;
        int G;
        int B;
        int alpha;
    }
    //initialise opencl device
    //get all platforms (drivers)
    std::vector<cl::Platform> all_platforms;
    cl::Platform::get(&all_platforms);
    if(all_platforms.size()==0){
        std::cout<<" No platforms found. Check OpenCL installation!\n";
        exit(1);
    }
    cl::Platform default_platform=all_platforms[0];
    std::cout << "Using platform: "<<default_platform.getInfo<CL_PLATFORM_NAME>()<<"\n";

    //get default device of the default platform
    std::vector<cl::Device> all_devices;
    default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices);
    if(all_devices.size()==0){
        std::cout<<" No devices found. Check OpenCL installation!\n";
        exit(1);
    }
    cl::Device default_device=all_devices[0];
    std::cout<< "Using device: "<<default_device.getInfo<CL_DEVICE_NAME>()<<"\n";

    cl::Context context({default_device});

    cl::Program::Sources sources;

    //initialise DNA with a random seed
    leaderDNA = seedDNA();
    //run render loop until desired accuracy is reached
    while (leaderaccuracy<accuracy)
        {
            //mutate from the leaderDNA
            mutatedDNA = mutateDNA(leaderDNA)
            //compute fitness of mutation vs leaderDNA
            //check if it is fitter, if so overwrite leaderDNA
            if (computefitness() == 1)
            {
                //overwrite leaderDNA
            }
        }
    //perform final render, output svg and raster image
    saverender(leaderDNA);
}
int computefitnesspercent (DNA, originalimage)
{
    //compute what % match DNA is to original image
}
int computefitness (DNA, originalimage)
{
	//compute the fitness of input DNA, i.e. how close is it to original image?

    //read leader dna

    //compare input dna to leader dna to find changed polygons
    compareDNA(leaderDNA,DNA);
    //create bounding box containing changed polygons

    //render leader dna within bounding box
    leaderrender = renderDNA(leaderDNA,boundx,boundy);
    //render input dna within bounding box
    inputrender = renderDNA(DNA,boundx,boundy);
    //compare leader and input dna rendered bounding boxes
    compareimage(leaderrender,inputrender);
    //returns 1 if input dna is fitter than leader dna, else returns 0
}
int seedDNA()
{
    //create a random seed dna
}
int compareDNA(DNA0,DNA1)
{
    //compare DNA0 to DNA1 to find changed polygons
}
int compareimage(image0,image1)
{
    //compare two raster images, return 1 if image1 fitter than image0, else return 0
    char *img1data, *img2data, fname[15];
    int s, n = 0, y = 0;

    sprintf(fname, "photo%d.bmp", p - 1);
    cout << "\n" << fname;
    ifstream img1(fname, ios::in|ios::binary|ios::ate);
    sprintf(fname, "photo%d.bmp", p);
    cout << "\n" << fname;
    ifstream img2(fname, ios::in|ios::binary|ios::ate);

    if (img1.is_open() && img2.is_open())
    {
        s = (int)img1.tellg();
        img1data = new char [s];
        img1.seekg (0, ios::beg);
        img1.read (img1data, s);
        img1.close();

        img2data = new char [s];
        img2.seekg (0, ios::beg);
        img2.read (img2data, s);
        img2.close();
    }

    for(int i=0; i<s; i++)
        if (img1data[i]==img2data[i]) y++;

    return (y);
}

int renderDNA (shape_t * DNA, cairo_t * cr)
{
	//render input DNA to a raster image and svg

    //render to raster image
    cairo_set_source_rgb(cr, 1, 1, 1);
    cairo_rectangle(cr, 0, 0, WIDTH, HEIGHT);
    cairo_fill(cr);
    for(int i = 0; i < NUM_SHAPES; i++)
        draw_shape(dna, cr, i);
    //render to svg
}

void draw_shape(shape_t * dna, cairo_t * cr, int i)
{
	//draw an individual shape within a DNA strand
    cairo_set_line_width(cr, 0);
    shape_t * shape = &dna[i];
    cairo_set_source_rgba(cr, shape->r, shape->g, shape->b, shape->a);
    cairo_move_to(cr, shape->points[0].x, shape->points[0].y);
    for(int j = 1; j < NUM_POINTS; j++)
        cairo_line_to(cr, shape->points[j].x, shape->points[j].y);
    cairo_fill(cr);
}

}

int mutateDNA (DNA,mutationtype)
{
	//mutate input DNA randomly according to mutation type
	    mutated_shape = RANDINT(NUM_SHAPES);
    double roulette = RANDDOUBLE(2.8);
    double drastic = RANDDOUBLE(2);

    // mutate color
    if(roulette<1)
    {
        if(dna_test[mutated_shape].a < 0.01 // completely transparent shapes are stupid
                || roulette<0.25)
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].a += RANDDOUBLE(0.1);
                dna_test[mutated_shape].a = CLAMP(dna_test[mutated_shape].a, 0.0, 1.0);
            }
            else
                dna_test[mutated_shape].a = RANDDOUBLE(1.0);
        }
        else if(roulette<0.50)
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].r += RANDDOUBLE(0.1);
                dna_test[mutated_shape].r = CLAMP(dna_test[mutated_shape].r, 0.0, 1.0);
            }
            else
                dna_test[mutated_shape].r = RANDDOUBLE(1.0);
        }
        else if(roulette<0.75)
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].g += RANDDOUBLE(0.1);
                dna_test[mutated_shape].g = CLAMP(dna_test[mutated_shape].g, 0.0, 1.0);
            }
            else
                dna_test[mutated_shape].g = RANDDOUBLE(1.0);
        }
        else
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].b += RANDDOUBLE(0.1);
                dna_test[mutated_shape].b = CLAMP(dna_test[mutated_shape].b, 0.0, 1.0);
            }
            else
                dna_test[mutated_shape].b = RANDDOUBLE(1.0);
        }
    }

    // mutate shape
    else if(roulette < 2.0)
    {
        int point_i = RANDINT(NUM_POINTS);
        if(roulette<1.5)
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].points[point_i].x += (int)RANDDOUBLE(WIDTH/10.0);
                dna_test[mutated_shape].points[point_i].x = CLAMP(dna_test[mutated_shape].points[point_i].x, 0, WIDTH-1);
            }
            else
                dna_test[mutated_shape].points[point_i].x = RANDDOUBLE(WIDTH);
        }
        else
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].points[point_i].y += (int)RANDDOUBLE(HEIGHT/10.0);
                dna_test[mutated_shape].points[point_i].y = CLAMP(dna_test[mutated_shape].points[point_i].y, 0, HEIGHT-1);
            }
            else
                dna_test[mutated_shape].points[point_i].y = RANDDOUBLE(HEIGHT);
        }
    }

    // mutate stacking
    else
    {
        int destination = RANDINT(NUM_SHAPES);
        shape_t s = dna_test[mutated_shape];
        dna_test[mutated_shape] = dna_test[destination];
        dna_test[destination] = s;
        return destination;
    }
    return -1;

}
}

int saveDNA(DNA)
{
	int result;

	while(1)
	{
		// start by writing a temp file.

		pFile = fopen ("volution.dna.temp","w");
		fprintf (pFile, DNA);
		fclose (pFile);

		// Then rename the real backup to a secondary backup.

		result = rename("volution.dna","volution_2.dna");

		// Then rename the temp file to the primary backup

		result = rename("volution.dna.temp","volution.dna");

		// Then delete the temp file

		result = remove("volution.dna.temp");

		//sleep for 30 seconds.

		sleep(30000);
	}
}

int saverender(DNA)
{
    //render DNA and save resulting image to disk as .svg file and raster image (.png)

    //render image from DNA
    renderDNA(DNA);
    //save resultant image to disk as svg and png files
}
<commit_msg>fitness function improvements<commit_after>#include <iostream>
#include <CL/cl.hpp>
#include <string>
#include <vector>

using namespace std;

int main (int argc, char* argv[])
{
    //read input commandline arguments
    for (int i = 1; i < argc; ++i)
    {
        if (std::string(argv[i]) == "-a")
            {
                //initialise desired accuracy variable according to commandline argument -a
                //or if no argument is given, set default value
                int accuracy = 90;
            }
        if (std::string(argv[i]) == "-p")
            {
                //initialise maximum polygons variable according to commandline argument -p
                //or if no argument is given, set default value
                int polygons = 50;
            }
        if (std::string(argv[i]) == "-v")
            {
                //initialise maximum verices per polygon variable according to commandline argument -v
                //or if no argument is given, set default value
                int vertices = 6;
            }
    }

    //read specified input image file

    //initialise variables
	class DNA
	{
		public:
		string genome;
        int polygons;
        int vertices;
        polygon[polygons];

	}
    class polygon;
    {
        public:
        int x[vertices];
        int y[vertices];
        int R;
        int G;
        int B;
        int alpha;
    }
    //initialise opencl device
    //get all platforms (drivers)
    std::vector<cl::Platform> all_platforms;
    cl::Platform::get(&all_platforms);
    if(all_platforms.size()==0){
        std::cout<<" No platforms found. Check OpenCL installation!\n";
        exit(1);
    }
    cl::Platform default_platform=all_platforms[0];
    std::cout << "Using platform: "<<default_platform.getInfo<CL_PLATFORM_NAME>()<<"\n";

    //get default device of the default platform
    std::vector<cl::Device> all_devices;
    default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices);
    if(all_devices.size()==0){
        std::cout<<" No devices found. Check OpenCL installation!\n";
        exit(1);
    }
    cl::Device default_device=all_devices[0];
    std::cout<< "Using device: "<<default_device.getInfo<CL_DEVICE_NAME>()<<"\n";

    cl::Context context({default_device});

    cl::Program::Sources sources;

    //initialise DNA with a random seed
    leaderDNA = seedDNA();
    //run render loop until desired accuracy is reached
    while (leaderaccuracy<accuracy)
        {
            //mutate from the leaderDNA
            mutatedDNA = mutateDNA(leaderDNA)
            //compute fitness of mutation vs leaderDNA
            //check if it is fitter, if so overwrite leaderDNA
            if (computefitness(leaderDNA,mutatedDNA) == 1)
            {
                //overwrite leaderDNA
                leaderDNA = mutatedDNA;
            }
        }
    //perform final render, output svg and raster image
    saverender(leaderDNA);
}
int computefitnesspercent (DNA, originalimage)
{
    //compute what % match DNA is to original image
}
int computefitness (DNA0, DNA1)
{
	//compute the fitness of input DNA, i.e. how close is it to original image?

    //read leader dna

    //compare input dna to leader dna to find changed polygons
    compareDNA(leaderDNA,DNA);
    //create bounding box containing changed polygons

    //render leader dna within bounding box
    leaderrender = renderDNA(leaderDNA,boundx,boundy);
    //render input dna within bounding box
    inputrender = renderDNA(DNA,boundx,boundy);
    //compare leader and input dna rendered bounding boxes
    compareimage(leaderrender,inputrender);
    //returns 1 if dna1 is fitter than dna0, else returns 0
}
int seedDNA()
{
    //create a random seed dna
}
int compareDNA(DNA0,DNA1)
{
    //compare DNA0 to DNA1 to find changed polygons
}
int compareimage(image0,image1)
{
    //compare two raster images, return 1 if image1 fitter than image0, else return 0
    char *img1data, *img2data, fname[15];
    int s, n = 0, y = 0;

    sprintf(fname, "photo%d.bmp", p - 1);
    cout << "\n" << fname;
    ifstream img1(fname, ios::in|ios::binary|ios::ate);
    sprintf(fname, "photo%d.bmp", p);
    cout << "\n" << fname;
    ifstream img2(fname, ios::in|ios::binary|ios::ate);

    if (img1.is_open() && img2.is_open())
    {
        s = (int)img1.tellg();
        img1data = new char [s];
        img1.seekg (0, ios::beg);
        img1.read (img1data, s);
        img1.close();

        img2data = new char [s];
        img2.seekg (0, ios::beg);
        img2.read (img2data, s);
        img2.close();
    }

    for(int i=0; i<s; i++)
        if (img1data[i]==img2data[i]) y++;

    return (y);
}

int renderDNA (shape_t * DNA, cairo_t * cr)
{
	//render input DNA to a raster image and svg

    //render to raster image
    cairo_set_source_rgb(cr, 1, 1, 1);
    cairo_rectangle(cr, 0, 0, WIDTH, HEIGHT);
    cairo_fill(cr);
    for(int i = 0; i < NUM_SHAPES; i++)
        draw_shape(dna, cr, i);
    //render to svg
}

void draw_shape(shape_t * dna, cairo_t * cr, int i)
{
	//draw an individual shape within a DNA strand
    cairo_set_line_width(cr, 0);
    shape_t * shape = &dna[i];
    cairo_set_source_rgba(cr, shape->r, shape->g, shape->b, shape->a);
    cairo_move_to(cr, shape->points[0].x, shape->points[0].y);
    for(int j = 1; j < NUM_POINTS; j++)
        cairo_line_to(cr, shape->points[j].x, shape->points[j].y);
    cairo_fill(cr);
}

}

int mutateDNA (DNA,mutationtype)
{
	//mutate input DNA randomly according to mutation type
	    mutated_shape = RANDINT(NUM_SHAPES);
    double roulette = RANDDOUBLE(2.8);
    double drastic = RANDDOUBLE(2);

    // mutate color
    if(roulette<1)
    {
        if(dna_test[mutated_shape].a < 0.01 // completely transparent shapes are stupid
                || roulette<0.25)
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].a += RANDDOUBLE(0.1);
                dna_test[mutated_shape].a = CLAMP(dna_test[mutated_shape].a, 0.0, 1.0);
            }
            else
                dna_test[mutated_shape].a = RANDDOUBLE(1.0);
        }
        else if(roulette<0.50)
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].r += RANDDOUBLE(0.1);
                dna_test[mutated_shape].r = CLAMP(dna_test[mutated_shape].r, 0.0, 1.0);
            }
            else
                dna_test[mutated_shape].r = RANDDOUBLE(1.0);
        }
        else if(roulette<0.75)
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].g += RANDDOUBLE(0.1);
                dna_test[mutated_shape].g = CLAMP(dna_test[mutated_shape].g, 0.0, 1.0);
            }
            else
                dna_test[mutated_shape].g = RANDDOUBLE(1.0);
        }
        else
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].b += RANDDOUBLE(0.1);
                dna_test[mutated_shape].b = CLAMP(dna_test[mutated_shape].b, 0.0, 1.0);
            }
            else
                dna_test[mutated_shape].b = RANDDOUBLE(1.0);
        }
    }

    // mutate shape
    else if(roulette < 2.0)
    {
        int point_i = RANDINT(NUM_POINTS);
        if(roulette<1.5)
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].points[point_i].x += (int)RANDDOUBLE(WIDTH/10.0);
                dna_test[mutated_shape].points[point_i].x = CLAMP(dna_test[mutated_shape].points[point_i].x, 0, WIDTH-1);
            }
            else
                dna_test[mutated_shape].points[point_i].x = RANDDOUBLE(WIDTH);
        }
        else
        {
            if(drastic < 1)
            {
                dna_test[mutated_shape].points[point_i].y += (int)RANDDOUBLE(HEIGHT/10.0);
                dna_test[mutated_shape].points[point_i].y = CLAMP(dna_test[mutated_shape].points[point_i].y, 0, HEIGHT-1);
            }
            else
                dna_test[mutated_shape].points[point_i].y = RANDDOUBLE(HEIGHT);
        }
    }

    // mutate stacking
    else
    {
        int destination = RANDINT(NUM_SHAPES);
        shape_t s = dna_test[mutated_shape];
        dna_test[mutated_shape] = dna_test[destination];
        dna_test[destination] = s;
        return destination;
    }
    return -1;

}
}

int saveDNA(DNA)
{
	int result;

	while(1)
	{
		// start by writing a temp file.

		pFile = fopen ("volution.dna.temp","w");
		fprintf (pFile, DNA);
		fclose (pFile);

		// Then rename the real backup to a secondary backup.

		result = rename("volution.dna","volution_2.dna");

		// Then rename the temp file to the primary backup

		result = rename("volution.dna.temp","volution.dna");

		// Then delete the temp file

		result = remove("volution.dna.temp");

		//sleep for 30 seconds.

		sleep(30000);
	}
}

int saverender(DNA)
{
    //render DNA and save resulting image to disk as .svg file and raster image (.png)

    //render image from DNA
    renderDNA(DNA);
    //save resultant image to disk as svg and png files
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2004 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    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 General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */
#ifdef HAVE_CVS_IDENT
#ident "$Id: event.cc,v 1.20 2005/06/22 00:04:49 steve Exp $"
#endif

# include  "event.h"
# include  "compile.h"
# include  "vthread.h"
# include  "schedule.h"
# include  "vpi_priv.h"

# include  <string.h>
# include  <assert.h>
# include  <stdlib.h>
#ifdef HAVE_MALLOC_H
# include  <malloc.h>
#endif

void waitable_hooks_s::run_waiting_threads_()
{
      if (threads == 0)
	    return;

      vthread_t tmp = threads;
      threads = 0;
      vthread_schedule_list(tmp);
}

inline vvp_fun_edge::edge_t VVP_EDGE(vvp_bit4_t from, vvp_bit4_t to)
{
      return 1 << ((from << 2) | to);
}

const vvp_fun_edge::edge_t vvp_edge_posedge
      = VVP_EDGE(BIT4_0,BIT4_1)
      | VVP_EDGE(BIT4_0,BIT4_X)
      | VVP_EDGE(BIT4_0,BIT4_Z)
      | VVP_EDGE(BIT4_X,BIT4_1)
      | VVP_EDGE(BIT4_Z,BIT4_1)
      ;

const vvp_fun_edge::edge_t vvp_edge_negedge
      = VVP_EDGE(BIT4_1,BIT4_0)
      | VVP_EDGE(BIT4_1,BIT4_X)
      | VVP_EDGE(BIT4_1,BIT4_Z)
      | VVP_EDGE(BIT4_X,BIT4_0)
      | VVP_EDGE(BIT4_Z,BIT4_0)
      ;

const vvp_fun_edge::edge_t vvp_edge_none    = 0;

vvp_fun_edge::vvp_fun_edge(edge_t e)
: edge_(e)
{
      bits_[0] = BIT4_X;
      bits_[1] = BIT4_X;
      bits_[2] = BIT4_X;
      bits_[3] = BIT4_X;
}

vvp_fun_edge::~vvp_fun_edge()
{
}

void vvp_fun_edge::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
	/* See what kind of edge this represents. */
      edge_t mask = VVP_EDGE(bits_[port.port()], bit.value(0));

	/* Save the current input for the next time around. */
      bits_[port.port()] = bit.value(0);

      if ((edge_ == vvp_edge_none) || (edge_ & mask)) {
	    run_waiting_threads_();

	    vvp_net_t*net = port.ptr();
	    vvp_send_vec4(net->out, bit);
      }
}

vvp_fun_anyedge::vvp_fun_anyedge()
{
}

vvp_fun_anyedge::~vvp_fun_anyedge()
{
}

void vvp_fun_anyedge::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
      unsigned pdx = port.port();
      bool flag = false;

      if (bits_[pdx].size() != bit.size()) {
	    flag = true;

      } else {
	    for (unsigned idx = 0 ;  idx < bit.size() ;  idx += 1) {
		  if (bits_[pdx].value(idx) != bit.value(idx)) {
			flag = true;
			break;
		  }
	    }
      }

      if (flag) {
	    bits_[pdx] = bit;
	    run_waiting_threads_();
	    vvp_net_t*net = port.ptr();
	    vvp_send_vec4(net->out, bit);
      }
}

vvp_fun_event_or::vvp_fun_event_or()
{
}

vvp_fun_event_or::~vvp_fun_event_or()
{
}

void vvp_fun_event_or::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
      run_waiting_threads_();
      vvp_net_t*net = port.ptr();
      vvp_send_vec4(net->out, bit);
}

vvp_named_event::vvp_named_event(struct __vpiHandle*h)
{
      handle_ = h;
}

vvp_named_event::~vvp_named_event()
{
}

void vvp_named_event::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
      run_waiting_threads_();
      vvp_net_t*net = port.ptr();
      vvp_send_vec4(net->out, bit);
}

/*
**  Create an event functor
**  edge:  compile_event(label, type, argc, argv)
**  or:    compile_event(label, NULL, argc, argv)
**
**  Named events are handled elsewhere.
*/

static void compile_event_or(char*label, unsigned argc, struct symb_s*argv);

void compile_event(char*label, char*type,
		   unsigned argc, struct symb_s*argv)
{
      vvp_net_fun_t*fun = 0;

      if (type == 0) {
	    compile_event_or(label, argc, argv);
	    return;
      }

      if (strcmp(type,"edge") == 0) {

	    free(type);
	    fun = new vvp_fun_anyedge;

      } else {

	    vvp_fun_edge::edge_t edge = vvp_edge_none;

	    if (strcmp(type,"posedge") == 0)
		  edge = vvp_edge_posedge;
	    else if (strcmp(type,"negedge") == 0)
		  edge = vvp_edge_negedge;

	    assert(argc <= 4);
	    free(type);

	    fun = new vvp_fun_edge(edge);
      }

      vvp_net_t* ptr = new vvp_net_t;
      ptr->fun = fun;

      define_functor_symbol(label, ptr);
      free(label);

      inputs_connect(ptr, argc, argv);
}

static void compile_event_or(char*label, unsigned argc, struct symb_s*argv)
{
      vvp_net_fun_t*fun = new vvp_fun_event_or;
      vvp_net_t* ptr = new vvp_net_t;
      ptr->fun = fun;

      define_functor_symbol(label, ptr);
      free(label);

	/* This is a very special case. Point all the source inputs to
	   the same input. It doesn't matter that the streams get
	   tangled because data values are irrelevant. */
      for (unsigned idx = 0 ;  idx < argc ;  idx += 1) {
	    input_connect(ptr, 0, argv[idx].text);
      }
}

/*
 * This handles the compile of named events. This functor has no
 * inputs, it is only accessed by behavioral trigger statements, which
 * in vvp are %set instructions.
 */
void compile_named_event(char*label, char*name)
{
      vvp_net_t*ptr = new vvp_net_t;

      vpiHandle obj = vpip_make_named_event(name, ptr);
      ptr->fun = new vvp_named_event(obj);

      define_functor_symbol(label, ptr);
      compile_vpi_symbol(label, obj);
      vpip_attach_to_current_scope(obj);

      free(label);
      free(name);
}

/*
 * $Log: event.cc,v $
 * Revision 1.20  2005/06/22 00:04:49  steve
 *  Reduce vvp_vector4 copies by using const references.
 *
 * Revision 1.19  2005/06/17 23:47:02  steve
 *  threads member for waitable_hook_s needs initailizing.
 *
 * Revision 1.18  2005/05/25 05:44:51  steve
 *  Handle event/or with specific, efficient nodes.
 *
 * Revision 1.17  2004/12/29 23:45:13  steve
 *  Add the part concatenation node (.concat).
 *
 *  Add a vvp_event_anyedge class to handle the special
 *  case of .event statements of edge type. This also
 *  frees the posedge/negedge types to handle all 4 inputs.
 *
 *  Implement table functor recv_vec4 method to receive
 *  and process vectors.
 *
 * Revision 1.16  2004/12/18 18:52:44  steve
 *  Rework named events and event/or.
 *
 * Revision 1.15  2004/12/11 02:31:29  steve
 *  Rework of internals to carry vectors through nexus instead
 *  of single bits. Make the ivl, tgt-vvp and vvp initial changes
 *  down this path.
 *
 */
<commit_msg> Callbacks for named event triggers.<commit_after>/*
 * Copyright (c) 2004 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    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 General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */
#ifdef HAVE_CVS_IDENT
#ident "$Id: event.cc,v 1.21 2006/02/21 04:57:26 steve Exp $"
#endif

# include  "event.h"
# include  "compile.h"
# include  "vthread.h"
# include  "schedule.h"
# include  "vpi_priv.h"

# include  <string.h>
# include  <assert.h>
# include  <stdlib.h>
#ifdef HAVE_MALLOC_H
# include  <malloc.h>
#endif

void waitable_hooks_s::run_waiting_threads_()
{
      if (threads == 0)
	    return;

      vthread_t tmp = threads;
      threads = 0;
      vthread_schedule_list(tmp);
}

inline vvp_fun_edge::edge_t VVP_EDGE(vvp_bit4_t from, vvp_bit4_t to)
{
      return 1 << ((from << 2) | to);
}

const vvp_fun_edge::edge_t vvp_edge_posedge
      = VVP_EDGE(BIT4_0,BIT4_1)
      | VVP_EDGE(BIT4_0,BIT4_X)
      | VVP_EDGE(BIT4_0,BIT4_Z)
      | VVP_EDGE(BIT4_X,BIT4_1)
      | VVP_EDGE(BIT4_Z,BIT4_1)
      ;

const vvp_fun_edge::edge_t vvp_edge_negedge
      = VVP_EDGE(BIT4_1,BIT4_0)
      | VVP_EDGE(BIT4_1,BIT4_X)
      | VVP_EDGE(BIT4_1,BIT4_Z)
      | VVP_EDGE(BIT4_X,BIT4_0)
      | VVP_EDGE(BIT4_Z,BIT4_0)
      ;

const vvp_fun_edge::edge_t vvp_edge_none    = 0;

vvp_fun_edge::vvp_fun_edge(edge_t e)
: edge_(e)
{
      bits_[0] = BIT4_X;
      bits_[1] = BIT4_X;
      bits_[2] = BIT4_X;
      bits_[3] = BIT4_X;
}

vvp_fun_edge::~vvp_fun_edge()
{
}

void vvp_fun_edge::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
	/* See what kind of edge this represents. */
      edge_t mask = VVP_EDGE(bits_[port.port()], bit.value(0));

	/* Save the current input for the next time around. */
      bits_[port.port()] = bit.value(0);

      if ((edge_ == vvp_edge_none) || (edge_ & mask)) {
	    run_waiting_threads_();

	    vvp_net_t*net = port.ptr();
	    vvp_send_vec4(net->out, bit);
      }
}

vvp_fun_anyedge::vvp_fun_anyedge()
{
}

vvp_fun_anyedge::~vvp_fun_anyedge()
{
}

void vvp_fun_anyedge::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
      unsigned pdx = port.port();
      bool flag = false;

      if (bits_[pdx].size() != bit.size()) {
	    flag = true;

      } else {
	    for (unsigned idx = 0 ;  idx < bit.size() ;  idx += 1) {
		  if (bits_[pdx].value(idx) != bit.value(idx)) {
			flag = true;
			break;
		  }
	    }
      }

      if (flag) {
	    bits_[pdx] = bit;
	    run_waiting_threads_();
	    vvp_net_t*net = port.ptr();
	    vvp_send_vec4(net->out, bit);
      }
}

vvp_fun_event_or::vvp_fun_event_or()
{
}

vvp_fun_event_or::~vvp_fun_event_or()
{
}

void vvp_fun_event_or::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
      run_waiting_threads_();
      vvp_net_t*net = port.ptr();
      vvp_send_vec4(net->out, bit);
}

vvp_named_event::vvp_named_event(struct __vpiHandle*h)
{
      handle_ = h;
}

vvp_named_event::~vvp_named_event()
{
}

void vvp_named_event::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
      run_waiting_threads_();
      vvp_net_t*net = port.ptr();
      vvp_send_vec4(net->out, bit);

      vpip_run_named_event_callbacks(handle_);
}

/*
**  Create an event functor
**  edge:  compile_event(label, type, argc, argv)
**  or:    compile_event(label, NULL, argc, argv)
**
**  Named events are handled elsewhere.
*/

static void compile_event_or(char*label, unsigned argc, struct symb_s*argv);

void compile_event(char*label, char*type,
		   unsigned argc, struct symb_s*argv)
{
      vvp_net_fun_t*fun = 0;

      if (type == 0) {
	    compile_event_or(label, argc, argv);
	    return;
      }

      if (strcmp(type,"edge") == 0) {

	    free(type);
	    fun = new vvp_fun_anyedge;

      } else {

	    vvp_fun_edge::edge_t edge = vvp_edge_none;

	    if (strcmp(type,"posedge") == 0)
		  edge = vvp_edge_posedge;
	    else if (strcmp(type,"negedge") == 0)
		  edge = vvp_edge_negedge;

	    assert(argc <= 4);
	    free(type);

	    fun = new vvp_fun_edge(edge);
      }

      vvp_net_t* ptr = new vvp_net_t;
      ptr->fun = fun;

      define_functor_symbol(label, ptr);
      free(label);

      inputs_connect(ptr, argc, argv);
}

static void compile_event_or(char*label, unsigned argc, struct symb_s*argv)
{
      vvp_net_fun_t*fun = new vvp_fun_event_or;
      vvp_net_t* ptr = new vvp_net_t;
      ptr->fun = fun;

      define_functor_symbol(label, ptr);
      free(label);

	/* This is a very special case. Point all the source inputs to
	   the same input. It doesn't matter that the streams get
	   tangled because data values are irrelevant. */
      for (unsigned idx = 0 ;  idx < argc ;  idx += 1) {
	    input_connect(ptr, 0, argv[idx].text);
      }
}

/*
 * This handles the compile of named events. This functor has no
 * inputs, it is only accessed by behavioral trigger statements, which
 * in vvp are %set instructions.
 */
void compile_named_event(char*label, char*name)
{
      vvp_net_t*ptr = new vvp_net_t;

      vpiHandle obj = vpip_make_named_event(name, ptr);
      ptr->fun = new vvp_named_event(obj);

      define_functor_symbol(label, ptr);
      compile_vpi_symbol(label, obj);
      vpip_attach_to_current_scope(obj);

      free(label);
      free(name);
}

/*
 * $Log: event.cc,v $
 * Revision 1.21  2006/02/21 04:57:26  steve
 *  Callbacks for named event triggers.
 *
 * Revision 1.20  2005/06/22 00:04:49  steve
 *  Reduce vvp_vector4 copies by using const references.
 *
 * Revision 1.19  2005/06/17 23:47:02  steve
 *  threads member for waitable_hook_s needs initailizing.
 *
 * Revision 1.18  2005/05/25 05:44:51  steve
 *  Handle event/or with specific, efficient nodes.
 *
 * Revision 1.17  2004/12/29 23:45:13  steve
 *  Add the part concatenation node (.concat).
 *
 *  Add a vvp_event_anyedge class to handle the special
 *  case of .event statements of edge type. This also
 *  frees the posedge/negedge types to handle all 4 inputs.
 *
 *  Implement table functor recv_vec4 method to receive
 *  and process vectors.
 *
 * Revision 1.16  2004/12/18 18:52:44  steve
 *  Rework named events and event/or.
 *
 * Revision 1.15  2004/12/11 02:31:29  steve
 *  Rework of internals to carry vectors through nexus instead
 *  of single bits. Make the ivl, tgt-vvp and vvp initial changes
 *  down this path.
 *
 */
<|endoftext|>


<commit_before>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */

#include <iostream>
#include "core/driver.h"
#include "core/modmanager.h"
#include "core/value.h"
#include "core/cstring.h"
#include "core/scope.h"
#include "modules/std/std_pkg.h"
#include "modules/db/db_pkg.h"
#include "core/user.h"

namespace clever {

/// Adds the available packages to be imported
void ModManager::init()
{
	addModule("std",   new modules::Std);
	addModule("db",	   new modules::Db);
	addModule("_user", m_user = new UserModule);
}

/// Performs shutdown operation
void ModManager::shutdown()
{
	std::vector<Type*> typevec;
	ModuleMap::const_iterator itm = m_mods.begin(), endm = m_mods.end();

	while (itm != endm) {
		TypeMap& types = itm->second->getTypes();
		TypeMap::const_iterator itt(types.begin()), ite(types.end());

		while (itt != ite) {
			itt->second->deallocMembers();
			typevec.push_back(itt->second);
			++itt;
		}

		clever_delete(itm->second);
		++itm;
	}

	std::for_each(typevec.begin(), typevec.end(), clever_delete<Type>);
}

/// Adds a new module
void ModManager::addModule(const std::string& name, Module* module)
{
	if (m_mods.find(name) != m_mods.end()) {
		//std::cerr << "Module `" << name << "' already added!" << std::endl;
		return;
	}

	m_mods.insert(ModulePair(name, module));
	module->init();
	module->setLoaded();

	//std::cout << "init " << module->getName() << std::endl;

	if (module->hasModules()) {
		ModuleMap& mods = module->getModules();
		ModuleMap::const_iterator it = mods.begin(), end = mods.end();

		while (it != end) {
			// @TODO(Felipe): recursivity
			m_mods.insert(ModulePair(it->first, it->second));
			++it;
		}
	}
}

/// Loads an specific module type
void ModManager::loadType(Scope* scope, Environment* env, const std::string& name,
	Type* type) const
{
	Value* tmp = new Value(type);

	scope->pushValue(CSTRING(name), tmp)->voffset = env->pushValue(tmp);

	type->init();
}

/// Loads an specific module function
void ModManager::loadFunction(Scope* scope, Environment* env, const CString* name,
	Function* func) const
{
	Value* fval = new Value();

	fval->setObj(CLEVER_FUNC_TYPE, func);

	scope->pushValue(name, fval)->voffset = env->pushValue(fval);
}

/// Loads a module if it is not already loaded
void ModManager::loadModule(Scope* scope, Environment* env, Module* module,
	ImportKind kind, const CString* name) const
{
	if (kind == ModManager::ALL && module->hasModules()) {
		ModuleMap& mods = module->getModules();
		ModuleMap::const_iterator it = mods.begin(), end = mods.end();

		while (it != end) {
			loadModule(scope, env, it->second, kind, NULL);
			++it;
		}
	}

	if (module->isLoaded()) {
		return;
	}

	module->init();
	module->setLoaded();

	//std::cout << "load " << module->getName() << std::endl;

	if (kind & ModManager::FUNCTION) {
		FunctionMap& funcs = module->getFunctions();

		if (name) {
			FunctionMap::const_iterator it = funcs.find(name);

			if (it == funcs.end()) {
				std::cerr << "Function `" << *name << "' not found!" << std::endl;
			} else {
				loadFunction(scope, env, it->first, it->second);
			}
		} else {
			FunctionMap::const_iterator itf(funcs.begin()),	endf(funcs.end());

			while (EXPECTED(itf != endf)) {
				loadFunction(scope, env, itf->first, itf->second);
				++itf;
			}
		}
	}

	if (kind & ModManager::TYPE) {
		TypeMap& types = module->getTypes();

		if (name) {
			TypeMap::const_iterator it = types.find(*name);

			if (it == types.end()) {
				std::cerr << "Type `" << *name << "' not found!" << std::endl;
			} else {
				loadType(scope, env, it->first, it->second);
			}
		} else {
			TypeMap::const_iterator itt(types.begin()), ite(types.end());

			while (EXPECTED(itt != ite)) {
				loadType(scope, env, itt->first, itt->second);
				++itt;
			}
		}
	}
}

/// Imports an userland module
ast::Node* ModManager::importFile(Scope* scope, Environment* env,
	const std::string& module, ImportKind kind, const CString* name) const
{
	std::string mod_name = module;

	std::replace(mod_name.begin(), mod_name.end(), '.', '/');

	const std::string& fname = m_include_path + mod_name + ".clv";

	if (!m_driver->loadFile(fname)) {
		return m_driver->getCompiler().getAST();
	}

	return NULL;
}

/// Imports a module
ast::Node* ModManager::importModule(Scope* scope, Environment* env,
	const std::string& module, ImportKind kind, const CString* name) const
{
	ModuleMap::const_iterator it = m_mods.find(module);

	//std::cout << "imp " << module << std::endl;

	if (it == m_mods.end()) {
		ast::Node* tree;

		if ((tree = importFile(scope, env, module, kind, name)) == NULL) {
			std::cerr << "Module `" << module << "' not found!" << std::endl;
			return NULL;
		}
		return tree;
	}

	loadModule(scope, env, it->second, kind, name);

	return NULL;
}

} // clever
<commit_msg>- Make function related Values constant<commit_after>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */

#include <iostream>
#include "core/driver.h"
#include "core/modmanager.h"
#include "core/value.h"
#include "core/cstring.h"
#include "core/scope.h"
#include "modules/std/std_pkg.h"
#include "modules/db/db_pkg.h"
#include "core/user.h"

namespace clever {

/// Adds the available packages to be imported
void ModManager::init()
{
	addModule("std",   new modules::Std);
	addModule("db",	   new modules::Db);
	addModule("_user", m_user = new UserModule);
}

/// Performs shutdown operation
void ModManager::shutdown()
{
	std::vector<Type*> typevec;
	ModuleMap::const_iterator itm = m_mods.begin(), endm = m_mods.end();

	while (itm != endm) {
		TypeMap& types = itm->second->getTypes();
		TypeMap::const_iterator itt(types.begin()), ite(types.end());

		while (itt != ite) {
			itt->second->deallocMembers();
			typevec.push_back(itt->second);
			++itt;
		}

		clever_delete(itm->second);
		++itm;
	}

	std::for_each(typevec.begin(), typevec.end(), clever_delete<Type>);
}

/// Adds a new module
void ModManager::addModule(const std::string& name, Module* module)
{
	if (m_mods.find(name) != m_mods.end()) {
		//std::cerr << "Module `" << name << "' already added!" << std::endl;
		return;
	}

	m_mods.insert(ModulePair(name, module));
	module->init();
	module->setLoaded();

	//std::cout << "init " << module->getName() << std::endl;

	if (module->hasModules()) {
		ModuleMap& mods = module->getModules();
		ModuleMap::const_iterator it = mods.begin(), end = mods.end();

		while (it != end) {
			// @TODO(Felipe): recursivity
			m_mods.insert(ModulePair(it->first, it->second));
			++it;
		}
	}
}

/// Loads an specific module type
void ModManager::loadType(Scope* scope, Environment* env, const std::string& name,
	Type* type) const
{
	Value* tmp = new Value(type);

	scope->pushValue(CSTRING(name), tmp)->voffset = env->pushValue(tmp);

	type->init();
}

/// Loads an specific module function
void ModManager::loadFunction(Scope* scope, Environment* env, const CString* name,
	Function* func) const
{
	Value* fval = new Value();

	fval->setObj(CLEVER_FUNC_TYPE, func);
	fval->setConst(true);

	scope->pushValue(name, fval)->voffset = env->pushValue(fval);
}

/// Loads a module if it is not already loaded
void ModManager::loadModule(Scope* scope, Environment* env, Module* module,
	ImportKind kind, const CString* name) const
{
	if (kind == ModManager::ALL && module->hasModules()) {
		ModuleMap& mods = module->getModules();
		ModuleMap::const_iterator it = mods.begin(), end = mods.end();

		while (it != end) {
			loadModule(scope, env, it->second, kind, NULL);
			++it;
		}
	}

	if (module->isLoaded()) {
		return;
	}

	module->init();
	module->setLoaded();

	//std::cout << "load " << module->getName() << std::endl;

	if (kind & ModManager::FUNCTION) {
		FunctionMap& funcs = module->getFunctions();

		if (name) {
			FunctionMap::const_iterator it = funcs.find(name);

			if (it == funcs.end()) {
				std::cerr << "Function `" << *name << "' not found!" << std::endl;
			} else {
				loadFunction(scope, env, it->first, it->second);
			}
		} else {
			FunctionMap::const_iterator itf(funcs.begin()),	endf(funcs.end());

			while (EXPECTED(itf != endf)) {
				loadFunction(scope, env, itf->first, itf->second);
				++itf;
			}
		}
	}

	if (kind & ModManager::TYPE) {
		TypeMap& types = module->getTypes();

		if (name) {
			TypeMap::const_iterator it = types.find(*name);

			if (it == types.end()) {
				std::cerr << "Type `" << *name << "' not found!" << std::endl;
			} else {
				loadType(scope, env, it->first, it->second);
			}
		} else {
			TypeMap::const_iterator itt(types.begin()), ite(types.end());

			while (EXPECTED(itt != ite)) {
				loadType(scope, env, itt->first, itt->second);
				++itt;
			}
		}
	}
}

/// Imports an userland module
ast::Node* ModManager::importFile(Scope* scope, Environment* env,
	const std::string& module, ImportKind kind, const CString* name) const
{
	std::string mod_name = module;

	std::replace(mod_name.begin(), mod_name.end(), '.', '/');

	const std::string& fname = m_include_path + mod_name + ".clv";

	if (!m_driver->loadFile(fname)) {
		return m_driver->getCompiler().getAST();
	}

	return NULL;
}

/// Imports a module
ast::Node* ModManager::importModule(Scope* scope, Environment* env,
	const std::string& module, ImportKind kind, const CString* name) const
{
	ModuleMap::const_iterator it = m_mods.find(module);

	//std::cout << "imp " << module << std::endl;

	if (it == m_mods.end()) {
		ast::Node* tree;

		if ((tree = importFile(scope, env, module, kind, name)) == NULL) {
			std::cerr << "Module `" << module << "' not found!" << std::endl;
			return NULL;
		}
		return tree;
	}

	loadModule(scope, env, it->second, kind, name);

	return NULL;
}

} // clever
<|endoftext|>


<commit_before>//
// Copyright (C) 2007 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2007 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// $$
//////////////////////////////////////////////////////////////////////////////

#ifdef HAVE_ILBC // [

// SYSTEM INCLUDES
#include <limits.h>

// APPLICATION INCLUDES
#include "mp/MpdSipxILBC.h"
extern "C" {
#include <iLBC_define.h>
#include <iLBC_decode.h>
}

const MpCodecInfo MpdSipxILBC::smCodecInfo(
    SdpCodec::SDP_CODEC_ILBC,   // codecType
    "iLBC",                     // codecVersion
    8000,                       // samplingRate
    8,                          // numBitsPerSample (not used)
    1,                          // numChannels
    240,                        // interleaveBlockSize
    13334,                      // bitRate
    NO_OF_BYTES_30MS * 8,       // minPacketBits
    NO_OF_BYTES_30MS * 8,       // avgPacketBits
    NO_OF_BYTES_30MS * 8,       // maxPacketBits
    240,                        // numSamplesPerFrame
    6);                         // preCodecJitterBufferSize (should be adjusted)

MpdSipxILBC::MpdSipxILBC(int payloadType)
: MpDecoderBase(payloadType, &smCodecInfo)
, mpState(NULL)
{
}

MpdSipxILBC::~MpdSipxILBC()
{
   freeDecode();
}

OsStatus MpdSipxILBC::initDecode()
{
   if (mpState == NULL)
   {
      mpState = new iLBC_Dec_Inst_t();
      memset(mpState, 0, sizeof(*mpState));
      ::initDecode(mpState, 30, 1);
   }
   return OS_SUCCESS;
}

OsStatus MpdSipxILBC::freeDecode(void)
{
   delete mpState;
   mpState = NULL;
   return OS_SUCCESS;
}

int MpdSipxILBC::decode(const MpRtpBufPtr &pPacket,
                        unsigned decodedBufferLength,
                        MpAudioSample *samplesBuffer)
{
   // Check if available buffer size is enough for the packet.
   if (decodedBufferLength < 240)
   {
      osPrintf("MpdSipxILBC::decode: Jitter buffer overloaded. Glitch!\n");
      return 0;
   }

   // Decode incoming packet to temp buffer. If no packet - do PLC.
   float buffer[240];
   if (pPacket.isValid())
   {
      if (NO_OF_BYTES_30MS != pPacket->getPayloadSize())
      {
         osPrintf("MpdSipxILBC::decode: Payload size: %d!\n", pPacket->getPayloadSize());
         return 0;
      }

      // Packet data available. Decode it.
      iLBC_decode(buffer, (unsigned char*)pPacket->getDataPtr(), mpState, 1);
   }
   else
   {
      // Packet data is not available. Do PLC.
      iLBC_decode(buffer, NULL, mpState, 0);
   }

   for (int i = 0; i < 240; ++i)
   {
      float tmp = buffer[i];
      if (tmp > SHRT_MAX)
         tmp = SHRT_MAX;
      if (tmp < SHRT_MIN)
         tmp = SHRT_MIN;

      samplesBuffer[i] = MpAudioSample(tmp + 0.5f);
   }

   return 240;
}

#endif // HAVE_ILBC ]
<commit_msg>Remove dependency of MpdSipxILBC from <limits.h> and make it a litle bit more flexible.<commit_after>//
// Copyright (C) 2007 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2007 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// $$
//////////////////////////////////////////////////////////////////////////////

#ifdef HAVE_ILBC // [

// SYSTEM INCLUDES
// APPLICATION INCLUDES
#include "mp/MpdSipxILBC.h"
extern "C" {
#include <iLBC_define.h>
#include <iLBC_decode.h>
}

const MpCodecInfo MpdSipxILBC::smCodecInfo(
    SdpCodec::SDP_CODEC_ILBC,   // codecType
    "iLBC",                     // codecVersion
    8000,                       // samplingRate
    8,                          // numBitsPerSample (not used)
    1,                          // numChannels
    240,                        // interleaveBlockSize
    13334,                      // bitRate
    NO_OF_BYTES_30MS * 8,       // minPacketBits
    NO_OF_BYTES_30MS * 8,       // avgPacketBits
    NO_OF_BYTES_30MS * 8,       // maxPacketBits
    240,                        // numSamplesPerFrame
    6);                         // preCodecJitterBufferSize (should be adjusted)

MpdSipxILBC::MpdSipxILBC(int payloadType)
: MpDecoderBase(payloadType, &smCodecInfo)
, mpState(NULL)
{
}

MpdSipxILBC::~MpdSipxILBC()
{
   freeDecode();
}

OsStatus MpdSipxILBC::initDecode()
{
   if (mpState == NULL)
   {
      mpState = new iLBC_Dec_Inst_t();
      memset(mpState, 0, sizeof(*mpState));
      ::initDecode(mpState, 30, 1);
   }
   return OS_SUCCESS;
}

OsStatus MpdSipxILBC::freeDecode(void)
{
   delete mpState;
   mpState = NULL;
   return OS_SUCCESS;
}

int MpdSipxILBC::decode(const MpRtpBufPtr &pPacket,
                        unsigned decodedBufferLength,
                        MpAudioSample *samplesBuffer)
{
   // Check if available buffer size is enough for the packet.
   if (decodedBufferLength < 240)
   {
      osPrintf("MpdSipxILBC::decode: Jitter buffer overloaded. Glitch!\n");
      return 0;
   }

   // Decode incoming packet to temp buffer. If no packet - do PLC.
   float buffer[240];
   if (pPacket.isValid())
   {
      if (pPacket->getPayloadSize() != pPacket->getPayloadSize())
      {
         osPrintf("MpdSipxILBC::decode: Payload size: %d!\n", pPacket->getPayloadSize());
         return 0;
      }

      // Packet data available. Decode it.
      iLBC_decode(buffer, (unsigned char*)pPacket->getDataPtr(), mpState, 1);
   }
   else
   {
      // Packet data is not available. Do PLC.
      iLBC_decode(buffer, NULL, mpState, 0);
   }

   for (int i = 0; i < 240; ++i)
   {
      float tmp = buffer[i];
      if (tmp > MAX_SAMPLE)
         tmp = MAX_SAMPLE;
      if (tmp < MIN_SAMPLE)
         tmp = MIN_SAMPLE;

      samplesBuffer[i] = MpAudioSample(tmp + 0.5f);
   }

   return 240;
}

#endif // HAVE_ILBC ]
<|endoftext|>