<commit_before>#include <jni.h>
#include "jni-util.h"

extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*)
{
  JNIEnv* e;
  if (vm->GetEnv(reinterpret_cast<void**>(&e), JNI_VERSION_1_6) != JNI_OK) {
    return -1;
  }

  jclass c = e->FindClass("JNI");
  if (c == 0) {
    return -1;
  }

  e->SetStaticBooleanField(
      c, e->GetStaticFieldID(c, "onLoadCalled", "Z"), true);

  return JNI_VERSION_1_6;
}

extern "C" JNIEXPORT jdouble JNICALL Java_JNI_addDoubles(JNIEnv*,
                                                         jclass,
                                                         jdouble a1,
                                                         jdouble a2,
                                                         jdouble a3,
                                                         jdouble a4,
                                                         jdouble a5,
                                                         jdouble a6,
                                                         jdouble a7,
                                                         jdouble a8,
                                                         jdouble a9,
                                                         jdouble a10,
                                                         jdouble a11,
                                                         jdouble a12,
                                                         jdouble a13,
                                                         jdouble a14,
                                                         jdouble a15,
                                                         jdouble a16,
                                                         jdouble a17,
                                                         jdouble a18,
                                                         jdouble a19,
                                                         jdouble a20)
{
  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13
         + a14 + a15 + a16 + a17 + a18 + a19 + a20;
}

extern "C" JNIEXPORT jfloat JNICALL Java_JNI_addFloats(JNIEnv*,
                                                       jclass,
                                                       jfloat a1,
                                                       jfloat a2,
                                                       jfloat a3,
                                                       jfloat a4,
                                                       jfloat a5,
                                                       jfloat a6,
                                                       jfloat a7,
                                                       jfloat a8,
                                                       jfloat a9,
                                                       jfloat a10,
                                                       jfloat a11,
                                                       jfloat a12,
                                                       jfloat a13,
                                                       jfloat a14,
                                                       jfloat a15,
                                                       jfloat a16,
                                                       jfloat a17,
                                                       jfloat a18,
                                                       jfloat a19,
                                                       jfloat a20)
{
  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13
         + a14 + a15 + a16 + a17 + a18 + a19 + a20;
}

extern "C" JNIEXPORT jdouble JNICALL Java_JNI_addMix(JNIEnv*,
                                                     jclass,
                                                     jfloat a1,
                                                     jdouble a2,
                                                     jfloat a3,
                                                     jdouble a4,
                                                     jfloat a5,
                                                     jfloat a6,
                                                     jfloat a7,
                                                     jfloat a8,
                                                     jfloat a9,
                                                     jfloat a10,
                                                     jfloat a11,
                                                     jfloat a12,
                                                     jfloat a13,
                                                     jfloat a14,
                                                     jfloat a15,
                                                     jdouble a16,
                                                     jfloat a17,
                                                     jfloat a18,
                                                     jfloat a19,
                                                     jfloat a20)
{
  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13
         + a14 + a15 + a16 + a17 + a18 + a19 + a20;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary2(JNIEnv* e, jclass c, jobject o1, jobject o2, jobject o3,
                               jint i1, jint i2)
{
  return i1 + i2;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary3(JNIEnv* e, jclass c, jobject o1, jobject o2, jobject o3,
                               jint i1, jint i2, jint i3)
{
  return i1 + i2 + i3;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary4(JNIEnv* e, jclass c, jobject o1, jobject o2, jobject o3,
                               jint i1, jint i2, jint i3, jint i4)
{
  return i1 + i2 + i3 + i4;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary5(JNIEnv* e, jclass c, jobject o1, jobject o2, jobject o3,
                               jint i1, jint i2, jint i3, jint i4, jint i5)
{
  return i1 + i2 + i3 + i4 + i5;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary6(JNIEnv* e, jclass c, jobject o1, jobject o2, jobject o3,
                               jint i1, jint i2, jint i3, jint i4, jint i5, jint i6)
{
  return i1 + i2 + i3 + i4 + i5 + i6;
}

extern "C" JNIEXPORT jfloat JNICALL
    Java_JNI_doEcho__F(JNIEnv* e, jclass c, jfloat f)
{
  jvalue value;
  value.f = f;
  jvalue array[] = {value};
  return e->CallStaticFloatMethodA(
      c, e->GetStaticMethodID(c, "echo", "(F)F"), array);
}

extern "C" JNIEXPORT jdouble JNICALL
    Java_JNI_doEcho__D(JNIEnv* e, jclass c, jdouble f)
{
  jvalue value;
  value.d = f;
  jvalue array[] = {value};
  return e->CallStaticDoubleMethodA(
      c, e->GetStaticMethodID(c, "echo", "(D)D"), array);
}

extern "C" JNIEXPORT jlong JNICALL
    Java_JNI_fromReflectedMethod(JNIEnv* e, jclass, jobject method)
{
  return reinterpret_cast<uintptr_t>(e->FromReflectedMethod(method));
}

extern "C" JNIEXPORT jobject JNICALL
    Java_JNI_toReflectedMethod(JNIEnv* e,
                               jclass,
                               jclass c,
                               jlong id,
                               jboolean isStatic)
{
  return e->ToReflectedMethod(c, reinterpret_cast<jmethodID>(id), isStatic);
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_callStaticIntMethod(JNIEnv* e, jclass, jclass c, jlong id)
{
  return e->CallStaticIntMethod(c, reinterpret_cast<jmethodID>(id));
}

extern "C" JNIEXPORT jobject JNICALL
    Java_JNI_newObject(JNIEnv* e, jclass, jclass c, jlong id)
{
  return e->NewObject(c, reinterpret_cast<jmethodID>(id));
}

extern "C" JNIEXPORT jlong JNICALL
    Java_JNI_fromReflectedField(JNIEnv* e, jclass, jobject field)
{
  return reinterpret_cast<uintptr_t>(e->FromReflectedField(field));
}

extern "C" JNIEXPORT jobject JNICALL
    Java_JNI_toReflectedField(JNIEnv* e,
                              jclass,
                              jclass c,
                              jlong id,
                              jboolean isStatic)
{
  return e->ToReflectedField(c, reinterpret_cast<jfieldID>(id), isStatic);
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_getStaticIntField(JNIEnv* e, jclass, jclass c, jlong id)
{
  return e->GetStaticIntField(c, reinterpret_cast<jfieldID>(id));
}

extern "C" JNIEXPORT jobject JNICALL
    Java_JNI_testLocalRef(JNIEnv* e, jclass, jobject o)
{
  return e->NewLocalRef(o);
}

extern "C" JNIEXPORT jobject JNICALL
    Java_Buffers_allocateNative(JNIEnv* e, jclass, jint capacity)
{
  void* p = allocate(e, capacity);
  if (p == 0)
    return 0;

  return e->NewDirectByteBuffer(p, capacity);
}

extern "C" JNIEXPORT void JNICALL
    Java_Buffers_freeNative(JNIEnv* e, jclass, jobject b)
{
  free(e->GetDirectBufferAddress(b));
}
<commit_msg>fix for -Wunused-parameters<commit_after>#include <jni.h>
#include "jni-util.h"

extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*)
{
  JNIEnv* e;
  if (vm->GetEnv(reinterpret_cast<void**>(&e), JNI_VERSION_1_6) != JNI_OK) {
    return -1;
  }

  jclass c = e->FindClass("JNI");
  if (c == 0) {
    return -1;
  }

  e->SetStaticBooleanField(
      c, e->GetStaticFieldID(c, "onLoadCalled", "Z"), true);

  return JNI_VERSION_1_6;
}

extern "C" JNIEXPORT jdouble JNICALL Java_JNI_addDoubles(JNIEnv*,
                                                         jclass,
                                                         jdouble a1,
                                                         jdouble a2,
                                                         jdouble a3,
                                                         jdouble a4,
                                                         jdouble a5,
                                                         jdouble a6,
                                                         jdouble a7,
                                                         jdouble a8,
                                                         jdouble a9,
                                                         jdouble a10,
                                                         jdouble a11,
                                                         jdouble a12,
                                                         jdouble a13,
                                                         jdouble a14,
                                                         jdouble a15,
                                                         jdouble a16,
                                                         jdouble a17,
                                                         jdouble a18,
                                                         jdouble a19,
                                                         jdouble a20)
{
  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13
         + a14 + a15 + a16 + a17 + a18 + a19 + a20;
}

extern "C" JNIEXPORT jfloat JNICALL Java_JNI_addFloats(JNIEnv*,
                                                       jclass,
                                                       jfloat a1,
                                                       jfloat a2,
                                                       jfloat a3,
                                                       jfloat a4,
                                                       jfloat a5,
                                                       jfloat a6,
                                                       jfloat a7,
                                                       jfloat a8,
                                                       jfloat a9,
                                                       jfloat a10,
                                                       jfloat a11,
                                                       jfloat a12,
                                                       jfloat a13,
                                                       jfloat a14,
                                                       jfloat a15,
                                                       jfloat a16,
                                                       jfloat a17,
                                                       jfloat a18,
                                                       jfloat a19,
                                                       jfloat a20)
{
  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13
         + a14 + a15 + a16 + a17 + a18 + a19 + a20;
}

extern "C" JNIEXPORT jdouble JNICALL Java_JNI_addMix(JNIEnv*,
                                                     jclass,
                                                     jfloat a1,
                                                     jdouble a2,
                                                     jfloat a3,
                                                     jdouble a4,
                                                     jfloat a5,
                                                     jfloat a6,
                                                     jfloat a7,
                                                     jfloat a8,
                                                     jfloat a9,
                                                     jfloat a10,
                                                     jfloat a11,
                                                     jfloat a12,
                                                     jfloat a13,
                                                     jfloat a14,
                                                     jfloat a15,
                                                     jdouble a16,
                                                     jfloat a17,
                                                     jfloat a18,
                                                     jfloat a19,
                                                     jfloat a20)
{
  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13
         + a14 + a15 + a16 + a17 + a18 + a19 + a20;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary2(JNIEnv*, jclass, jobject, jobject, jobject,
                               jint i1, jint i2)
{
  return i1 + i2;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary3(JNIEnv*, jclass, jobject, jobject, jobject,
                               jint i1, jint i2, jint i3)
{
  return i1 + i2 + i3;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary4(JNIEnv*, jclass, jobject, jobject, jobject,
                               jint i1, jint i2, jint i3, jint i4)
{
  return i1 + i2 + i3 + i4;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary5(JNIEnv*, jclass, jobject, jobject, jobject,
                               jint i1, jint i2, jint i3, jint i4, jint i5)
{
  return i1 + i2 + i3 + i4 + i5;
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_addStackBoundary6(JNIEnv*, jclass, jobject, jobject, jobject,
                               jint i1, jint i2, jint i3, jint i4, jint i5, jint i6)
{
  return i1 + i2 + i3 + i4 + i5 + i6;
}

extern "C" JNIEXPORT jfloat JNICALL
    Java_JNI_doEcho__F(JNIEnv* e, jclass c, jfloat f)
{
  jvalue value;
  value.f = f;
  jvalue array[] = {value};
  return e->CallStaticFloatMethodA(
      c, e->GetStaticMethodID(c, "echo", "(F)F"), array);
}

extern "C" JNIEXPORT jdouble JNICALL
    Java_JNI_doEcho__D(JNIEnv* e, jclass c, jdouble f)
{
  jvalue value;
  value.d = f;
  jvalue array[] = {value};
  return e->CallStaticDoubleMethodA(
      c, e->GetStaticMethodID(c, "echo", "(D)D"), array);
}

extern "C" JNIEXPORT jlong JNICALL
    Java_JNI_fromReflectedMethod(JNIEnv* e, jclass, jobject method)
{
  return reinterpret_cast<uintptr_t>(e->FromReflectedMethod(method));
}

extern "C" JNIEXPORT jobject JNICALL
    Java_JNI_toReflectedMethod(JNIEnv* e,
                               jclass,
                               jclass c,
                               jlong id,
                               jboolean isStatic)
{
  return e->ToReflectedMethod(c, reinterpret_cast<jmethodID>(id), isStatic);
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_callStaticIntMethod(JNIEnv* e, jclass, jclass c, jlong id)
{
  return e->CallStaticIntMethod(c, reinterpret_cast<jmethodID>(id));
}

extern "C" JNIEXPORT jobject JNICALL
    Java_JNI_newObject(JNIEnv* e, jclass, jclass c, jlong id)
{
  return e->NewObject(c, reinterpret_cast<jmethodID>(id));
}

extern "C" JNIEXPORT jlong JNICALL
    Java_JNI_fromReflectedField(JNIEnv* e, jclass, jobject field)
{
  return reinterpret_cast<uintptr_t>(e->FromReflectedField(field));
}

extern "C" JNIEXPORT jobject JNICALL
    Java_JNI_toReflectedField(JNIEnv* e,
                              jclass,
                              jclass c,
                              jlong id,
                              jboolean isStatic)
{
  return e->ToReflectedField(c, reinterpret_cast<jfieldID>(id), isStatic);
}

extern "C" JNIEXPORT jint JNICALL
    Java_JNI_getStaticIntField(JNIEnv* e, jclass, jclass c, jlong id)
{
  return e->GetStaticIntField(c, reinterpret_cast<jfieldID>(id));
}

extern "C" JNIEXPORT jobject JNICALL
    Java_JNI_testLocalRef(JNIEnv* e, jclass, jobject o)
{
  return e->NewLocalRef(o);
}

extern "C" JNIEXPORT jobject JNICALL
    Java_Buffers_allocateNative(JNIEnv* e, jclass, jint capacity)
{
  void* p = allocate(e, capacity);
  if (p == 0)
    return 0;

  return e->NewDirectByteBuffer(p, capacity);
}

extern "C" JNIEXPORT void JNICALL
    Java_Buffers_freeNative(JNIEnv* e, jclass, jobject b)
{
  free(e->GetDirectBufferAddress(b));
}
<|endoftext|>


<commit_before>/*
 Hanoh Haim
 Cisco Systems, Inc.
*/

/*
Copyright (c) 2015-2015 Cisco Systems, Inc.

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.
*/

/*
 * This file is compiled only for simulation.
 * Since in simulation, we do not use DPDK libraries, all mbuf functions needed for simulation are duplictated here.
 *   with some small changes.
 */

#include "mbuf.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "sanb_atomic.h"

void rte_pktmbuf_detach(struct rte_mbuf *m);

rte_mempool_t * utl_rte_mempool_create_non_pkt(const char  *name,
                                               unsigned n,
                                               unsigned elt_size,
                                               unsigned cache_size,
                                               int socket_id){
    rte_mempool_t * p=new rte_mempool_t();
    assert(p);
    p->elt_size =elt_size;
    p->size=n;
    p->priv_size=0;
    p->magic=MAGIC0;
    p->magic2=MAGIC2;
    return p;
}

rte_mempool_t * utl_rte_mempool_create(const char  *name,
                                      unsigned n,
                                      unsigned elt_size,
                                      unsigned cache_size,
                                      int socket_id
                                       ){

    rte_mempool_t * p=new rte_mempool_t();
    assert(p);
    p->size=n;
    p->elt_size =elt_size;
    p->priv_size=sizeof(rte_mbuf_t); /* each pool has less memory */
    p->magic=MAGIC0;
    p->magic2=MAGIC2;
    return p;
}

void utl_rte_mempool_delete(rte_mempool_t * & pool){
    if (pool) {
        delete pool;
        pool=0;
    }
}

uint16_t rte_mbuf_refcnt_update(rte_mbuf_t *m, int16_t value)
{
    utl_rte_pktmbuf_check(m);
    m->refcnt_reserved = (uint16_t)(m->refcnt_reserved + value);
    assert(m->refcnt_reserved >= 0);
	return m->refcnt_reserved;
}

void rte_pktmbuf_reset(struct rte_mbuf *m)
{
    utl_rte_pktmbuf_check(m);
    m->next = NULL;
    m->pkt_len = 0;
    m->nb_segs = 1;
    m->in_port = 0xff;
    m->ol_flags = 0;

    #if RTE_PKTMBUF_HEADROOM > 0
    m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
            RTE_PKTMBUF_HEADROOM : m->buf_len;
    #else
    m->data_off = RTE_PKTMBUF_HEADROOM ;
    #endif

    m->data_len = 0;
}

rte_mbuf_t *rte_pktmbuf_alloc(rte_mempool_t *mp){

    uint16_t buf_len;

    utl_rte_check(mp);

    buf_len = mp->elt_size ;

    rte_mbuf_t *m =(rte_mbuf_t *)malloc(buf_len );
    assert(m);

    m->magic  = MAGIC0;
    m->magic2 = MAGIC2;
    m->pool   = mp;
    m->refcnt_reserved = 1;
    m->buf_len    = buf_len-(sizeof(rte_mbuf_t)+RTE_PKTMBUF_HEADROOM);
    m->buf_addr   =(char *)((char *)m+sizeof(rte_mbuf_t)+RTE_PKTMBUF_HEADROOM) ;

    rte_pktmbuf_reset(m);

    return (m);
}

void rte_pktmbuf_free_seg(rte_mbuf_t *m) {

    utl_rte_pktmbuf_check(m);

	if (rte_mbuf_refcnt_update(m, -1) == 0) {
        /* if this is an indirect mbuf, then
         *  - detach mbuf
         *  - free attached mbuf segment
         */

        if (RTE_MBUF_INDIRECT(m)) {
            struct rte_mbuf *md = RTE_MBUF_FROM_BADDR(m->buf_addr);
            rte_pktmbuf_detach(m);
            if (rte_mbuf_refcnt_update(md, -1) == 0)
                free(md);
        }
        free(m);
    }
}

void rte_pktmbuf_free(rte_mbuf_t *m){

    rte_mbuf_t *m_next;

    utl_rte_pktmbuf_check(m);

    while (m != NULL) {
        m_next = m->next;
        rte_pktmbuf_free_seg(m);
        m = m_next;
    }
}

static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
{
    struct rte_mbuf *m2 = (struct rte_mbuf *)m;
    utl_rte_pktmbuf_check(m);

    while (m2->next != NULL)
        m2 = m2->next;
    return m2;
}

char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
{
    void *tail;
    struct rte_mbuf *m_last;
    utl_rte_pktmbuf_check(m);

    m_last = rte_pktmbuf_lastseg(m);
    if (len > rte_pktmbuf_tailroom(m_last))
        return NULL;

    tail = (char*) m_last->buf_addr + m_last->data_len;
    m_last->data_len = (uint16_t)(m_last->data_len + len);
    m->pkt_len  = (m->pkt_len + len);
    return (char*) tail;
}

char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
{
    utl_rte_pktmbuf_check(m);

    if (len > m->data_len)
        return NULL;

    m->data_len = (uint16_t)(m->data_len - len);
    m->data_off += len;
    m->pkt_len  = (m->pkt_len - len);
    return (char *)m->buf_addr + m->data_off;
}

int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
{
    struct rte_mbuf *m_last;
        utl_rte_pktmbuf_check(m);

    m_last = rte_pktmbuf_lastseg(m);
    if (len > m_last->data_len)
        return -1;

    m_last->data_len = (uint16_t)(m_last->data_len - len);
    m->pkt_len  = (m->pkt_len - len);
    return 0;
}

int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
{
    return (m->nb_segs == 1);
}

static void
rte_pktmbuf_hexdump(const void *buf, unsigned int len)
{
    unsigned int i, out, ofs;
    const unsigned char *data = (unsigned char *)buf;
#define LINE_LEN 80
    char line[LINE_LEN];

    printf("  dump data at 0x%p, len=%u\n", data, len);
    ofs = 0;
    while (ofs < len) {
        out = snprintf(line, LINE_LEN, "  %08X", ofs);
        for (i = 0; ofs+i < len && i < 16; i++)
            out += snprintf(line+out, LINE_LEN - out, " %02X",
                    data[ofs+i]&0xff);
        for (; i <= 16; i++)
            out += snprintf(line+out, LINE_LEN - out, "   ");
        for (i = 0; ofs < len && i < 16; i++, ofs++) {
            unsigned char c = data[ofs];
            if (!isascii(c) || !isprint(c))
                c = '.';
            out += snprintf(line+out, LINE_LEN - out, "%c", c);
        }
        printf("%s\n", line);
    }
}

int rte_mempool_sc_get(struct rte_mempool *mp, void **obj_p){
    utl_rte_check(mp);
    uint16_t buf_len;
    buf_len = mp->elt_size ;
    *obj_p=(void *)::malloc(buf_len);
    return (0);
}

void rte_mempool_sp_put(struct rte_mempool *mp, void *obj){
    free(obj);
}

void rte_exit(int exit_code, const char *format, ...){
    exit(exit_code);
}

void
rte_pktmbuf_dump(const struct rte_mbuf *m, unsigned dump_len)
{
    unsigned int len;
    unsigned nb_segs;

    printf("dump mbuf at 0x%p, phys=0x%p, buf_len=%u\n",
           m, m->buf_addr, (unsigned)m->buf_len);
    printf("  pkt_len=%u,  nb_segs=%u, "
           "in_port=%u\n", m->pkt_len,
           (unsigned)m->nb_segs, (unsigned)m->in_port);
    nb_segs = m->nb_segs;

    while (m && nb_segs != 0) {

        printf("  segment at 0x%p, data=0x%p, data_len=%u\n",
               m, m->buf_addr, (unsigned)m->data_len);
        len = dump_len;
        if (len > m->data_len)
            len = m->data_len;

        if (len != 0)
            rte_pktmbuf_hexdump(rte_pktmbuf_mtod(m,char *), len);
        dump_len -= len;
        m = m->next;
        nb_segs --;
    }
}

void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
{

    rte_mbuf_refcnt_update(md, 1);
    mi->buf_addr = md->buf_addr;
    mi->buf_len = md->buf_len;
    mi->data_off = md->data_off;

    mi->next = NULL;
    mi->data_len = md->data_len;
    mi->pkt_len  = mi->data_len;
    mi->ol_flags = mi->ol_flags | IND_ATTACHED_MBUF;
    mi->nb_segs = 1;
}

void rte_pktmbuf_detach(struct rte_mbuf *m)
{
    const struct rte_mempool *mp = m->pool;
    void *buf = RTE_MBUF_TO_BADDR(m);
    uint32_t buf_len = mp->elt_size - sizeof(*m);

    m->buf_addr = buf;
    m->buf_len = (uint16_t)buf_len;

    #if RTE_PKTMBUF_HEADROOM > 0
    m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
            RTE_PKTMBUF_HEADROOM : m->buf_len;
    #else
    m->data_off = RTE_PKTMBUF_HEADROOM ;
    #endif

    m->data_len = 0;
	m->ol_flags = 0;
}

uint64_t rte_rand(void){
    return ( rand() );
}

#ifdef ONLY_A_TEST

#define CONST_NB_MBUF  2048
#define CONST_MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)

void test_pkt_mbuf(){

    rte_mempool_t * mp1=utl_rte_mempool_create("big-const",
                                          CONST_NB_MBUF,
                                          CONST_MBUF_SIZE,
                                          32);
    rte_mbuf_t * m1 = rte_pktmbuf_alloc(mp1);
    rte_mbuf_t * m2 = rte_pktmbuf_alloc(mp1);

    char *p=rte_pktmbuf_append(m1, 10);
    int i;

    for (i=0; i<10;i++) {
        p[i]=i;
    }

    p=rte_pktmbuf_append(m2, 10);

    for (i=0; i<10;i++) {
        p[i]=0x55+i;
    }

    rte_pktmbuf_dump(m1, m1->pkt_len);
    rte_pktmbuf_dump(m2, m1->pkt_len);

    rte_pktmbuf_free(m1);
    rte_pktmbuf_free(m2);
}

#endif
<commit_msg>TSO phase #2<commit_after>/*
 Hanoh Haim
 Cisco Systems, Inc.
*/

/*
Copyright (c) 2015-2015 Cisco Systems, Inc.

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.
*/

/*
 * This file is compiled only for simulation.
 * Since in simulation, we do not use DPDK libraries, all mbuf functions needed for simulation are duplictated here.
 *   with some small changes.
 */

#include "mbuf.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "sanb_atomic.h"

void rte_pktmbuf_detach(struct rte_mbuf *m);

rte_mempool_t * utl_rte_mempool_create_non_pkt(const char  *name,
                                               unsigned n,
                                               unsigned elt_size,
                                               unsigned cache_size,
                                               int socket_id){
    rte_mempool_t * p=new rte_mempool_t();
    assert(p);
    p->elt_size =elt_size;
    p->size=n;
    p->priv_size=0;
    p->magic=MAGIC0;
    p->magic2=MAGIC2;
    return p;
}

rte_mempool_t * utl_rte_mempool_create(const char  *name,
                                      unsigned n,
                                      unsigned elt_size,
                                      unsigned cache_size,
                                      int socket_id
                                       ){

    rte_mempool_t * p=new rte_mempool_t();
    assert(p);
    p->size=n;
    p->elt_size =elt_size;
    p->priv_size=sizeof(rte_mbuf_t); /* each pool has less memory */
    p->magic=MAGIC0;
    p->magic2=MAGIC2;
    return p;
}

void utl_rte_mempool_delete(rte_mempool_t * & pool){
    if (pool) {
        delete pool;
        pool=0;
    }
}

uint16_t rte_mbuf_refcnt_update(rte_mbuf_t *m, int16_t value)
{
    utl_rte_pktmbuf_check(m);
    m->refcnt_reserved = (uint16_t)(m->refcnt_reserved + value);
    assert(m->refcnt_reserved >= 0);
	return m->refcnt_reserved;
}

void rte_pktmbuf_reset(struct rte_mbuf *m)
{
    utl_rte_pktmbuf_check(m);
    m->next = NULL;
    m->pkt_len = 0;
    m->nb_segs = 1;
    m->in_port = 0xff;
    m->ol_flags = 0;
    m->tso_segsz=0;
    m->l2_len=0;
    m->l3_len=0;
    m->vlan_tci=0;

    #if RTE_PKTMBUF_HEADROOM > 0
    m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
            RTE_PKTMBUF_HEADROOM : m->buf_len;
    #else
    m->data_off = RTE_PKTMBUF_HEADROOM ;
    #endif

    m->data_len = 0;
}

rte_mbuf_t *rte_pktmbuf_alloc(rte_mempool_t *mp){

    uint16_t buf_len;

    utl_rte_check(mp);

    buf_len = mp->elt_size ;

    rte_mbuf_t *m =(rte_mbuf_t *)malloc(buf_len );
    assert(m);

    m->magic  = MAGIC0;
    m->magic2 = MAGIC2;
    m->pool   = mp;
    m->refcnt_reserved = 1;
    m->buf_len    = buf_len-(sizeof(rte_mbuf_t)+RTE_PKTMBUF_HEADROOM);
    m->buf_addr   =(char *)((char *)m+sizeof(rte_mbuf_t)+RTE_PKTMBUF_HEADROOM) ;

    rte_pktmbuf_reset(m);

    return (m);
}

void rte_pktmbuf_free_seg(rte_mbuf_t *m) {

    utl_rte_pktmbuf_check(m);

	if (rte_mbuf_refcnt_update(m, -1) == 0) {
        /* if this is an indirect mbuf, then
         *  - detach mbuf
         *  - free attached mbuf segment
         */

        if (RTE_MBUF_INDIRECT(m)) {
            struct rte_mbuf *md = RTE_MBUF_FROM_BADDR(m->buf_addr);
            rte_pktmbuf_detach(m);
            if (rte_mbuf_refcnt_update(md, -1) == 0)
                free(md);
        }
        free(m);
    }
}

void rte_pktmbuf_free(rte_mbuf_t *m){

    rte_mbuf_t *m_next;

    utl_rte_pktmbuf_check(m);

    while (m != NULL) {
        m_next = m->next;
        rte_pktmbuf_free_seg(m);
        m = m_next;
    }
}

static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
{
    struct rte_mbuf *m2 = (struct rte_mbuf *)m;
    utl_rte_pktmbuf_check(m);

    while (m2->next != NULL)
        m2 = m2->next;
    return m2;
}

char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
{
    void *tail;
    struct rte_mbuf *m_last;
    utl_rte_pktmbuf_check(m);

    m_last = rte_pktmbuf_lastseg(m);
    if (len > rte_pktmbuf_tailroom(m_last))
        return NULL;

    tail = (char*) m_last->buf_addr + m_last->data_len;
    m_last->data_len = (uint16_t)(m_last->data_len + len);
    m->pkt_len  = (m->pkt_len + len);
    return (char*) tail;
}

char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
{
    utl_rte_pktmbuf_check(m);

    if (len > m->data_len)
        return NULL;

    m->data_len = (uint16_t)(m->data_len - len);
    m->data_off += len;
    m->pkt_len  = (m->pkt_len - len);
    return (char *)m->buf_addr + m->data_off;
}

int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
{
    struct rte_mbuf *m_last;
        utl_rte_pktmbuf_check(m);

    m_last = rte_pktmbuf_lastseg(m);
    if (len > m_last->data_len)
        return -1;

    m_last->data_len = (uint16_t)(m_last->data_len - len);
    m->pkt_len  = (m->pkt_len - len);
    return 0;
}

int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
{
    return (m->nb_segs == 1);
}

static void
rte_pktmbuf_hexdump(const void *buf, unsigned int len)
{
    unsigned int i, out, ofs;
    const unsigned char *data = (unsigned char *)buf;
#define LINE_LEN 80
    char line[LINE_LEN];

    printf("  dump data at 0x%p, len=%u\n", data, len);
    ofs = 0;
    while (ofs < len) {
        out = snprintf(line, LINE_LEN, "  %08X", ofs);
        for (i = 0; ofs+i < len && i < 16; i++)
            out += snprintf(line+out, LINE_LEN - out, " %02X",
                    data[ofs+i]&0xff);
        for (; i <= 16; i++)
            out += snprintf(line+out, LINE_LEN - out, "   ");
        for (i = 0; ofs < len && i < 16; i++, ofs++) {
            unsigned char c = data[ofs];
            if (!isascii(c) || !isprint(c))
                c = '.';
            out += snprintf(line+out, LINE_LEN - out, "%c", c);
        }
        printf("%s\n", line);
    }
}

int rte_mempool_sc_get(struct rte_mempool *mp, void **obj_p){
    utl_rte_check(mp);
    uint16_t buf_len;
    buf_len = mp->elt_size ;
    *obj_p=(void *)::malloc(buf_len);
    return (0);
}

void rte_mempool_sp_put(struct rte_mempool *mp, void *obj){
    free(obj);
}

void rte_exit(int exit_code, const char *format, ...){
    exit(exit_code);
}

void
rte_pktmbuf_dump(const struct rte_mbuf *m, unsigned dump_len)
{
    unsigned int len;
    unsigned nb_segs;

    printf("dump mbuf at 0x%p, phys=0x%p, buf_len=%u\n",
           m, m->buf_addr, (unsigned)m->buf_len);
    printf("  pkt_len=%u,  nb_segs=%u, "
           "in_port=%u\n", m->pkt_len,
           (unsigned)m->nb_segs, (unsigned)m->in_port);
    nb_segs = m->nb_segs;

    while (m && nb_segs != 0) {

        printf("  segment at 0x%p, data=0x%p, data_len=%u\n",
               m, m->buf_addr, (unsigned)m->data_len);
        len = dump_len;
        if (len > m->data_len)
            len = m->data_len;

        if (len != 0)
            rte_pktmbuf_hexdump(rte_pktmbuf_mtod(m,char *), len);
        dump_len -= len;
        m = m->next;
        nb_segs --;
    }
}

void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
{

    rte_mbuf_refcnt_update(md, 1);
    mi->buf_addr = md->buf_addr;
    mi->buf_len = md->buf_len;
    mi->data_off = md->data_off;

    mi->next = NULL;
    mi->data_len = md->data_len;
    mi->pkt_len  = mi->data_len;
    mi->ol_flags = mi->ol_flags | IND_ATTACHED_MBUF;
    mi->nb_segs = 1;
}

void rte_pktmbuf_detach(struct rte_mbuf *m)
{
    const struct rte_mempool *mp = m->pool;
    void *buf = RTE_MBUF_TO_BADDR(m);
    uint32_t buf_len = mp->elt_size - sizeof(*m);

    m->buf_addr = buf;
    m->buf_len = (uint16_t)buf_len;

    #if RTE_PKTMBUF_HEADROOM > 0
    m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
            RTE_PKTMBUF_HEADROOM : m->buf_len;
    #else
    m->data_off = RTE_PKTMBUF_HEADROOM ;
    #endif

    m->data_len = 0;
	m->ol_flags = 0;
}

uint64_t rte_rand(void){
    return ( rand() );
}

#ifdef ONLY_A_TEST

#define CONST_NB_MBUF  2048
#define CONST_MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)

void test_pkt_mbuf(){

    rte_mempool_t * mp1=utl_rte_mempool_create("big-const",
                                          CONST_NB_MBUF,
                                          CONST_MBUF_SIZE,
                                          32);
    rte_mbuf_t * m1 = rte_pktmbuf_alloc(mp1);
    rte_mbuf_t * m2 = rte_pktmbuf_alloc(mp1);

    char *p=rte_pktmbuf_append(m1, 10);
    int i;

    for (i=0; i<10;i++) {
        p[i]=i;
    }

    p=rte_pktmbuf_append(m2, 10);

    for (i=0; i<10;i++) {
        p[i]=0x55+i;
    }

    rte_pktmbuf_dump(m1, m1->pkt_len);
    rte_pktmbuf_dump(m2, m1->pkt_len);

    rte_pktmbuf_free(m1);
    rte_pktmbuf_free(m2);
}

#endif
<|endoftext|>


<commit_before>#ifdef _WIN32

#include "platform.h"
#include "imgui.h"
#include <Windows.h>
#include <assert.h>
#include <iostream>
#include <stdint.h>
#include <winnls.h>

wchar_t *utf8_to_wide(const char *s) {
	size_t len = utf8len(s);
	wchar_t *buf = (wchar_t *)malloc(sizeof(wchar_t) * (1 + len));
	mbstowcs(buf, s, len);
	buf[len] = 0;
	return buf;
}

char *wide_to_utf8(const wchar_t *s) {
	size_t len = 0;
	wchar_t c;
	for (const wchar_t *ss = s; 0 != (c = *ss); ++ss) {
		if (c < 0x80) {
			len += 1;
		} else if (c < 0x800) {
			len += 2;
		} else if (c >= 0xd800 && c < 0xdc00) {
			// surrogate pair
			len += 4;
			++ss;
		} else if (c >= 0xdc00 && c < 0xe000) {
			// pair end -- invalid sequence
			return nullptr;
		} else {
			len += 3;
		}
	}
	char *buf = (char *)malloc(1 + len);
	wcstombs(buf, s, len);
	buf[len] = 0;
	return buf;
}

char *file_as_buffer(size_t *buffer_size, const char *utf8_filename) {
	wchar_t *wide_filename = utf8_to_wide(utf8_filename);
	HANDLE file = CreateFile(wide_filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
	                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	free(wide_filename);
	if (file == INVALID_HANDLE_VALUE) {
		*buffer_size = 0;
		return nullptr;
	}

	LARGE_INTEGER filesize;
	GetFileSizeEx(file, &filesize);
	uint32_t sz = (uint32_t)filesize.QuadPart;
	assert(filesize.QuadPart == sz);
	*buffer_size = sz;

	char *buf = (char *)malloc(sz);
	uint32_t numRead = 0;
	ReadFile(file, buf, sz, (LPDWORD)&numRead, NULL);
	assert(numRead == sz);

	return buf;
}

char *show_file_picker() {
	OPENFILENAME ofn;
	wchar_t filename[1024];
	filename[0] = 0;
	memset(&ofn, 0, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = (HWND)ImGui::GetIO().ImeWindowHandle;
	ofn.lpstrFilter = L"BRD Files\0*.brd\0All Files\0*.*\0\0";
	ofn.lpstrFile = filename;
	ofn.nMaxFile = 1024;
	if (GetOpenFileName(&ofn)) {
		return wide_to_utf8(filename);
	}
	return nullptr;
}

// Not caring about XP. If this is a concern, find a replacement for CompareStringEx()
const std::vector<char> load_font(const std::string &name) {
	std::vector<char> data;
	HFONT fontHandle;

	wchar_t *wname = utf8_to_wide(name.c_str());

	fontHandle = CreateFont(0, 0, 0, 0, 0, 0, 0, 0, 0, OUT_TT_ONLY_PRECIS, 0, 0, 0, wname);
	if (!fontHandle) {
		std::cerr << "CreateFont failed" << std::endl;
		free(wname);
		return data;
	}
	HDC hdc = ::CreateCompatibleDC(NULL);
	if (hdc != NULL) {
		::SelectObject(hdc, fontHandle);

		int ncount = ::GetTextFaceW(hdc, 0, nullptr);
		LPWSTR fname = new wchar_t[ncount];
		::GetTextFaceW(hdc, ncount, fname);

		if (!name.empty() &&
		    ::CompareStringEx(NULL, NORM_IGNORECASE, wname, name.size(), fname, ncount - 1, NULL,
		                      NULL, 0) != CSTR_EQUAL) { // We didn't get the font we requested
			free(wname);
			return data;
		}

		free(wname);

		const size_t size = ::GetFontData(hdc, 0, 0, NULL, 0);
		if (size > 0 && size != GDI_ERROR) {
			char *buffer = new char[size];
			if (::GetFontData(hdc, 0, 0, buffer, size) == size) {
				data = std::vector<char>(buffer, buffer + size);
			}
			delete[] buffer;
		}
		::DeleteDC(hdc);
	}
	DeleteObject(fontHandle);
	return data;
}

#endif // _WIN32
<commit_msg>Revert "Win32: search for TrueType fonts only"<commit_after>#ifdef _WIN32

#include "platform.h"
#include "imgui.h"
#include <Windows.h>
#include <assert.h>
#include <iostream>
#include <stdint.h>
#include <winnls.h>

wchar_t *utf8_to_wide(const char *s) {
	size_t len = utf8len(s);
	wchar_t *buf = (wchar_t *)malloc(sizeof(wchar_t) * (1 + len));
	mbstowcs(buf, s, len);
	buf[len] = 0;
	return buf;
}

char *wide_to_utf8(const wchar_t *s) {
	size_t len = 0;
	wchar_t c;
	for (const wchar_t *ss = s; 0 != (c = *ss); ++ss) {
		if (c < 0x80) {
			len += 1;
		} else if (c < 0x800) {
			len += 2;
		} else if (c >= 0xd800 && c < 0xdc00) {
			// surrogate pair
			len += 4;
			++ss;
		} else if (c >= 0xdc00 && c < 0xe000) {
			// pair end -- invalid sequence
			return nullptr;
		} else {
			len += 3;
		}
	}
	char *buf = (char *)malloc(1 + len);
	wcstombs(buf, s, len);
	buf[len] = 0;
	return buf;
}

char *file_as_buffer(size_t *buffer_size, const char *utf8_filename) {
	wchar_t *wide_filename = utf8_to_wide(utf8_filename);
	HANDLE file = CreateFile(wide_filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
	                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	free(wide_filename);
	if (file == INVALID_HANDLE_VALUE) {
		*buffer_size = 0;
		return nullptr;
	}

	LARGE_INTEGER filesize;
	GetFileSizeEx(file, &filesize);
	uint32_t sz = (uint32_t)filesize.QuadPart;
	assert(filesize.QuadPart == sz);
	*buffer_size = sz;

	char *buf = (char *)malloc(sz);
	uint32_t numRead = 0;
	ReadFile(file, buf, sz, (LPDWORD)&numRead, NULL);
	assert(numRead == sz);

	return buf;
}

char *show_file_picker() {
	OPENFILENAME ofn;
	wchar_t filename[1024];
	filename[0] = 0;
	memset(&ofn, 0, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = (HWND)ImGui::GetIO().ImeWindowHandle;
	ofn.lpstrFilter = L"BRD Files\0*.brd\0All Files\0*.*\0\0";
	ofn.lpstrFile = filename;
	ofn.nMaxFile = 1024;
	if (GetOpenFileName(&ofn)) {
		return wide_to_utf8(filename);
	}
	return nullptr;
}

// Not caring about XP. If this is a concern, find a replacement for CompareStringEx()
const std::vector<char> load_font(const std::string &name) {
	std::vector<char> data;
	HFONT fontHandle;

	wchar_t *wname = utf8_to_wide(name.c_str());

	fontHandle = CreateFont(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, name.empty() ? NULL : wname);
	if (!fontHandle) {
		std::cerr << "CreateFont failed" << std::endl;
		free(wname);
		return data;
	}
	HDC hdc = ::CreateCompatibleDC(NULL);
	if (hdc != NULL) {
		::SelectObject(hdc, fontHandle);

		int ncount = ::GetTextFaceW(hdc, 0, nullptr);
		LPWSTR fname = new wchar_t[ncount];
		::GetTextFaceW(hdc, ncount, fname);

		if (!name.empty() &&
		    ::CompareStringEx(NULL, NORM_IGNORECASE, wname, name.size(), fname, ncount - 1, NULL,
		                      NULL, 0) != CSTR_EQUAL) { // We didn't get the font we requested
			free(wname);
			return data;
		}

		free(wname);

		const size_t size = ::GetFontData(hdc, 0, 0, NULL, 0);
		if (size > 0 && size != GDI_ERROR) {
			char *buffer = new char[size];
			if (::GetFontData(hdc, 0, 0, buffer, size) == size) {
				data = std::vector<char>(buffer, buffer + size);
			}
			delete[] buffer;
		}
		::DeleteDC(hdc);
	}
	DeleteObject(fontHandle);
	return data;
}

#endif // _WIN32
<|endoftext|>


<commit_before>/*
** Copyright 2012-2013, 2021 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#include "com/centreon/process_manager.hh"
#include <sys/signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <algorithm>
#include <cassert>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include "com/centreon/exceptions/basic.hh"
#include "com/centreon/logging/logger.hh"
#include "com/centreon/process_listener.hh"

using namespace com::centreon;

// Default varibale.
static int const DEFAULT_TIMEOUT = 200;

/**
 *  Add process to the process manager.
 *
 *  @param[in] p    The process to manage.
 *  @param[in] obj  The object to notify.
 */
void process_manager::add(process* p) {
  // Check viability pointer.
  assert(p);

  // We lock _lock_processes before to avoid deadlocks
  std::lock_guard<std::mutex> lock(_lock_processes);

  // Monitor err/out output if necessary.
  if (p->_enable_stream[process::out])
    _processes_fd[p->_stream[process::out]] = p;
  if (p->_enable_stream[process::err])
    _processes_fd[p->_stream[process::err]] = p;

  // Add timeout to kill process if necessary.
  if (p->_timeout)
    _processes_timeout.insert({p->_timeout, p});

  // Need to update file descriptor list.
  _update = true;

  // Add pid process to use waitpid.
  _processes_pid[p->_process] = p;

  // write(_fds_exit[1], "up", 2);
}

/**
 *  Get instance of the process manager.
 *
 *  @return the process manager.
 */
process_manager& process_manager::instance() {
  static process_manager instance;
  return instance;
}

/**
 *  Default constructor. It is private. No need to call, we just use the static
 *  internal function instance().
 */
process_manager::process_manager()
    : _thread{nullptr}, _fds_size{0}, _update(true) {
  _fds.reserve(64);

  // Run process manager thread.
  _thread = new std::thread(&process_manager::_run, this);
}

/**
 *  Destructor.
 */
process_manager::~process_manager() noexcept {
  // Kill all running process.
  {
    std::lock_guard<std::mutex> lock(_lock_processes);
    for (auto it = _processes_pid.begin(), end = _processes_pid.end();
         it != end; ++it) {
      try {
        it->second->kill();
      } catch (const std::exception& e) {
        (void)e;
      }
    }
  }

  // Exit process manager thread.
  //_close(_fds_exit[1]);

  // Waiting the end of the process manager thread.
  _running = false;
  _thread->join();
  delete _thread;
  _thread = nullptr;

  {
    std::lock_guard<std::mutex> lock(_lock_processes);

    // Release memory.
    _fds.clear();

    // Waiting all process.
    int ret(0);
    int status(0);
    while ((ret = ::waitpid(-1, &status, 0)) > 0 || (ret && errno == EINTR))
      ;
  }
}

/**
 *  close syscall wrapper.
 *
 *  @param[in, out] fd The file descriptor to close.
 */
void process_manager::_close(int& fd) noexcept {
  if (fd >= 0) {
    while (::close(fd) < 0 && errno == EINTR)
      std::this_thread::yield();
  }
  fd = -1;
}

/**
 *  Close stream.
 *
 *  @param[in] fd  The file descriptor to close.
 */
void process_manager::_close_stream(int fd) noexcept {
  try {
    process* p;
    // Get process to link with fd and remove this
    // fd to the process manager.
    {
      std::lock_guard<std::mutex> lock(_lock_processes);
      _update = true;
      std::unordered_map<int, process*>::iterator it(_processes_fd.find(fd));
      if (it == _processes_fd.end()) {
        _update = true;
        throw basic_error() << "invalid fd: "
                               "not found into processes fd list";
      }
      p = it->second;
      _processes_fd.erase(it);
    }

    // Update process informations.
    p->do_close(fd);
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
}

/**
 *  Remove process from list of processes timeout.
 *
 *  @param[in] p The process to remove.
 */
void process_manager::_erase_timeout(process* p) {
  // Check process viability.
  if (!p || !p->_timeout)
    return;
  std::lock_guard<std::mutex> lock(_lock_processes);
  auto range = _processes_timeout.equal_range(p->_timeout);
  for (auto it = range.first; it != range.second; ++it) {
    if (it->second == p) {
      _processes_timeout.erase(it);
      break;
    }
  }
}

/**
 *  Kill process to reach the timeout.
 */
void process_manager::_kill_processes_timeout() noexcept {
  std::lock_guard<std::mutex> lock(_lock_processes);
  // Get the current time.
  std::time_t now(time(nullptr));

  // Kill process who timeout and remove it from timeout list.
  for (auto it = _processes_timeout.begin(), end = _processes_timeout.end();
       it != end && it->first <= now;) {
    process* p = it->second;
    try {
      p->kill();
    } catch (const std::exception& e) {
      log_error(logging::high) << e.what();
    }
    it = _processes_timeout.erase(it);
  }
}

/**
 *  Read stream.
 *
 *  @param[in] fd  The file descriptor to read.
 *
 *  @return Number of bytes read.
 */
uint32_t process_manager::_read_stream(int fd) noexcept {
  uint32_t size(0);
  try {
    process* p;
    // Get process to link with fd.
    {
      std::lock_guard<std::mutex> lock(_lock_processes);
      std::unordered_map<int, process*>::iterator it(_processes_fd.find(fd));
      if (it == _processes_fd.end()) {
        _update = true;
        throw basic_error() << "invalid fd: not found into processes fd list";
      }
      p = it->second;
    }

    size = p->do_read(fd);
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
  return size;
}

/**
 *  Internal thread to monitor processes.
 */
void process_manager::_run() {
  _running = true;
  try {
    for (;;) {
      // Update the file descriptor list.
      _update_list();

      if (!_running && _fds.size() == 0 && _processes_pid.size() == 0 &&
          _orphans_pid.size() == 0)
        break;

      int ret = poll(_fds.data(), _fds.size(), DEFAULT_TIMEOUT);
      if (ret < 0) {
        if (errno == EINTR)
          ret = 0;
        else {
          const char* msg = strerror(errno);
          throw basic_error() << "poll failed: " << msg;
        }
      }
      for (uint32_t i = 0, checked = 0;
           checked < static_cast<uint32_t>(ret) && i < _fds_size; ++i) {
        // No event.
        if (!_fds[i].revents)
          continue;

        ++checked;

        // Data are available.
        uint32_t size = 0;
        if (_fds[i].revents & (POLLIN | POLLPRI))
          size = _read_stream(_fds[i].fd);
        // File descriptor was close.
        if ((_fds[i].revents & POLLHUP) && !size)
          _close_stream(_fds[i].fd);

        //  Error!
        else if (_fds[i].revents & (POLLERR | POLLNVAL)) {
          _update = true;
          log_error(logging::high)
              << "invalid fd " << _fds[i].fd << " from process manager";
        }
      }
      // Release finished process.
      _wait_processes();
      _wait_orphans_pid();
      // Kill process in timeout.
      _kill_processes_timeout();
    }
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
}

/**
 *  Update process informations at the end of the process.
 *
 *  @param[in] p       The process to update informations.
 *  @param[in] status  The status of the process to set.
 */
void process_manager::_update_ending_process(process* p, int status) noexcept {
  // Check process viability.
  if (!p)
    return;

  p->update_ending_process(status);
  _erase_timeout(p);
}

/**
 *  Update list of file descriptor to watch.
 */
void process_manager::_update_list() {
  // No need to update.
  if (!_update)
    return;

  std::lock_guard<std::mutex> lock(_lock_processes);

  // Set file descriptor to wait event.
  if (_processes_fd.size() != _fds_size) {
    _fds.resize(_processes_fd.size());
    _fds_size = _fds.size();
  }
  auto itt = _fds.begin();
  for (auto it = _processes_fd.begin(), end = _processes_fd.end(); it != end;
       ++it) {
    itt->fd = it->first;
    itt->events = POLLIN | POLLPRI | POLL_HUP;
    itt->revents = 0;
    ++itt;
  }
  // Disable update.
  _update = false;
}

/**
 *  Waiting orphans pid.
 */
void process_manager::_wait_orphans_pid() noexcept {
  try {
    std::unique_lock<std::mutex> lock(_lock_processes);
    std::deque<orphan>::iterator it = _orphans_pid.begin();
    while (it != _orphans_pid.end()) {
      process* p(nullptr);
      // Get process to link with pid and remove this pid
      // to the process manager.
      {
        auto it_p = _processes_pid.find(it->pid);
        if (it_p == _processes_pid.end()) {
          ++it;
          continue;
        }
        p = it_p->second;
        _processes_pid.erase(it_p);
      }

      // Update process.
      lock.unlock();
      _update_ending_process(p, it->status);
      lock.lock();

      // Erase orphan pid.
      it = _orphans_pid.erase(it);
    }
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
}

/**
 *  Waiting finished process.
 */
void process_manager::_wait_processes() noexcept {
  try {
    while (true) {
      int status = 0;
      pid_t pid(::waitpid(-1, &status, WNOHANG));
      // No process are finished.
      if (pid <= 0)
        break;

      process* p = nullptr;
      // Get process to link with pid and remove this pid
      // to the process manager.
      {
        std::lock_guard<std::mutex> lock(_lock_processes);
        auto it = _processes_pid.find(pid);
        if (it == _processes_pid.end()) {
          _orphans_pid.push_back(orphan(pid, status));
          continue;
        }
        p = it->second;
        _processes_pid.erase(it);
      }

      // Update process.
      if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
        p->_is_timeout = true;
      _update_ending_process(p, status);
    }
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
}
<commit_msg>enh(process_manager): waitpid is called with NOHANG to avoid deadlock<commit_after>/*
** Copyright 2012-2013, 2021 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#include "com/centreon/process_manager.hh"
#include <sys/signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <algorithm>
#include <cassert>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include "com/centreon/exceptions/basic.hh"
#include "com/centreon/logging/logger.hh"
#include "com/centreon/process_listener.hh"

using namespace com::centreon;

// Default varibale.
static int const DEFAULT_TIMEOUT = 200;

/**
 *  Add process to the process manager.
 *
 *  @param[in] p    The process to manage.
 *  @param[in] obj  The object to notify.
 */
void process_manager::add(process* p) {
  // Check viability pointer.
  assert(p);

  // We lock _lock_processes before to avoid deadlocks
  std::lock_guard<std::mutex> lock(_lock_processes);

  // Monitor err/out output if necessary.
  if (p->_enable_stream[process::out])
    _processes_fd[p->_stream[process::out]] = p;
  if (p->_enable_stream[process::err])
    _processes_fd[p->_stream[process::err]] = p;

  // Add timeout to kill process if necessary.
  if (p->_timeout)
    _processes_timeout.insert({p->_timeout, p});

  // Need to update file descriptor list.
  _update = true;

  // Add pid process to use waitpid.
  _processes_pid[p->_process] = p;

  // write(_fds_exit[1], "up", 2);
}

/**
 *  Get instance of the process manager.
 *
 *  @return the process manager.
 */
process_manager& process_manager::instance() {
  static process_manager instance;
  return instance;
}

/**
 *  Default constructor. It is private. No need to call, we just use the static
 *  internal function instance().
 */
process_manager::process_manager()
    : _thread{nullptr}, _fds_size{0}, _update(true) {
  _fds.reserve(64);

  // Run process manager thread.
  _thread = new std::thread(&process_manager::_run, this);
}

/**
 *  Destructor.
 */
process_manager::~process_manager() noexcept {
  // Kill all running process.
  {
    std::lock_guard<std::mutex> lock(_lock_processes);
    for (auto it = _processes_pid.begin(), end = _processes_pid.end();
         it != end; ++it) {
      try {
        it->second->kill();
      } catch (const std::exception& e) {
        (void)e;
      }
    }
  }

  // Exit process manager thread.
  //_close(_fds_exit[1]);

  // Waiting the end of the process manager thread.
  _running = false;
  _thread->join();
  delete _thread;
  _thread = nullptr;

  {
    std::lock_guard<std::mutex> lock(_lock_processes);

    // Release memory.
    _fds.clear();

    // Waiting all process.
    int status(0);
    auto time_limit = std::chrono::system_clock::now() + std::chrono::seconds(10);
    int ret = ::waitpid(-1, &status, WNOHANG);
    while (ret >= 0 || (ret < 0 && errno == EINTR)) {
      if (ret == 0)
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
      ret = ::waitpid(-1, &status, WNOHANG);
      if (std::chrono::system_clock::now() >= time_limit)
        break;
    }
  }
}

/**
 *  close syscall wrapper.
 *
 *  @param[in, out] fd The file descriptor to close.
 */
void process_manager::_close(int& fd) noexcept {
  if (fd >= 0) {
    while (::close(fd) < 0 && errno == EINTR)
      std::this_thread::yield();
  }
  fd = -1;
}

/**
 *  Close stream.
 *
 *  @param[in] fd  The file descriptor to close.
 */
void process_manager::_close_stream(int fd) noexcept {
  try {
    process* p;
    // Get process to link with fd and remove this
    // fd to the process manager.
    {
      std::lock_guard<std::mutex> lock(_lock_processes);
      _update = true;
      std::unordered_map<int, process*>::iterator it(_processes_fd.find(fd));
      if (it == _processes_fd.end()) {
        _update = true;
        throw basic_error() << "invalid fd: "
                               "not found into processes fd list";
      }
      p = it->second;
      _processes_fd.erase(it);
    }

    // Update process informations.
    p->do_close(fd);
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
}

/**
 *  Remove process from list of processes timeout.
 *
 *  @param[in] p The process to remove.
 */
void process_manager::_erase_timeout(process* p) {
  // Check process viability.
  if (!p || !p->_timeout)
    return;
  std::lock_guard<std::mutex> lock(_lock_processes);
  auto range = _processes_timeout.equal_range(p->_timeout);
  for (auto it = range.first; it != range.second; ++it) {
    if (it->second == p) {
      _processes_timeout.erase(it);
      break;
    }
  }
}

/**
 *  Kill process to reach the timeout.
 */
void process_manager::_kill_processes_timeout() noexcept {
  std::lock_guard<std::mutex> lock(_lock_processes);
  // Get the current time.
  std::time_t now(time(nullptr));

  // Kill process who timeout and remove it from timeout list.
  for (auto it = _processes_timeout.begin(), end = _processes_timeout.end();
       it != end && it->first <= now;) {
    process* p = it->second;
    try {
      p->kill();
    } catch (const std::exception& e) {
      log_error(logging::high) << e.what();
    }
    it = _processes_timeout.erase(it);
  }
}

/**
 *  Read stream.
 *
 *  @param[in] fd  The file descriptor to read.
 *
 *  @return Number of bytes read.
 */
uint32_t process_manager::_read_stream(int fd) noexcept {
  uint32_t size(0);
  try {
    process* p;
    // Get process to link with fd.
    {
      std::lock_guard<std::mutex> lock(_lock_processes);
      std::unordered_map<int, process*>::iterator it(_processes_fd.find(fd));
      if (it == _processes_fd.end()) {
        _update = true;
        throw basic_error() << "invalid fd: not found into processes fd list";
      }
      p = it->second;
    }

    size = p->do_read(fd);
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
  return size;
}

/**
 *  Internal thread to monitor processes.
 */
void process_manager::_run() {
  _running = true;
  try {
    for (;;) {
      // Update the file descriptor list.
      _update_list();

      if (!_running && _fds.size() == 0 && _processes_pid.size() == 0 &&
          _orphans_pid.size() == 0)
        break;

      int ret = poll(_fds.data(), _fds.size(), DEFAULT_TIMEOUT);
      if (ret < 0) {
        if (errno == EINTR)
          ret = 0;
        else {
          const char* msg = strerror(errno);
          throw basic_error() << "poll failed: " << msg;
        }
      }
      for (uint32_t i = 0, checked = 0;
           checked < static_cast<uint32_t>(ret) && i < _fds_size; ++i) {
        // No event.
        if (!_fds[i].revents)
          continue;

        ++checked;

        // Data are available.
        uint32_t size = 0;
        if (_fds[i].revents & (POLLIN | POLLPRI))
          size = _read_stream(_fds[i].fd);
        // File descriptor was close.
        if ((_fds[i].revents & POLLHUP) && !size)
          _close_stream(_fds[i].fd);

        //  Error!
        else if (_fds[i].revents & (POLLERR | POLLNVAL)) {
          _update = true;
          log_error(logging::high)
              << "invalid fd " << _fds[i].fd << " from process manager";
        }
      }
      // Release finished process.
      _wait_processes();
      _wait_orphans_pid();
      // Kill process in timeout.
      _kill_processes_timeout();
    }
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
}

/**
 *  Update process informations at the end of the process.
 *
 *  @param[in] p       The process to update informations.
 *  @param[in] status  The status of the process to set.
 */
void process_manager::_update_ending_process(process* p, int status) noexcept {
  // Check process viability.
  if (!p)
    return;

  p->update_ending_process(status);
  _erase_timeout(p);
}

/**
 *  Update list of file descriptor to watch.
 */
void process_manager::_update_list() {
  // No need to update.
  if (!_update)
    return;

  std::lock_guard<std::mutex> lock(_lock_processes);

  // Set file descriptor to wait event.
  if (_processes_fd.size() != _fds_size) {
    _fds.resize(_processes_fd.size());
    _fds_size = _fds.size();
  }
  auto itt = _fds.begin();
  for (auto it = _processes_fd.begin(), end = _processes_fd.end(); it != end;
       ++it) {
    itt->fd = it->first;
    itt->events = POLLIN | POLLPRI | POLL_HUP;
    itt->revents = 0;
    ++itt;
  }
  // Disable update.
  _update = false;
}

/**
 *  Waiting orphans pid.
 */
void process_manager::_wait_orphans_pid() noexcept {
  try {
    std::unique_lock<std::mutex> lock(_lock_processes);
    std::deque<orphan>::iterator it = _orphans_pid.begin();
    while (it != _orphans_pid.end()) {
      process* p(nullptr);
      // Get process to link with pid and remove this pid
      // to the process manager.
      {
        auto it_p = _processes_pid.find(it->pid);
        if (it_p == _processes_pid.end()) {
          ++it;
          continue;
        }
        p = it_p->second;
        _processes_pid.erase(it_p);
      }

      // Update process.
      lock.unlock();
      _update_ending_process(p, it->status);
      lock.lock();

      // Erase orphan pid.
      it = _orphans_pid.erase(it);
    }
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
}

/**
 *  Waiting finished process.
 */
void process_manager::_wait_processes() noexcept {
  try {
    for (;;) {
      int status = 0;
      pid_t pid(::waitpid(-1, &status, WNOHANG));
      // No process are finished.
      if (pid <= 0)
        break;

      process* p = nullptr;
      // Get process to link with pid and remove this pid
      // to the process manager.
      {
        std::lock_guard<std::mutex> lock(_lock_processes);
        auto it = _processes_pid.find(pid);
        if (it == _processes_pid.end()) {
          _orphans_pid.push_back(orphan(pid, status));
          continue;
        }
        p = it->second;
        _processes_pid.erase(it);
      }

      // Update process.
      if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
        p->_is_timeout = true;
      _update_ending_process(p, status);
    }
  } catch (const std::exception& e) {
    log_error(logging::high) << e.what();
  }
}
<|endoftext|>


<commit_before>#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <math.h>
#include <limits>

#include "scene.hpp"
#include "light.hpp"

using std::vector;

/*
 * In the case of an empty constructor, Scene will generate a predefined
 * scene for rendering.
 */
Scene::Scene() : shapes(vector<Shape*>()),
                 lights(vector<LightSource*>()),
                 ambient(Color(0.25, 0.25, 0.25)),
                 camera(Camera()) {
    shapes.push_back(new Plane(Point(0, -3, 0), Vector(0, 1, 0),
                Color(0, 1, 1), 1, 0.5, 0.5, 0.5));
    //shapes.push_back(new Plane(Point(0, 0, 10), Vector(0, 0, 1),
                //Color(0, 1, 0), 1, 0.5, 0.5, 0.5));
    shapes.push_back(new Sphere(Point(1, -1, 5), 1,
                Color(1, 0, 0), 1, 0.5, 0.5, 0.5));
    shapes.push_back(new Sphere(Point(-1, -1, 5), 1,
                Color(0, 0, 1), 1, 0.5, 0.5, 0.5));

    lights.push_back(new PointLight(Color(1, 1, 1), Point(0, 5, 5)));
}

Scene::Scene(std::string fileName): shapes(vector<Shape*>()),
                                    lights(vector<LightSource*>()),
                                    ambient(Color(0.25, 0.25, 0.25)),
                                    camera(Camera()) {
    std::ifstream input_scene (fileName.c_str());
    // Read the file and add specified shapes.
    // We need to figure out what our syntax/grammar is first though.
}

Color Scene::raytrace(const Ray& camera_ray) const {
    const Shape *nearest_shape = NULL;
    float nearest_distance2 = std::numeric_limits<float>::max();
    Ray nearest_hit;
    for (vector<Shape*>::const_iterator it = shapes.begin(); it != shapes.end(); it++) {
        const Shape *shape = *it;
        Ray *intersection = shape->getIntersection(camera_ray);
        if (intersection == NULL) // Didn't hit this shape
            continue;
        float int_distance2 = Ray::makeRay(camera_ray.getOrigin(),
                intersection->getOrigin()).getDir().magnitude2();
        if (int_distance2 < nearest_distance2) {
            // Found a closer hit
            nearest_shape = shape;
            nearest_distance2 = int_distance2;
            nearest_hit = *intersection;
        }
        delete intersection;
    }
    if (nearest_shape == NULL) {
        // Didn't hit anything
        return Color(1, 0, 1); // Magenta
    } else {
        return shade(nearest_shape, nearest_hit);
    }
}

Color Scene::shade(const Shape *obj, Ray hit) const{
    for(vector<LightSource*>::const_iterator it = lights.begin(); it != lights.end(); it++) {
        Ray shadow = Ray::makeRay(hit.getOrigin(), (*it)->getPoint());
        Color result = Color(ambient);
        bool collision = false;

        // Detect collisions, for now do nothing if there is a collision
        for(vector<Shape*>::const_iterator sh = shapes.begin(); sh != shapes.end(); sh++) {
            Ray *hit = (*sh)->getIntersection(shadow);
            if (hit != NULL) {
                collision = true;
                delete hit;
                break;
            }
        }

        // Calculate local illumination
        if(!collision) {
            // Normalize the direction vectors before calculations
            shadow.normalize();
            hit.normalize();

            float cos_theta = (shadow.getDir()).dotProduct(hit.getDir());

            if(cos_theta<0)
                cos_theta=0;

            Color diffuse = cos_theta*obj->getDiffuseCoefficient()*((*it)->getColor());
            result = result + diffuse;
            result = result * obj->getColor();
        }

        return result;
    }
}
Scene::~Scene() {
    for(vector<Shape*>::iterator it = shapes.begin(); it != shapes.end(); it++) {
        delete *it;
    }
    for(vector<LightSource*>::iterator it = lights.begin(); it != lights.end(); it++) {
        delete *it;
    }
}

Ray Scene::get_camera_ray(float x, float y) const {
    return camera.get_ray(x, -y);
}
<commit_msg>Inverted the shading<commit_after>#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <math.h>
#include <limits>

#include "scene.hpp"
#include "light.hpp"

using std::vector;

/*
 * In the case of an empty constructor, Scene will generate a predefined
 * scene for rendering.
 */
Scene::Scene() : shapes(vector<Shape*>()),
                 lights(vector<LightSource*>()),
                 ambient(Color(0.25, 0.25, 0.25)),
                 camera(Camera()) {
    shapes.push_back(new Plane(Point(0, -3, 0), Vector(0, 1, 0),
                Color(0, 1, 1), 1, 0.5, 0.5, 0.5));
    //shapes.push_back(new Plane(Point(0, 0, 10), Vector(0, 0, 1),
                //Color(0, 1, 0), 1, 0.5, 0.5, 0.5));
    shapes.push_back(new Sphere(Point(1, -1, 5), 1,
                Color(1, 0, 0), 1, 0.5, 0.5, 0.5));
    shapes.push_back(new Sphere(Point(-1, -1, 5), 1,
                Color(0, 0, 1), 1, 0.5, 0.5, 0.5));

    lights.push_back(new PointLight(Color(1, 1, 1), Point(0, 5, 5)));
}

Scene::Scene(std::string fileName): shapes(vector<Shape*>()),
                                    lights(vector<LightSource*>()),
                                    ambient(Color(0.25, 0.25, 0.25)),
                                    camera(Camera()) {
    std::ifstream input_scene (fileName.c_str());
    // Read the file and add specified shapes.
    // We need to figure out what our syntax/grammar is first though.
}

Color Scene::raytrace(const Ray& camera_ray) const {
    const Shape *nearest_shape = NULL;
    float nearest_distance2 = std::numeric_limits<float>::max();
    Ray nearest_hit;
    for (vector<Shape*>::const_iterator it = shapes.begin(); it != shapes.end(); it++) {
        const Shape *shape = *it;
        Ray *intersection = shape->getIntersection(camera_ray);
        if (intersection == NULL) // Didn't hit this shape
            continue;
        float int_distance2 = Ray::makeRay(camera_ray.getOrigin(),
                intersection->getOrigin()).getDir().magnitude2();
        if (int_distance2 < nearest_distance2) {
            // Found a closer hit
            nearest_shape = shape;
            nearest_distance2 = int_distance2;
            nearest_hit = *intersection;
        }
        delete intersection;
    }
    if (nearest_shape == NULL) {
        // Didn't hit anything
        return Color(1, 0, 1); // Magenta
    } else {
        return shade(nearest_shape, nearest_hit);
    }
}

Color Scene::shade(const Shape *obj, Ray hit) const{
    for(vector<LightSource*>::const_iterator it = lights.begin(); it != lights.end(); it++) {
        LightSource *light = *it;
        Ray shadow = Ray::makeRay(hit.getOrigin(), light->getPoint());
        Color result = Color(ambient);
        bool collision = false;

        // Detect collisions, for now do nothing if there is a collision
        for(vector<Shape*>::const_iterator sh = shapes.begin(); sh != shapes.end(); sh++) {
            Ray *hit = (*sh)->getIntersection(shadow);
            if (hit != NULL) {
                collision = true;
                delete hit;
                break;
            }
        }

        // Calculate local illumination
        if(!collision) {
            // Normalize the direction vectors before calculations
            shadow.normalize();
            hit.normalize();

            float cos_theta = (shadow.getDir()).dotProduct(hit.getDir());

            if(cos_theta < 0)
                cos_theta = -cos_theta;
            else
                cos_theta = 0;

            Color diffuse = cos_theta * obj->getDiffuseCoefficient()
                * light->getColor();
            result = result + diffuse;
            result = result * obj->getColor();
        }

        return result;
    }
}
Scene::~Scene() {
    for(vector<Shape*>::iterator it = shapes.begin(); it != shapes.end(); it++) {
        delete *it;
    }
    for(vector<LightSource*>::iterator it = lights.begin(); it != lights.end(); it++) {
        delete *it;
    }
}

Ray Scene::get_camera_ray(float x, float y) const {
    return camera.get_ray(x, -y);
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "temp_scaffolding_stubs.h"

#include "build/build_config.h"

#include <vector>

#include "base/gfx/rect.h"
#include "base/logging.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/download/download_request_dialog_delegate.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/hung_renderer_dialog.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/options_window.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/process_watcher.h"

#if defined(OS_MACOSX)
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_shelf.h"
#endif

#if defined(TOOLKIT_VIEWS)
#include "views/controls/menu/chrome_menu.h"
#endif

class TabContents;

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

void AutomationProvider::GetActiveWindow(int* handle) { NOTIMPLEMENTED(); }

void AutomationProvider::ActivateWindow(int handle) { NOTIMPLEMENTED(); }

void AutomationProvider::SetWindowVisible(int handle, bool visible,
                                          bool* result) { NOTIMPLEMENTED(); }

void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditForBrowser(
    int browser_handle,
    bool* success,
    int* autocomplete_edit_handle) {
  *success = false;
  NOTIMPLEMENTED();
}
#endif

void AutomationProvider::GetBrowserForWindow(int window_handle,
                                             bool* success,
                                             int* browser_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetSecurityState(int handle, bool* success,
                                          SecurityStyle* security_style,
                                          int* ssl_cert_status,
                                          int* mixed_content_status) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetPageType(int handle, bool* success,
                                     NavigationEntry::PageType* page_type) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
                                                 IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::PrintNow(int tab_handle,
                                  IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
                                                 bool* success,
                                                 std::wstring* text) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
                                                 const std::wstring& text,
                                                 bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditGetMatches(
    int autocomplete_edit_handle,
    bool* success,
    std::vector<AutocompleteMatchData>* matches) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditIsQueryInProgress(
    int autocomplete_edit_handle,
    bool* success,
    bool* query_in_progress) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::OnMessageFromExternalHost(
    int handle, const std::string& message, const std::string& origin,
    const std::string& target) {
  NOTIMPLEMENTED();
}
#endif  // defined(OS_MACOSX)

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

#if defined(OS_LINUX)
bool ShellIntegration::SetAsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}
#endif

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

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details,
                                        std::vector<std::wstring>* new_tabs) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  // Pretend we processed them correctly.
  return true;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return 0;
}

bool FirstRun::CreateChromeDesktopShortcut() {
  NOTIMPLEMENTED();
  return false;
}

bool FirstRun::CreateChromeQuickLaunchShortcut() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

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

void InstallJankometer(const CommandLine&) {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

void UninstallJankometer() {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

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

void RLZTracker::CleanupRlz() {
  // http://code.google.com/p/chromium/issues/detail?id=8152
}

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

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

#if defined(OS_MACOSX)

class DownloadShelfMac : public DownloadShelf {
 public:
  explicit DownloadShelfMac(TabContents* tab_contents)
      : DownloadShelf(tab_contents) { }
  virtual void AddDownload(BaseDownloadItemModel* download_model) { }
  virtual bool IsShowing() const { return false; }
  virtual bool IsClosing() const { return false; }
};

// static
DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) {
  return new DownloadShelfMac(tab_contents);
}

#endif

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

void RunRepostFormWarningDialog(NavigationController*) {
}

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

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

MemoryDetails::MemoryDetails() {
  NOTIMPLEMENTED();
}

void MemoryDetails::StartFetch() {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}
#endif

DownloadRequestDialogDelegate* DownloadRequestDialogDelegate::Create(
    TabContents* tab,
    DownloadRequestManager::TabDownloadState* host) {
  NOTIMPLEMENTED();
  return NULL;
}

#if !defined(TOOLKIT_VIEWS)
namespace download_util {

void DragDownload(const DownloadItem* download, SkBitmap* icon) {
  NOTIMPLEMENTED();
}

}  // namespace download_util
#endif

#if defined(OS_MACOSX)
void HungRendererDialog::HideForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}

void HungRendererDialog::ShowForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}
#endif

#if !defined(TOOLKIT_VIEWS)
void BrowserList::AllBrowsersClosed() {
  // TODO(port): Close any dependent windows if necessary when the last browser
  //             window is closed.
}
#endif

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

#if defined(OS_MACOSX)
void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  NOTIMPLEMENTED();
}
#endif

#if !defined(TOOLKIT_VIEWS)
bool DockInfo::GetNewWindowBounds(gfx::Rect* new_window_bounds,
                                  bool* maximize_new_window) const {
  NOTIMPLEMENTED();
  return true;
}
#endif

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

#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
namespace views {

MenuItemView::MenuItemView(MenuDelegate* delegate) {
}

MenuItemView::~MenuItemView() {
}

MenuItemView* MenuItemView::AppendMenuItemInternal(int item_id,
                                                   const std::wstring& label,
                                                   const SkBitmap& icon,
                                                   Type type) {
  NOTIMPLEMENTED();
  return NULL;
}

void MenuItemView::RunMenuAt(gfx::NativeView parent,
               const gfx::Rect& bounds,
               AnchorPosition anchor,
               bool has_mnemonics) {
  NOTIMPLEMENTED();
}

void MenuItemView::RunMenuForDropAt(gfx::NativeView parent,
                      const gfx::Rect& bounds,
                      AnchorPosition anchor) {
  NOTIMPLEMENTED();
}

// Hides and cancels the menu. This does nothing if the menu is not open.
void MenuItemView::Cancel() {
  NOTIMPLEMENTED();
}

SubmenuView* MenuItemView::CreateSubmenu() {
  NOTIMPLEMENTED();
  return NULL;
}

void MenuItemView::SetSelected(bool selected) {
  NOTIMPLEMENTED();
}

void MenuItemView::SetIcon(const SkBitmap& icon, int item_id) {
  NOTIMPLEMENTED();
}

void MenuItemView::SetIcon(const SkBitmap& icon) {
  NOTIMPLEMENTED();
}

void MenuItemView::Paint(gfx::Canvas* canvas) {
  NOTIMPLEMENTED();
}

gfx::Size MenuItemView::GetPreferredSize() {
  NOTIMPLEMENTED();
  return gfx::Size();
}

MenuController* MenuItemView::GetMenuController() {
  NOTIMPLEMENTED();
  return NULL;
}

MenuDelegate* MenuItemView::GetDelegate() {
  NOTIMPLEMENTED();
  return NULL;
}

MenuItemView* MenuItemView::GetRootMenuItem() {
  NOTIMPLEMENTED();
  return NULL;
}

wchar_t MenuItemView::GetMnemonic() {
  return 'a';
}

}  // namespace views

#endif
<commit_msg>Hopefully fix the Linux build again. Review URL: http://codereview.chromium.org/115850<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "temp_scaffolding_stubs.h"

#include "build/build_config.h"

#include <vector>

#include "base/gfx/rect.h"
#include "base/logging.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/download/download_request_dialog_delegate.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/hung_renderer_dialog.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/options_window.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/process_watcher.h"

#if defined(OS_MACOSX)
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_shelf.h"
#endif

#if defined(TOOLKIT_VIEWS)
#include "views/controls/menu/chrome_menu.h"
#endif

class TabContents;

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

void AutomationProvider::GetActiveWindow(int* handle) { NOTIMPLEMENTED(); }

void AutomationProvider::ActivateWindow(int handle) { NOTIMPLEMENTED(); }

void AutomationProvider::SetWindowVisible(int handle, bool visible,
                                          bool* result) { NOTIMPLEMENTED(); }

void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditForBrowser(
    int browser_handle,
    bool* success,
    int* autocomplete_edit_handle) {
  *success = false;
  NOTIMPLEMENTED();
}
#endif

void AutomationProvider::GetBrowserForWindow(int window_handle,
                                             bool* success,
                                             int* browser_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetSecurityState(int handle, bool* success,
                                          SecurityStyle* security_style,
                                          int* ssl_cert_status,
                                          int* mixed_content_status) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetPageType(int handle, bool* success,
                                     NavigationEntry::PageType* page_type) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
                                                 IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::PrintNow(int tab_handle,
                                  IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
                                                 bool* success,
                                                 std::wstring* text) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
                                                 const std::wstring& text,
                                                 bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditGetMatches(
    int autocomplete_edit_handle,
    bool* success,
    std::vector<AutocompleteMatchData>* matches) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditIsQueryInProgress(
    int autocomplete_edit_handle,
    bool* success,
    bool* query_in_progress) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::OnMessageFromExternalHost(
    int handle, const std::string& message, const std::string& origin,
    const std::string& target) {
  NOTIMPLEMENTED();
}
#endif  // defined(OS_MACOSX)

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

#if defined(OS_LINUX)
bool ShellIntegration::SetAsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}
#endif

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

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details,
                                        std::vector<std::wstring>* new_tabs) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  // Pretend we processed them correctly.
  return true;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return 0;
}

bool FirstRun::CreateChromeDesktopShortcut() {
  NOTIMPLEMENTED();
  return false;
}

bool FirstRun::CreateChromeQuickLaunchShortcut() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

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

void InstallJankometer(const CommandLine&) {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

void UninstallJankometer() {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

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

void RLZTracker::CleanupRlz() {
  // http://code.google.com/p/chromium/issues/detail?id=8152
}

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

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

#if defined(OS_MACOSX)

class DownloadShelfMac : public DownloadShelf {
 public:
  explicit DownloadShelfMac(TabContents* tab_contents)
      : DownloadShelf(tab_contents) { }
  virtual void AddDownload(BaseDownloadItemModel* download_model) { }
  virtual bool IsShowing() const { return false; }
  virtual bool IsClosing() const { return false; }
};

// static
DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) {
  return new DownloadShelfMac(tab_contents);
}

#endif

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

void RunRepostFormWarningDialog(NavigationController*) {
}

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

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

MemoryDetails::MemoryDetails() {
  NOTIMPLEMENTED();
}

void MemoryDetails::StartFetch() {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}
#endif

DownloadRequestDialogDelegate* DownloadRequestDialogDelegate::Create(
    TabContents* tab,
    DownloadRequestManager::TabDownloadState* host) {
  NOTIMPLEMENTED();
  return NULL;
}

#if !defined(TOOLKIT_VIEWS)
namespace download_util {

void DragDownload(const DownloadItem* download, SkBitmap* icon) {
  NOTIMPLEMENTED();
}

}  // namespace download_util
#endif

#if defined(OS_MACOSX)
void HungRendererDialog::HideForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}

void HungRendererDialog::ShowForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}
#endif

#if !defined(TOOLKIT_VIEWS)
void BrowserList::AllBrowsersClosed() {
  // TODO(port): Close any dependent windows if necessary when the last browser
  //             window is closed.
}
#endif

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

#if defined(OS_MACOSX)
void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  NOTIMPLEMENTED();
}
#endif

#if defined(OS_MACOSX)
bool DockInfo::GetNewWindowBounds(gfx::Rect* new_window_bounds,
                                  bool* maximize_new_window) const {
  NOTIMPLEMENTED();
  return true;
}
#endif

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

#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
namespace views {

MenuItemView::MenuItemView(MenuDelegate* delegate) {
}

MenuItemView::~MenuItemView() {
}

MenuItemView* MenuItemView::AppendMenuItemInternal(int item_id,
                                                   const std::wstring& label,
                                                   const SkBitmap& icon,
                                                   Type type) {
  NOTIMPLEMENTED();
  return NULL;
}

void MenuItemView::RunMenuAt(gfx::NativeView parent,
               const gfx::Rect& bounds,
               AnchorPosition anchor,
               bool has_mnemonics) {
  NOTIMPLEMENTED();
}

void MenuItemView::RunMenuForDropAt(gfx::NativeView parent,
                      const gfx::Rect& bounds,
                      AnchorPosition anchor) {
  NOTIMPLEMENTED();
}

// Hides and cancels the menu. This does nothing if the menu is not open.
void MenuItemView::Cancel() {
  NOTIMPLEMENTED();
}

SubmenuView* MenuItemView::CreateSubmenu() {
  NOTIMPLEMENTED();
  return NULL;
}

void MenuItemView::SetSelected(bool selected) {
  NOTIMPLEMENTED();
}

void MenuItemView::SetIcon(const SkBitmap& icon, int item_id) {
  NOTIMPLEMENTED();
}

void MenuItemView::SetIcon(const SkBitmap& icon) {
  NOTIMPLEMENTED();
}

void MenuItemView::Paint(gfx::Canvas* canvas) {
  NOTIMPLEMENTED();
}

gfx::Size MenuItemView::GetPreferredSize() {
  NOTIMPLEMENTED();
  return gfx::Size();
}

MenuController* MenuItemView::GetMenuController() {
  NOTIMPLEMENTED();
  return NULL;
}

MenuDelegate* MenuItemView::GetDelegate() {
  NOTIMPLEMENTED();
  return NULL;
}

MenuItemView* MenuItemView::GetRootMenuItem() {
  NOTIMPLEMENTED();
  return NULL;
}

wchar_t MenuItemView::GetMnemonic() {
  return 'a';
}

}  // namespace views

#endif
<|endoftext|>


<commit_before>//Author   : Sam Forrest
//Problem  : Week 3, Common Permutation
//Status   : Accepted

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    string s1, s2;
    while (!cin.eof())
    {
		//2 vectors to count chars in both s1 and s2
		vector <int> count1 (26, 0);
		vector <int> count2 (26, 0);
		getline(cin,s1);
		getline(cin,s2);

		//count chars in s1 and s2
		for(int i = 0; i < s1.length(); i++)
			if ((s1[i] >= 97) && (s1[i] <= 122))
				count1[s1[i]-97]++;

		for(int i = 0; i < s2.length(); i++)
			if ((s2[i] >= 97) && (s2[i] <= 122))
				count2[s2[i]-97]++;

		//iterate through characters in alphabetical order and output them min number of times
		for(int i =0; i < 26; i++)
			for (int j =0; j < ((count1[i] < count2[i]) ? count1[i] : count2[i]); j++)
				cout << char(i+97);

		if(!cin.eof())
			cout << endl;
    }
    return 0;
}
<commit_msg>Delete sam_solution.cpp<commit_after><|endoftext|>