From: Christophe ThiƩry Date: Fri, 29 Jul 2011 09:32:02 +0000 (+0200) Subject: Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot//simgrid/simgrid X-Git-Tag: v3_6_2~188^2~7 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/5b811fdb6d7fae96fa9fe45612dee560a64f2af6?hp=2fa2a6ce966b1ceb2327ea00f7e4073ceba55175 Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot//simgrid/simgrid --- diff --git a/COPYING b/COPYING index 7f936320c3..37b50f0024 100644 --- a/COPYING +++ b/COPYING @@ -7,6 +7,30 @@ Some perticular files distributed with the project have other licenses. More specifically, these files are listed below, along with their license. +========================================================================= + +We have embeded pcre 8.12 library into the windows installer. + +PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. +Release 8 of PCRE is distributed under the terms of the "BSD" licence. +The basic library functions are written in C and are freestanding. Also +included in the distribution is a set of C++ wrapper functions. + +/* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + ========================================================================== The file src/xbt/snprintf.c contains this license text: diff --git a/ChangeLog b/ChangeLog index c53ae08349..981ebece0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,22 @@ SimGrid (3.7) unstable; urgency=low + Dot Loader + * Bug fix: correction of the dot file parsing with the libcgraph + + Windows Port + * Fix many issues that prevented SimGrid from working + correctly on windows (both for 32 and 64 bit architectures): + - port win32_ucontext.c to 64 bit arch + - now that we rely on gcc, clean xbt/log.h so that it does not + add useless bugs that had been introduced to handle the + borland compiler + * Create an installer for windows with nsis(amd64 and win32) + - Add an hello world project to illustrate simgrid project creation. + - Embed libpcre into the Simgrid installer to avoid + its compilation burden + -- `LC_ALL=C date` Da SimGrid team SIMDAG - [dot loader] - * Bug fix: correction of the dot file parsing with the libcgraph SimGrid (3.6.1) unstable; urgency=low diff --git a/buildtools/Cmake/Flags.cmake b/buildtools/Cmake/Flags.cmake index 95b1ae5717..278388cdc9 100644 --- a/buildtools/Cmake/Flags.cmake +++ b/buildtools/Cmake/Flags.cmake @@ -30,10 +30,6 @@ set(CMAKE_C_FLAGS "${optCFLAGS}${warnCFLAGS}${CMAKE_C_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${custom_flags}") -if(HAVE_PCRE_LIB AND WIN32) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPCRE_STATIC") -endif(HAVE_PCRE_LIB AND WIN32) - # Try to make Mac a bit more complient to open source standards if(CMAKE_SYSTEM_NAME MATCHES "Darwin") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE") diff --git a/buildtools/Cmake/MakeExe.cmake b/buildtools/Cmake/MakeExe.cmake index 30485806d9..ed00683542 100644 --- a/buildtools/Cmake/MakeExe.cmake +++ b/buildtools/Cmake/MakeExe.cmake @@ -69,6 +69,10 @@ if(HAVE_GTNETS) add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/gtnets) endif(HAVE_GTNETS) +if(HAVE_NS3) + add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/msg/ns3) +endif(HAVE_NS3) + add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/amok/bandwidth) add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/amok/saturate) diff --git a/buildtools/Cmake/Modules/FindPCRE.cmake b/buildtools/Cmake/Modules/FindPCRE.cmake index 93fd14dd76..5f22069aed 100644 --- a/buildtools/Cmake/Modules/FindPCRE.cmake +++ b/buildtools/Cmake/Modules/FindPCRE.cmake @@ -12,6 +12,15 @@ find_library(PATH_PCRE_LIB /sw /usr) +string(REGEX MATCH ".dll.a" operation "${PATH_PCRE_LIB}") + +if(NOT operation) + if(WIN32) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}-DPCRE_STATIC ") + endif(WIN32) +endif(NOT operation) + + find_path(PATH_PCRE_H "pcre.h" HINTS $ENV{SIMGRID_PCRE_LIBRARY_PATH} diff --git a/buildtools/Cmake/simgrid.nsi.in b/buildtools/Cmake/simgrid.nsi.in index e2f615123f..2191decb2d 100644 --- a/buildtools/Cmake/simgrid.nsi.in +++ b/buildtools/Cmake/simgrid.nsi.in @@ -356,7 +356,7 @@ section "Uninstall" RMDir "$SMPROGRAMS\SimGrid" # delete PCRE - RMDir "$INSTDIR\GnuWin32" + RMDir /r "$INSTDIR\GnuWin32" # Delete variable DeleteRegValue ${env_hklm} SIMGRID_ROOT diff --git a/doc/HelloWorld/FindPCRE.cmake b/doc/HelloWorld/FindPCRE.cmake index 9454da7151..e6f382b41e 100644 --- a/doc/HelloWorld/FindPCRE.cmake +++ b/doc/HelloWorld/FindPCRE.cmake @@ -13,6 +13,7 @@ endif(APPLE) find_library(PATH_PCRE_LIB NAMES pcre HINTS + $ENV{SIMGRID_PCRE_LIBRARY_PATH} $ENV{LD_LIBRARY_PATH} $ENV{PCRE_LIBRARY_PATH} PATH_SUFFIXES lib/ GnuWin32/lib @@ -23,8 +24,17 @@ find_library(PATH_PCRE_LIB /sw /usr) +string(REGEX MATCH ".dll.a" operation "${PATH_PCRE_LIB}") + +if(NOT operation) + if(WIN32) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}-DPCRE_STATIC ") + endif(WIN32) +endif(NOT operation) + find_path(PATH_PCRE_H "pcre.h" HINTS + $ENV{SIMGRID_PCRE_LIBRARY_PATH} $ENV{LD_LIBRARY_PATH} $ENV{PCRE_LIBRARY_PATH} PATH_SUFFIXES include/ GnuWin32/include @@ -51,6 +61,27 @@ else(PATH_PCRE_LIB) message(STATUS "Looking for lib pcre - not found") endif(PATH_PCRE_LIB) +if(WIN32) + find_path(PATH_PCRE_LICENCE "LICENCE" + HINTS + $ENV{SIMGRID_PCRE_LIBRARY_PATH} + $ENV{LD_LIBRARY_PATH} + $ENV{PCRE_LIBRARY_PATH} + PATH_SUFFIXES GnuWin32 + PATHS + /opt + /opt/local + /opt/csw + /sw + /usr) + message(STATUS "Looking for pcre licence") + if(PATH_PCRE_LICENCE) + message(STATUS "Looking for pcre licence - found") + else(PATH_PCRE_LICENCE) + message(STATUS "Looking for pcre licence - not found") + endif(PATH_PCRE_LICENCE) +endif(WIN32) + if(PATH_PCRE_LIB AND PATH_PCRE_H) string(REGEX REPLACE "/libpcre.*[.]${LIB_EXE}$" "" PATHLIBPCRE "${PATH_PCRE_LIB}") string(REGEX REPLACE "/pcre.h" "" PATH_PCRE_H "${PATH_PCRE_H}") diff --git a/examples/msg/ns3/CMakeLists.txt b/examples/msg/ns3/CMakeLists.txt new file mode 100644 index 0000000000..1111655a04 --- /dev/null +++ b/examples/msg/ns3/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 2.6) + +set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(ns3 "ns3.c") + +### Add definitions for compile +target_link_libraries(ns3 simgrid m ) + diff --git a/examples/msg/ns3/ns3.c b/examples/msg/ns3/ns3.c new file mode 100644 index 0000000000..a40a8d5ff6 --- /dev/null +++ b/examples/msg/ns3/ns3.c @@ -0,0 +1,210 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include +#include +#include "msg/msg.h" +#include "xbt/log.h" +#include "xbt/asserts.h" + +XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, + "Messages specific for this msg example"); + +int master(int argc, char *argv[]); +int slave(int argc, char *argv[]); +int timer(int argc, char *argv[]); +MSG_error_t test_all(const char *platform_file, + const char *application_file); + +int timer_start = 1; + +typedef enum { + PORT_22 = 0, + MAX_CHANNEL +} channel_t; + +//keep a pointer to all surf running tasks. +#define NTASKS 1500 +int bool_printed = 0; +double start_time, end_time, elapsed_time; +double gl_data_size[NTASKS]; +m_task_t gl_task_array[NTASKS]; +const char *slavenames[NTASKS]; +const char *masternames[NTASKS]; +int gl_task_array_id = 0; +int count_finished = 0; + +#define FINALIZE ((void*)221297) /* a magic number to tell people to stop working */ + +/** master */ +int master(int argc, char *argv[]) +{ + char *slavename = NULL; + double task_comm_size = 0; + m_task_t todo; + char id_alias[10]; + //unique id to control statistics + int id = -1; + + if (argc != 4) { + XBT_INFO("Strange number of arguments expected 3 got %d", argc - 1); + } + + /* data size */ + int read; + read = sscanf(argv[1], "%lg", &task_comm_size); + xbt_assert(read, "Invalid argument %s\n", argv[1]); + + /* slave name */ + slavename = argv[2]; + id = atoi(argv[3]); + sprintf(id_alias, "flow_%d", id); + slavenames[id] = slavename; + TRACE_category(id_alias); + + masternames[id] = MSG_host_get_name(MSG_host_self()); + + { /* Task creation. */ + char sprintf_buffer[64] = "Task_0"; + todo = MSG_task_create(sprintf_buffer, 100*task_comm_size, task_comm_size, NULL); + TRACE_msg_set_task_category(todo, id_alias); + //keep track of running tasks + gl_task_array[id] = todo; + gl_data_size[id] = task_comm_size; + } + + { /* Process organisation */ + MSG_get_host_by_name(slavename); + } + + count_finished++; + + /* time measurement */ + sprintf(id_alias, "%d", id); + start_time = MSG_get_clock(); + //MSG_task_execute(todo); + MSG_task_send(todo, id_alias); + end_time = MSG_get_clock(); + + + return 0; +} /* end_of_master */ + + +/** Timer function */ +int timer(int argc, char *argv[]) +{ + int sleep_time; + int first_sleep; + + if (argc != 3) { + XBT_INFO("Strange number of arguments expected 2 got %d", argc - 1); + } + + sscanf(argv[1], "%d", &first_sleep); + sscanf(argv[2], "%d", &sleep_time); + + if(first_sleep){ + MSG_process_sleep(first_sleep); + } + + while(timer_start){ + MSG_process_sleep(sleep_time); + } + + return 0; +} + +/** Receiver function */ +int slave(int argc, char *argv[]) +{ + + m_task_t task = NULL; + int a = MSG_OK; + int id = 0; + char id_alias[10]; + + if (argc != 2) { + XBT_INFO("Strange number of arguments expected 1 got %d", argc - 1); + } + + id = atoi(argv[1]); + sprintf(id_alias, "%d", id); + + a = MSG_task_receive(&(task), id_alias); + + count_finished--; + if(count_finished == 0){ + timer_start = 0; + } + + + + if (a != MSG_OK) { + XBT_INFO("Hey?! What's up?"); + xbt_die("Unexpected behavior."); + } + + elapsed_time = MSG_get_clock() - start_time; + + XBT_INFO("FLOW[%d] : Receive %.0f bytes from %s to %s", + id, + MSG_task_get_data_size(task), + masternames[id], + slavenames[id]); + + MSG_task_destroy(task); + + return 0; +} /* end_of_slave */ + +/** Test function */ +MSG_error_t test_all(const char *platform_file, + const char *application_file) +{ + MSG_error_t res = MSG_OK; + + /* MSG_config("workstation/model", "GTNETS"); */ + /* MSG_config("workstation/model","KCCFLN05"); */ + { /* Simulation setting */ + MSG_set_channel_number(MAX_CHANNEL); + MSG_create_environment(platform_file); + } + + TRACE_declare_mark("endmark"); + + { /* Application deployment */ + MSG_function_register("master", master); + MSG_function_register("slave", slave); + MSG_function_register("timer", timer); + + MSG_launch_application(application_file); + } + res = MSG_main(); + return res; +} /* end_of_test_all */ + +/** Main function */ +int main(int argc, char *argv[]) +{ + MSG_error_t res = MSG_OK; + bool_printed = 0; + + MSG_global_init(&argc, argv); + if (argc < 3) { + printf("Usage: %s platform_file deployment_file\n", argv[0]); + exit(1); + } + + res = test_all(argv[1], argv[2]); + + MSG_clean(); + + if (res == MSG_OK) + return 0; + else + return 1; +} /* end_of_main */ diff --git a/examples/msg/ns3/onelink-d.xml b/examples/msg/ns3/onelink-d.xml new file mode 100644 index 0000000000..b9a1cf4fff --- /dev/null +++ b/examples/msg/ns3/onelink-d.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/msg/ns3/onelink-p.xml b/examples/msg/ns3/onelink-p.xml new file mode 100644 index 0000000000..b05e780dce --- /dev/null +++ b/examples/msg/ns3/onelink-p.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/include/xbt/log.h b/include/xbt/log.h index 790295e941..d80ba1ea88 100644 --- a/include/xbt/log.h +++ b/include/xbt/log.h @@ -241,11 +241,9 @@ typedef struct xbt_log_category_s s_xbt_log_category_t, /* * Do NOT access any members of this structure directly. FIXME: move to private? */ -#ifdef _XBT_WIN32 -#define XBT_LOG_BUFF_SIZE 16384 /* Size of the static string in which we build the log string */ -#else + #define XBT_LOG_BUFF_SIZE 2048 /* Size of the static string in which we build the log string */ -#endif + struct xbt_log_category_s { xbt_log_category_t parent; xbt_log_category_t firstChild; @@ -266,11 +264,7 @@ struct xbt_log_event_s { int lineNum; va_list ap; va_list ap_copy; /* need a copy to launch dynamic layouts when the static ones overflowed */ -#ifdef _XBT_WIN32 - char *buffer; -#else char buffer[XBT_LOG_BUFF_SIZE]; -#endif }; /** @@ -389,15 +383,10 @@ extern xbt_log_layout_t xbt_log_default_layout; * code. * Setting the LogEvent's valist member is done inside _log_logEvent. */ -#ifdef _XBT_WIN32 -#include /* calloc */ -#define _XBT_LOG_EV_BUFFER_ZERO() \ - _log_ev.buffer = (char*) calloc(XBT_LOG_BUFF_SIZE + 1, sizeof(char)) -#else + #include /* memset */ #define _XBT_LOG_EV_BUFFER_ZERO() \ memset(_log_ev.buffer, 0, XBT_LOG_BUFF_SIZE) -#endif /* Logging Macros */ @@ -405,9 +394,9 @@ extern xbt_log_layout_t xbt_log_default_layout; # define XBT_CLOG(cat, prio, ...) \ _XBT_IF_ONE_ARG(_XBT_CLOG_ARG1, _XBT_CLOG_ARGN, __VA_ARGS__)(__VA_ARGS__) # define _XBT_CLOG_ARG1(f) \ - fprintf(stderr,"%s:%d:" f, __FILE__, __LINE__) + fprintf(stderr,"%s:%d:\n" f, __FILE__, __LINE__) # define _XBT_CLOG_ARGN(f, ...) \ - fprintf(stderr,"%s:%d:" f, __FILE__, __LINE__, __VA_ARGS__) + fprintf(stderr,"%s:%d:\n" f, __FILE__, __LINE__, __VA_ARGS__) # define XBT_LOG(...) XBT_CLOG(0, __VA_ARGS__) #else # define XBT_CLOG_(catv, prio, ...) \ diff --git a/src/surf/network_ns3.c b/src/surf/network_ns3.c index 50cf119289..ea514d3805 100644 --- a/src/surf/network_ns3.c +++ b/src/surf/network_ns3.c @@ -18,6 +18,21 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_ns3, surf, "Logging specific to the SURF network NS3 module"); extern routing_global_t global_routing; +extern xbt_dict_t dict_socket; + +static double time_to_next_flow_completion = -1; + +static double ns3_share_resources(double min); +static void ns3_update_actions_state(double now, double delta); +static void finalize(void); +static surf_action_t communicate(const char *src_name, + const char *dst_name, double size, double rate); +static void action_suspend(surf_action_t action); +static void action_resume(surf_action_t action); +static int action_is_suspended(surf_action_t action); +static int action_unref(surf_action_t action); + +xbt_dynar_t IPV4addr; static void replace_str(char *str, const char *orig, const char *rep) { @@ -65,6 +80,8 @@ void parse_ns3_add_link(void) { XBT_DEBUG("NS3_ADD_LINK '%s'",A_surfxml_link_id); + if(!IPV4addr) IPV4addr = xbt_dynar_new(sizeof(char*),free); + tmgr_trace_t bw_trace; tmgr_trace_t state_trace; tmgr_trace_t lat_trace; @@ -234,44 +251,18 @@ static xbt_dynar_t ns3_get_route(const char *src, const char *dst) void parse_ns3_end_platform(void) { ns3_end_platform(); - - xbt_lib_cursor_t cursor = NULL; - char *name = NULL; - void **data = NULL; - XBT_DEBUG("link_lib"); - xbt_lib_foreach(link_lib, cursor, name, data) { - XBT_DEBUG("\tSee link '%s'\t--> NS3_LEVEL %p", - name, - data[NS3_LINK_LEVEL]); - } - XBT_DEBUG(" "); - XBT_DEBUG("host_lib"); - xbt_lib_foreach(host_lib, cursor, name, data) { - XBT_DEBUG("\tSee host '%s'\t--> NS3_LEVEL %p", - name, - data[NS3_HOST_LEVEL]); - } - XBT_DEBUG(" "); - XBT_DEBUG("as_router_lib"); - xbt_lib_foreach(as_router_lib, cursor, name, data) { - XBT_DEBUG("\tSee ASR '%s'\t--> NS3_LEVEL %p", - name, - data[NS3_ASR_LEVEL]); - } - - XBT_DEBUG(" "); } /* Create the ns3 topology based on routing strategy */ void create_ns3_topology() { - XBT_INFO("Starting topology generation"); + XBT_DEBUG("Starting topology generation"); //get the onelinks from the parsed platform xbt_dynar_t onelink_routes = global_routing->get_onelink_routes(); if (!onelink_routes) xbt_die("There is no routes!"); - XBT_INFO("Have get_onelink_routes, found %ld routes",onelink_routes->used); + XBT_DEBUG("Have get_onelink_routes, found %ld routes",onelink_routes->used); //save them in trace file onelink_t onelink; unsigned int iter; @@ -281,17 +272,15 @@ void create_ns3_topology() void *link = onelink->link_ptr; if( strcmp(src,dst) && ((surf_ns3_link_t)link)->created){ - XBT_INFO("Route from '%s' to '%s' with link '%s'",src,dst,((surf_ns3_link_t)link)->data->id); - char * link_bdw = xbt_strdup(((surf_ns3_link_t)link)->data->bdw); - char * link_lat = xbt_strdup(((surf_ns3_link_t)link)->data->lat); + XBT_DEBUG("Route from '%s' to '%s' with link '%s'",src,dst,((surf_ns3_link_t)link)->data->id); + char * link_bdw = bprintf("%sBps",((surf_ns3_link_t)link)->data->bdw); + char * link_lat = bprintf("%ss",(((surf_ns3_link_t)link)->data->lat)); ((surf_ns3_link_t)link)->created = 0; - replace_bdw_ns3(link_bdw); - replace_lat_ns3(link_lat); -// XBT_INFO("src (%s), dst (%s), src_id = %d, dst_id = %d",src,dst, src_id, dst_id); - XBT_INFO("\tLink (%s) bdw:%s->%s lat:%s->%s",((surf_ns3_link_t)link)->data->id, - ((surf_ns3_link_t)link)->data->bdw,link_bdw, - ((surf_ns3_link_t)link)->data->lat,link_lat + // XBT_DEBUG("src (%s), dst (%s), src_id = %d, dst_id = %d",src,dst, src_id, dst_id); + XBT_DEBUG("\tLink (%s) bdw:%s lat:%s",((surf_ns3_link_t)link)->data->id, + link_bdw, + link_lat ); //create link ns3 @@ -342,13 +331,39 @@ static void free_ns3_host(void * elmts) free(host); } +#ifdef HAVE_LATENCY_BOUND_TRACKING +static int ns3_get_link_latency_limited(surf_action_t action) +{ + return 0; +} +#endif + void surf_network_model_init_NS3(const char *filename) { + if (surf_network_model) + return; + surf_network_model = surf_model_init(); surf_network_model->name = "network NS3"; surf_network_model->extension.network.get_link_latency = ns3_get_link_latency; surf_network_model->extension.network.get_link_bandwidth = ns3_get_link_bandwidth; surf_network_model->extension.network.get_route = ns3_get_route; + + surf_network_model->model_private->share_resources = ns3_share_resources; + surf_network_model->model_private->update_actions_state = ns3_update_actions_state; + surf_network_model->model_private->finalize = finalize; + + surf_network_model->suspend = action_suspend; + surf_network_model->resume = action_resume; + surf_network_model->is_suspended = action_is_suspended; + surf_network_model->action_unref = action_unref; + surf_network_model->extension.network.communicate = communicate; + + /* Added the initialization for NS3 interface */ + if (ns3_initialize()) { + xbt_die("Impossible to initialize NS3 interface"); + } + routing_model_create(sizeof(s_surf_ns3_link_t), NULL, NULL); define_callbacks_ns3(filename); @@ -356,6 +371,106 @@ void surf_network_model_init_NS3(const char *filename) NS3_ASR_LEVEL = xbt_lib_add_level(as_router_lib,(void_f_pvoid_t)free_ns3_host); NS3_LINK_LEVEL = xbt_lib_add_level(link_lib,(void_f_pvoid_t)free_ns3_link); + xbt_dynar_push(model_list, &surf_network_model); update_model_description(surf_network_model_description, "NS3", surf_network_model); + +#ifdef HAVE_LATENCY_BOUND_TRACKING + surf_network_model->get_latency_limited = ns3_get_link_latency_limited; +#endif +} + +static void finalize(void) +{ + ns3_finalize(); + xbt_dynar_free_container(&IPV4addr); +} + +static double ns3_share_resources(double min) +{ + XBT_DEBUG("ns3_share_resources"); + + xbt_swag_t running_actions = + surf_network_model->states.running_action_set; + + //get the first relevant value from the running_actions list + if (!xbt_swag_size(running_actions)) + return -1.0; + + ns3_simulator(min); + time_to_next_flow_completion = ns3_time() - surf_get_clock(); + + xbt_assert(time_to_next_flow_completion, + "Time to next flow completion not initialized!\n"); + + XBT_DEBUG("ns3_share_resources return %f",time_to_next_flow_completion); + return time_to_next_flow_completion; +} + +static void ns3_update_actions_state(double now, double delta) +{ + xbt_dict_cursor_t cursor = NULL; + char *key; + void *data; + + surf_action_t action = NULL; + xbt_swag_t running_actions = + surf_network_model->states.running_action_set; + + /* If there are no running flows, just return */ + if (!xbt_swag_size(running_actions)) + return; + + xbt_dict_foreach(dict_socket,cursor,key,data){ + action = (surf_action_t)ns3_get_socket_action(data); + action->remains = ns3_get_socket_remains(data); + if(ns3_get_socket_is_finished(data) == 1){ + action->finish = now; + surf_action_state_set(action, SURF_ACTION_DONE); + } + } + return; +} + +/* Max durations are not supported */ +static surf_action_t communicate(const char *src_name, + const char *dst_name, double size, double rate) +{ + surf_action_t action = NULL; + + XBT_DEBUG("Communicate from %s to %s",src_name,dst_name); + action = surf_action_new(sizeof(s_surf_action_t), size, surf_network_model, 0); + + ns3_create_flow(src_name, dst_name, surf_get_clock(), size, action); + + return (surf_action_t) action; +} + +/* Suspend a flow() */ +static void action_suspend(surf_action_t action) +{ + THROW_UNIMPLEMENTED; +} + +/* Resume a flow() */ +static void action_resume(surf_action_t action) +{ + THROW_UNIMPLEMENTED; +} + +/* Test whether a flow is suspended */ +static int action_is_suspended(surf_action_t action) +{ + return 0; +} + +static int action_unref(surf_action_t action) +{ + action->refcount--; + if (!action->refcount) { + xbt_swag_remove(action, action->state_set); + surf_action_free(&action); + return 1; + } + return 0; } diff --git a/src/surf/ns3/ns3_interface.cc b/src/surf/ns3/ns3_interface.cc index 4542034b7a..8fcc51e0bf 100644 --- a/src/surf/ns3/ns3_interface.cc +++ b/src/surf/ns3/ns3_interface.cc @@ -5,6 +5,11 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "ns3_interface.h" +#include "ns3_simulator.h" +#include "xbt/lib.h" +#include "xbt/log.h" +#include "xbt/dynar.h" + #include "ns3/core-module.h" #include "ns3/simulator-module.h" #include "ns3/node-module.h" @@ -15,6 +20,10 @@ using namespace ns3; +extern xbt_lib_t host_lib; +extern int NS3_HOST_LEVEL; //host node for ns3 +extern xbt_dynar_t IPV4addr; + XBT_LOG_NEW_DEFAULT_SUBCATEGORY(interface_ns3, surf, "Logging specific to the SURF network NS3 module"); @@ -23,21 +32,87 @@ NodeContainer nodes; NodeContainer Cluster_nodes; Ipv4InterfaceContainer interfaces; + + int number_of_nodes = 0; int number_of_clusters_nodes = 0; int number_of_links = 1; int number_of_networks = 1; +int port_number = 1025; //Port number is limited from 1025 to 65 000 + +static NS3Sim* ns3_sim = 0; + +void ns3_simulator(double min){ + ns3_sim->simulator_stop(min); + ns3_sim->simulator_start(); +} + +void* ns3_get_socket_action(void *socket){ + return ns3_sim->get_action_from_socket(socket); +} + +double ns3_get_socket_remains(void *socket){ + return ns3_sim->get_remains_from_socket(socket); +} + +char ns3_get_socket_is_finished(void *socket){ + return ns3_sim->get_finished(socket); +} + + +double ns3_time(){ + return Simulator::Now().GetSeconds(); +} + +int ns3_create_flow(const char* a,const char *b,double start,u_int32_t TotalBytes,void * action) +{ + ns3_nodes_t node1 = (ns3_nodes_t) xbt_lib_get_or_null(host_lib,a,NS3_HOST_LEVEL); + ns3_nodes_t node2 = (ns3_nodes_t) xbt_lib_get_or_null(host_lib,b,NS3_HOST_LEVEL); + + Ptr src_node = nodes.Get(node1->node_num); + Ptr dst_node = nodes.Get(node2->node_num); + + char* addr = (char*)xbt_dynar_get_ptr(IPV4addr,node2->node_num); + + XBT_INFO("ns3_create_flow %d Bytes from %d to %d with Interface %s",TotalBytes, node1->node_num, node2->node_num,addr); + ns3_sim->create_flow_NS3(src_node, + dst_node, + port_number, + start, + addr, + TotalBytes, + action); + + port_number++; + if(port_number >= 65001 ) xbt_die("Too many connections! Port number is saturated."); + return 0; +} + +// clean up +int ns3_finalize(void){ + if (!ns3_sim) return -1; + delete ns3_sim; + ns3_sim = 0; + return 0; +} + +// initialize the NS3 interface and environment +int ns3_initialize(void){ + xbt_assert(!ns3_sim, "ns3 already initialized"); + ns3_sim = new NS3Sim(); + return 0; +} void * ns3_add_host(char * id) { ns3_nodes_t host = xbt_new0(s_ns3_nodes_t,1); - XBT_INFO("Interface ns3 add host[%d] '%s'",number_of_nodes,id); + XBT_DEBUG("Interface ns3 add host[%d] '%s'",number_of_nodes,id); Ptr node = CreateObject (0); stack.Install(node); nodes.Add(node); host->node_num = number_of_nodes; host->type = NS3_NETWORK_ELEMENT_HOST; - host->data = node; + host->data = GetPointer(node); number_of_nodes++; return host; } @@ -45,7 +120,7 @@ void * ns3_add_host(char * id) void * ns3_add_host_cluster(char * id) { ns3_nodes_t host = xbt_new0(s_ns3_nodes_t,1); - XBT_INFO("Interface ns3 add host[%d] '%s'",number_of_nodes,id); + XBT_DEBUG("Interface ns3 add host[%d] '%s'",number_of_nodes,id); Ptr node = CreateObject (0); stack.Install(node); Cluster_nodes.Add(node); @@ -60,7 +135,7 @@ void * ns3_add_host_cluster(char * id) void * ns3_add_router(char * id) { ns3_nodes_t router = xbt_new0(s_ns3_nodes_t,1); - XBT_INFO("Interface ns3 add router[%d] '%s'",number_of_nodes,id); + XBT_DEBUG("Interface ns3 add router[%d] '%s'",number_of_nodes,id); Ptr node = CreateObject (0); stack.Install(node); nodes.Add(node); @@ -118,10 +193,19 @@ void * ns3_add_cluster(char * bw,char * lat,char *id) void * ns3_add_AS(char * id) { - XBT_INFO("Interface ns3 add AS '%s'",id); + XBT_DEBUG("Interface ns3 add AS '%s'",id); return NULL; } +static char* transformIpv4Address (Ipv4Address from){ + std::stringstream sstream; + sstream << interfaces.GetAddress(interfaces.GetN()-2); + std::string s = sstream.str(); + size_t size = s.size() + 1; + char* IPaddr = bprintf("%s",s.c_str()); + return IPaddr; +} + void * ns3_add_link(int src,int dst,char * bw,char * lat) { if(number_of_links == 1 ) { @@ -146,9 +230,15 @@ void * ns3_add_link(int src,int dst,char * bw,char * lat) char * adr = bprintf("%d.%d.0.0",number_of_networks,number_of_links); address.SetBase (adr, "255.255.0.0"); XBT_DEBUG("\tInterface stack '%s'",adr); + free(adr); interfaces.Add(address.Assign (netA)); - XBT_DEBUG(" "); + xbt_dynar_set(IPV4addr,src, + transformIpv4Address(interfaces.GetAddress(interfaces.GetN()-2))); + + xbt_dynar_set(IPV4addr,dst, + transformIpv4Address(interfaces.GetAddress(interfaces.GetN()-1))); + if(number_of_links == 255){ if(number_of_networks == 255) xbt_die("Number of links and networks exceed 255*255"); @@ -161,48 +251,7 @@ void * ns3_add_link(int src,int dst,char * bw,char * lat) void * ns3_end_platform(void) { - XBT_INFO("InitializeRoutes"); + XBT_DEBUG("InitializeRoutes"); GlobalRouteManager::BuildGlobalRoutingDatabase(); GlobalRouteManager::InitializeRoutes(); - - //TODO REMOVE ;) - Ptr a = nodes.Get(0); - Ptr b = nodes.Get(1); - Ptr c = nodes.Get(2); - Ptr d = nodes.Get(3); - - UdpEchoServerHelper echoServer (9); - - ApplicationContainer serverApps = echoServer.Install (a); - serverApps.Start (Seconds (1.0)); - serverApps.Stop (Seconds (20.0)); - - UdpEchoClientHelper echoClient (interfaces.GetAddress (0), 9); - echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); - echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.))); - echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); - ApplicationContainer clientApps_b = echoClient.Install (b); - clientApps_b.Start (Seconds (2.0)); - clientApps_b.Stop (Seconds (10.0)); - - UdpEchoClientHelper echoClient2 (interfaces.GetAddress (0), 9); - echoClient2.SetAttribute ("MaxPackets", UintegerValue (1)); - echoClient2.SetAttribute ("Interval", TimeValue (Seconds (1.))); - echoClient2.SetAttribute ("PacketSize", UintegerValue (512)); - ApplicationContainer clientApps_c = echoClient2.Install (c); - clientApps_c.Start (Seconds (3.0)); - clientApps_c.Stop (Seconds (10.0)); - - UdpEchoClientHelper echoClient3 (interfaces.GetAddress (0), 9); - echoClient3.SetAttribute ("MaxPackets", UintegerValue (1)); - echoClient3.SetAttribute ("Interval", TimeValue (Seconds (1.))); - echoClient3.SetAttribute ("PacketSize", UintegerValue (256)); - ApplicationContainer clientApps_d = echoClient3.Install (d); - clientApps_d.Start (Seconds (4.0)); - clientApps_d.Stop (Seconds (10.0)); - - Simulator::Run (); - Simulator::Destroy (); - - //HEEEEEEE } diff --git a/src/surf/ns3/ns3_interface.h b/src/surf/ns3/ns3_interface.h index 73780c0007..e6d2187751 100644 --- a/src/surf/ns3/ns3_interface.h +++ b/src/surf/ns3/ns3_interface.h @@ -29,6 +29,14 @@ typedef struct ns3_nodes{ extern "C" { #endif +XBT_PUBLIC(int) ns3_finalize(void); +XBT_PUBLIC(int) ns3_initialize(void); +XBT_PUBLIC(int) ns3_create_flow(const char* a,const char *b,double start,u_int32_t TotalBytes,void * action); +XBT_PUBLIC(void) ns3_simulator(double min); +XBT_PUBLIC(double) ns3_time(void); +XBT_PUBLIC(void*) ns3_get_socket_action(void *socket); +XBT_PUBLIC(double) ns3_get_socket_remains(void *socket); +XBT_PUBLIC(char) ns3_get_socket_is_finished(void *socket); XBT_PUBLIC(void *) ns3_add_host(char * id); XBT_PUBLIC(void *) ns3_add_host_cluster(char * id); XBT_PUBLIC(void *) ns3_add_router(char * id); diff --git a/src/surf/ns3/ns3_simulator.cc b/src/surf/ns3/ns3_simulator.cc index 29fd20e182..41ef6345ab 100644 --- a/src/surf/ns3/ns3_simulator.cc +++ b/src/surf/ns3/ns3_simulator.cc @@ -5,6 +5,26 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "surf/ns3/ns3_simulator.h" +#include "xbt/dict.h" +#include "xbt/log.h" + +using namespace ns3; +using namespace std; + +static const uint32_t writeSize = 1024; // limit the amout of data to write +uint8_t data[writeSize]; +xbt_dict_t dict_socket = NULL; + +NS3Sim SimulatorNS3; + +static void receive_callback(Ptr localSocket); +static void send_callback(Ptr localSocket, uint32_t txSpace); +static void StartFlow(Ptr sock, + const char *to, + uint16_t port_number); + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simulator_ns3, surf, + "Logging specific to the SURF network NS3 module"); // Constructor. NS3Sim::NS3Sim(){ @@ -12,3 +32,118 @@ NS3Sim::NS3Sim(){ //Destructor. NS3Sim::~NS3Sim(){ } + +/* + * This function create a flow from src to dst + * + * Parameters + * src: node source + * dst: node destination + * port_number: The port number to use + * start: the time the communication start + * addr: ip address + * TotalBytes: number of bytes to transmit + */ +void NS3Sim::create_flow_NS3( + Ptr src, + Ptr dst, + uint16_t port_number, + double start, + const char *addr, + uint32_t TotalBytes, + void * action) +{ + if(!dict_socket) dict_socket = xbt_dict_new(); + PacketSinkHelper sink ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny(), port_number)); + sink.Install (dst); + Ptr sock = Socket::CreateSocket (src, TypeId::LookupByName ("ns3::TcpSocketFactory")); + MySocket *mysocket = new MySocket(); + mysocket->TotalBytes = TotalBytes; + mysocket->remaining = TotalBytes; + mysocket->sentBytes = 0; + mysocket->finished = 0; + mysocket->action = action; + xbt_dict_set(dict_socket,(const char*)&sock, mysocket,NULL); + sock->Bind(InetSocketAddress(port_number)); + Simulator::Schedule (Seconds(start),&StartFlow, sock, addr, port_number); +} + +void* NS3Sim::get_action_from_socket(void *socket){ + return ((MySocket *)socket)->action; +} + +char NS3Sim::get_finished(void *socket){ + return ((MySocket *)socket)->finished; +} + +double NS3Sim::get_remains_from_socket(void *socket){ + return ((MySocket *)socket)->remaining; +} + +void NS3Sim::simulator_stop(double min){ + if(min > 0.0) + Simulator::Stop(Seconds(min)); + else + Simulator::Stop(); +} + +void NS3Sim::simulator_start(void){ + XBT_DEBUG("Start simulator"); + Simulator::Run (); +} + +static void receive_callback(Ptr localSocket){ + Address addr; + localSocket->GetSockName (addr); + InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (addr); + MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket); + mysocket->finished = 1; + + //cout << "[" << Simulator::Now ().GetSeconds() << "] " << "Received [" << mysocket->TotalBytes << "bytes], from: " << iaddr.GetIpv4 () << " port: " << iaddr.GetPort () << endl; + std::stringstream sstream; + sstream << Simulator::Now ().GetSeconds(); + std::string s = sstream.str(); + size_t size = s.size() + 1; + char * time_sec = new char[ size ]; + strncpy( time_sec, s.c_str(), size ); + XBT_DEBUG("Stop simulator at %s seconds",time_sec); + Simulator::Stop(); +} + +static void send_callback(Ptr localSocket, uint32_t txSpace){ + + Address addr; + localSocket->GetSockName (addr); + InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (addr); + MySocket* mysocket = (MySocket*)xbt_dict_get_or_null(dict_socket,(char*)&localSocket); + uint32_t totalBytes = mysocket->TotalBytes; + while ((mysocket->sentBytes) < totalBytes && localSocket->GetTxAvailable () > 0){ + uint32_t toWrite = min ((mysocket->remaining), writeSize); + toWrite = min (toWrite, localSocket->GetTxAvailable ()); + int amountSent = localSocket->Send (&data[0], toWrite, 0); + +// cout << Simulator::Now () << " AmountSend: " << amountSent << " Towrite: " << toWrite << endl; + if(amountSent < 0) + return; + (mysocket->sentBytes) += amountSent; + (mysocket->remaining) -= amountSent; + //cout << "[" << Simulator::Now ().GetSeconds() << "] " << "Send one packet, remaining "<< mysocket->remaining << " bytes!" << endl; + } + if ((mysocket->sentBytes) >= totalBytes){ + localSocket->Close(); + } + +} + +static void StartFlow(Ptr sock, + const char *to, + uint16_t port_number) +{ + InetSocketAddress serverAddr (to, port_number); + + //cout << "[" << Simulator::Now().GetSeconds() << "] Starting flow to " << to << " using port " << port_number << endl; + + sock->Connect(serverAddr); + sock->SetSendCallback (MakeCallback (&send_callback)); + sock->SetRecvCallback (MakeCallback (&receive_callback)); +} diff --git a/src/surf/ns3/ns3_simulator.h b/src/surf/ns3/ns3_simulator.h index dce821b559..096667067e 100644 --- a/src/surf/ns3/ns3_simulator.h +++ b/src/surf/ns3/ns3_simulator.h @@ -9,15 +9,45 @@ #ifdef __cplusplus +#include "ns3/core-module.h" +#include "ns3/helper-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" +#include "ns3/global-routing-module.h" +#include "ns3/tcp-socket-factory.h" + +using namespace ns3; +using namespace std; + +struct MySocket{ + uint32_t sentBytes; + uint32_t remaining; + uint32_t TotalBytes; + char finished; + void* action; +}; + //Simulator s; class NS3Sim { - NS3Sim(); - ~NS3Sim(); private: public: - + NS3Sim(); + ~NS3Sim(); + void create_flow_NS3(Ptr src, + Ptr dst, + uint16_t port_number, + double start, + const char *addr, + uint32_t TotalBytes, + void * action); + void simulator_stop(double min); + void simulator_start(void); + void* get_action_from_socket(void *socket); + double get_remains_from_socket(void *socket); + char get_finished(void *socket); }; #endif /* __cplusplus */ diff --git a/src/surf/surf.c b/src/surf/surf.c index bd4660229c..09c7ccd220 100644 --- a/src/surf/surf.c +++ b/src/surf/surf.c @@ -442,14 +442,30 @@ double surf_solve(double max_date) XBT_DEBUG("Looking for next action end"); xbt_dynar_foreach(model_list, iter, model) { - XBT_DEBUG("Running for Resource [%s]", model->name); - model_next_action_end = model->model_private->share_resources(NOW); - XBT_DEBUG("Resource [%s] : next action end = %f", - model->name, model_next_action_end); - if (((min < 0.0) || (model_next_action_end < min)) - && (model_next_action_end >= 0.0)) - min = model_next_action_end; + + if(strcmp(model->name,"network NS3") ){ + XBT_DEBUG("Running for Resource [%s]", model->name); + model_next_action_end = model->model_private->share_resources(NOW); + XBT_DEBUG("Resource [%s] : next action end = %f", + model->name, model_next_action_end); + if (((min < 0.0) || (model_next_action_end < min)) + && (model_next_action_end >= 0.0)) + min = model_next_action_end; + } } + + XBT_DEBUG("Min for other resources : %f", min); + + + if(surf_network_model->name && !strcmp(surf_network_model->name,"network NS3")){ + // run until min or next flow + model_next_action_end = surf_network_model->model_private->share_resources(min); + XBT_DEBUG("Min for NS3 : %f", model_next_action_end); + if ( ((min < 0.0) || (model_next_action_end < min)) && ( model_next_action_end >= 0.0 )) + min = model_next_action_end; + } + + XBT_DEBUG("Next action end : %f", min); XBT_DEBUG("Looking for next event"); diff --git a/src/xbt/log.c b/src/xbt/log.c index e4030ef62a..6915419132 100644 --- a/src/xbt/log.c +++ b/src/xbt/log.c @@ -626,10 +626,6 @@ void _xbt_log_event_log(xbt_log_event_t ev, const char *fmt, ...) } va_end(ev->ap); va_end(ev->ap_copy); - -#ifdef _XBT_WIN32 - free(ev->buffer); -#endif } /* NOTE: diff --git a/src/xbt/win32_ucontext.c b/src/xbt/win32_ucontext.c index 757eb43a70..c91c39e426 100644 --- a/src/xbt/win32_ucontext.c +++ b/src/xbt/win32_ucontext.c @@ -21,6 +21,7 @@ */ #include "win32_ucontext.h" + int getcontext(ucontext_t * ucp) { int ret; @@ -45,12 +46,12 @@ int makecontext(ucontext_t * ucp, void (*func) (), int argc, ...) int i; va_list ap; char *sp; - - /* Stack grows down */ + + /* Stack grows down */ sp = (char *) (size_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size; /* Reserve stack space for the arguments (maximum possible: argc*(8 bytes per argument)) */ - sp -= argc * 8; + sp -= argc * sizeof(void*); if (sp < (char *) ucp->uc_stack.ss_sp) { /* errno = ENOMEM; */ @@ -59,15 +60,15 @@ int makecontext(ucontext_t * ucp, void (*func) (), int argc, ...) /* Set the instruction and the stack pointer */ #ifdef I_X86_ - ucp->uc_mcontext.Eip = (unsigned long) func; - ucp->uc_mcontext.Esp = (unsigned long) sp - 4; + ucp->uc_mcontext.Eip = (DWORD) func; + ucp->uc_mcontext.Esp = (DWORD) sp - sizeof(void*); #endif #ifdef _IA64_ # error "_IA64_" #endif #ifdef _AMD64_ - ucp->uc_mcontext.Rip = (unsigned long long) func; - ucp->uc_mcontext.Rsp = (unsigned long long) sp - 8; + ucp->uc_mcontext.Rip = (DWORD64) func; + ucp->uc_mcontext.Rsp = (DWORD64) sp - sizeof(void*); #endif /* Save/Restore the full machine context */ @@ -76,9 +77,9 @@ int makecontext(ucontext_t * ucp, void (*func) (), int argc, ...) /* Copy the arguments */ va_start(ap, argc); for (i = 0; i < argc; i++) { - memcpy(sp, ap, 8); - ap += 8; - sp += 8; + memcpy(sp, ap, sizeof(void*)); + ap += sizeof(void*); + sp += sizeof(void*); } va_end(ap); return 0; diff --git a/teshsuite/simdag/platforms/CMakeLists.txt b/teshsuite/simdag/platforms/CMakeLists.txt index 29421a9f95..c1452468b1 100644 --- a/teshsuite/simdag/platforms/CMakeLists.txt +++ b/teshsuite/simdag/platforms/CMakeLists.txt @@ -5,20 +5,20 @@ set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}") add_executable(basic_parsing_test basic_parsing_test.c) add_executable(is_router_test is_router_test.c) add_executable(flatifier flatifier.c) -if(NOT WIN32) +if(NOT WIN32 AND NOT APPLE) add_executable(evaluate_parse_time Evaluate_parse_time.c) add_executable(evaluate_get_route_time Evaluate_get_route_time.c) -endif(NOT WIN32) +endif(NOT WIN32 AND NOT APPLE) ### Add definitions for compile -if(NOT WIN32) +if(NOT WIN32 AND NOT APPLE) target_link_libraries(evaluate_get_route_time simgrid m) target_link_libraries(evaluate_parse_time simgrid m) target_link_libraries(basic_parsing_test simgrid m) target_link_libraries(is_router_test simgrid m) target_link_libraries(flatifier simgrid m) -else(NOT WIN32) +else(NOT WIN32 AND NOT APPLE) target_link_libraries(basic_parsing_test simgrid) target_link_libraries(is_router_test simgrid) target_link_libraries(flatifier simgrid) -endif(NOT WIN32) \ No newline at end of file +endif(NOT WIN32 AND NOT APPLE) \ No newline at end of file