/** \ingroup msg_task_usage * \brief Checks whether a communication is done, and if yes, finalizes it. * \param comm the communication to test * \return TRUE if the communication is finished * (but it may have failed, use MSG_comm_get_status() to know its status) * or FALSE if the communication is not finished yet * If the status is FALSE, don't forget to use MSG_process_sleep() after the test. */ int MSG_comm_test(msg_comm_t comm) { xbt_ex_t e; int finished = 0; TRY { finished = simcall_comm_test(comm->s_comm); if (finished && comm->task_received != NULL) { /* I am the receiver */ if (msg_global->debug_multiple_use && (*comm->task_received)->simdata->isused!=0) xbt_ex_free(*(xbt_ex_t*)(*comm->task_received)->simdata->isused); (*comm->task_received)->simdata->isused = 0; } } CATCH(e) { switch (e.category) { case network_error: comm->status = MSG_TRANSFER_FAILURE; finished = 1; break; case timeout_error: comm->status = MSG_TIMEOUT; finished = 1; break; default: RETHROW; } xbt_ex_free(e); } return finished; }
/** Victim. This process gets a lot of remote exceptions */ static int victim(int argc, char *argv[]) { xbt_ex_t e; msg_error_t res = MSG_OK; XBT_INFO("Let's work."); TRY { res = MSG_task_execute(MSG_task_create("Task", 1e14, 0, NULL)); if (res != MSG_OK) { XBT_INFO("The MSG_task_execute caught the exception for me and returned %d)",res); } else { xbt_die("I was expecting an exception during my execution!"); } } CATCH(e) { XBT_INFO("The received exception resumed my execution. Good. Here is it: ----------------------->8----"); xbt_ex_display(&e); XBT_INFO("(end of the first exception) ----8<------------------------"); xbt_ex_free(e); } XBT_INFO("Let's get suspended."); int gotit = 0; TRY { MSG_process_suspend(MSG_process_self()); } CATCH(e) { XBT_INFO("The received exception resumed my suspension. Good. Here is it: ----------------------->8----"); xbt_ex_display(&e); XBT_INFO("(end of the second exception) ----8<------------------------"); gotit = 1; xbt_ex_free(e); } if(!gotit) { xbt_die("I was expecting an exception during my suspension!"); } XBT_INFO("Let's sleep for 10 seconds."); TRY { res = MSG_process_sleep(10); if (res != MSG_OK) { XBT_INFO("The MSG_process_sleep caught the exception for me and returned %d)",res); } else { xbt_die("I was expecting to get an exception during my nap."); } } CATCH(e) { XBT_INFO("Got the second exception: ----------------------->8----"); xbt_ex_display(&e); XBT_INFO("(end of the third exception) ----8<------------------------"); xbt_ex_free(e); } XBT_INFO("Let's try a last time to do something on something"); MSG_process_sleep(10); XBT_INFO("That's enough now. I quit."); return 0; }
/** \ingroup msg_mailbox_management * \brief Get a task from a mailbox on a given host at a given rate * * \param mailbox The mailbox where the task was sent * \param task a memory location for storing a #msg_task_t. * \param host a #msg_host_t host from where the task was sent * \param timeout a timeout * \param rate a rate * \return Returns * #MSG_OK if the task was successfully received, * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise. */ msg_error_t MSG_mailbox_get_task_ext_bounded(msg_mailbox_t mailbox, msg_task_t * task, msg_host_t host, double timeout, double rate) { xbt_ex_t e; msg_error_t ret = MSG_OK; /* We no longer support getting a task from a specific host */ if (host) THROW_UNIMPLEMENTED; TRACE_msg_task_get_start(); double start_time = MSG_get_clock(); /* Sanity check */ xbt_assert(task, "Null pointer for the task storage"); if (*task) XBT_WARN ("Asked to write the received task in a non empty struct -- proceeding."); /* Try to receive it by calling SIMIX network layer */ TRY { simcall_comm_recv(mailbox, task, NULL, NULL, NULL, NULL, timeout, rate); XBT_DEBUG("Got task %s from %p",(*task)->name,mailbox); if (msg_global->debug_multiple_use && (*task)->simdata->isused!=0) xbt_ex_free(*(xbt_ex_t*)(*task)->simdata->isused); (*task)->simdata->isused = 0; } CATCH(e) { switch (e.category) { case cancel_error: ret = MSG_HOST_FAILURE; break; case network_error: ret = MSG_TRANSFER_FAILURE; break; case timeout_error: ret = MSG_TIMEOUT; break; case host_error: ret = MSG_HOST_FAILURE; break; default: RETHROW; } xbt_ex_free(e); } if (ret != MSG_HOST_FAILURE && ret != MSG_TRANSFER_FAILURE && ret != MSG_TIMEOUT) { TRACE_msg_task_get_end(start_time, *task); } MSG_RETURN(ret); }
void xbt_backtrace_display(xbt_ex_t * e) { xbt_ex_setup_backtrace(e); #ifdef HAVE_BACKTRACE if (e->used == 0) { fprintf(stderr, "(backtrace not set)\n"); } else { int i; fprintf(stderr, "Backtrace (displayed in thread %p):\n", (void *) xbt_thread_self()); for (i = 1; i < e->used; i++) /* no need to display "xbt_display_backtrace" */ fprintf(stderr, "---> %s\n", e->bt_strings[i] + 4); } /* don't fool xbt_ex_free with uninitialized msg field */ e->msg = NULL; e->remote = 0; xbt_ex_free(*e); #else XBT_ERROR("No backtrace on this arch"); #endif }
/** \ingroup msg_task_usage * \brief Receives a task from a mailbox from a specific host with a given timeout. * * This is a blocking function with a timeout, the execution flow will be blocked * until the task is received or the timeout is achieved. See #MSG_task_irecv * for receiving tasks asynchronously. You can provide a -1 timeout * to obtain an infinite timeout. * * \param task a memory location for storing a #msg_task_t. * \param alias name of the mailbox to receive the task from * \param timeout is the maximum wait time for completion (provide -1 for no timeout) * \param host a #msg_host_t host from where the task was sent * * \return Returns * #MSG_OK if the task was successfully received, * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise. */ msg_error_t MSG_task_receive_ext(msg_task_t * task, const char *alias, double timeout, msg_host_t host) { xbt_ex_t e; msg_error_t ret = MSG_OK; XBT_DEBUG ("MSG_task_receive_ext: Trying to receive a message on mailbox '%s'", alias); TRY { ret = MSG_mailbox_get_task_ext(MSG_mailbox_get_by_alias(alias), task, host, timeout); } CATCH(e) { switch (e.category) { case cancel_error: /* may be thrown by MSG_mailbox_get_by_alias */ ret = MSG_HOST_FAILURE; break; default: RETHROW; } xbt_ex_free(e); } return ret; }
/** \ingroup msg_task_usage * \brief Sleep for the specified number of seconds * * Makes the current process sleep until \a time seconds have elapsed. * * \param nb_sec a number of second */ msg_error_t MSG_process_sleep(double nb_sec) { xbt_ex_t e; msg_error_t status = MSG_OK; /*msg_process_t proc = MSG_process_self();*/ TRACE_msg_process_sleep_in(MSG_process_self()); TRY { simcall_process_sleep(nb_sec); } CATCH(e) { switch (e.category) { case cancel_error: XBT_DEBUG("According to the JAVA API, a sleep call should only deal with HostFailureException, WTF here ?"); // adsein: MSG_TASK_CANCELED is assigned when someone kills the process that made the sleep, this is not // correct. For instance, when the node is turned off, the error should be MSG_HOST_FAILURE, which is by the way // and according to the JAVA document, the only exception that can be triggered by MSG_Process_sleep call. // To avoid possible impacts in the code, I just raised a host_failure exception for the moment in the JAVA code // and did not change anythings at the C level. // See comment in the jmsg_process.c file, function JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_sleep(JNIEnv *env, jclass cls, jlong jmillis, jint jnanos) status = MSG_TASK_CANCELED; break; default: RETHROW; } xbt_ex_free(e); } TRACE_msg_process_sleep_out(MSG_process_self()); MSG_RETURN(status); }
JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_acquire(JNIEnv * env, jobject obj) { xbt_mutex_t mutex; mutex = (xbt_mutex_t) (uintptr_t) env->GetLongField(obj, jsyncro_field_Mutex_bind); xbt_ex_t e; TRY { xbt_mutex_acquire(mutex); } CATCH(e) { xbt_ex_free(e); } }
int client(int argc, char *argv[]) { gras_socket_t mysock; /* socket on which I listen */ gras_socket_t toserver; /* socket used to write to the server */ gras_init(&argc, argv); message_declaration(); mysock = gras_socket_server_range(1024, 10000, 0, 0); XBT_VERB("Client ready; listening on %d", gras_socket_my_port(mysock)); gras_os_sleep(1.5); /* sleep 1 second and half */ toserver = gras_socket_client(argv[1], atoi(argv[2])); long long_to_convert = 4321; char *string_result; XBT_INFO("Ask to convert %ld", long_to_convert); gras_msg_rpccall(toserver, 60, "convert i2a", &long_to_convert, &string_result); XBT_INFO("The server says that %ld is equal to \"%s\".", long_to_convert, string_result); free(string_result); char *string_to_convert = "1234"; long long_result; XBT_INFO("Ask to convert %s", string_to_convert); gras_msg_rpccall(toserver, 60, "convert a2i", &string_to_convert, &long_result); XBT_INFO("The server says that \"%s\" is equal to %d.", string_to_convert, long_result); xbt_ex_t e; string_to_convert = "azerty"; TRY { gras_msg_rpccall(toserver, 60, "convert a2i", &string_to_convert, &long_result); } CATCH(e) { XBT_INFO ("The server refuses to convert %s. Here is the received exception:", string_to_convert); xbt_ex_display(&e); xbt_ex_free(e); XBT_INFO("Again, previous exception was excepted"); } gras_msg_send(toserver, "done", NULL); XBT_INFO("Stopped the server"); gras_exit(); return 0; }
val_t PJ_value_get_or_new (const char *name, const char *color, type_t father) { val_t ret = 0; xbt_ex_t e; TRY { ret = PJ_value_get(name, father); } CATCH(e) { xbt_ex_free(e); ret = PJ_value_new(name, color, father); } return ret; }
/** @brief Returns a boolean indicating whether the element is part of the dynar * * Beware that if your dynar contains pointed values (such as strings) instead of scalar, this function is probably not * what you want. Check the documentation of xbt_dynar_search() for more info. */ int xbt_dynar_member(xbt_dynar_t const dynar, void *const elem) { xbt_ex_t e; TRY { xbt_dynar_search(dynar, elem); } CATCH(e) { if (e.category == not_found_error) { xbt_ex_free(e); return 0; } RETHROW; } return 1; }
/** @brief locks on a semaphore object up until the provided timeout expires */ msg_error_t MSG_sem_acquire_timeout(msg_sem_t sem, double timeout) { xbt_ex_t e; msg_error_t res = MSG_OK; TRY { simcall_sem_acquire_timeout(sem,timeout); } CATCH(e) { if (e.category == timeout_error) { res = MSG_TIMEOUT; xbt_ex_free(e); } else { RETHROW; } } return res; }
/** \ingroup m_task_usage * \brief Cancel a #msg_task_t. * \param task the task to cancel. If it was executed or transfered, it stops the process that were working on it. */ msg_error_t MSG_task_cancel(msg_task_t task) { xbt_assert((task != NULL), "Cannot cancel a NULL task"); if (task->simdata->compute) { simcall_process_execution_cancel(task->simdata->compute); } else if (task->simdata->comm) { simdata_task_t simdata = task->simdata; simcall_comm_cancel(simdata->comm); if (msg_global->debug_multiple_use && simdata->isused!=0) xbt_ex_free(*(xbt_ex_t*)simdata->isused); simdata->isused = 0; } return MSG_OK; }
JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_restart (JNIEnv *env, jobject jprocess) { msg_process_t process = jprocess_to_native_process(jprocess, env); xbt_ex_t e; if (!process) { jxbt_throw_notbound(env, "process", jprocess); return; } TRY { MSG_process_restart(process); } CATCH (e) { xbt_ex_free(e); } }
JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_setAutoRestart (JNIEnv *env, jobject jprocess, jboolean jauto_restart) { msg_process_t process = jprocess_to_native_process(jprocess, env); xbt_ex_t e; int auto_restart = jauto_restart == JNI_TRUE ? 1 : 0; if (!process) { jxbt_throw_notbound(env, "process", jprocess); return; } TRY { MSG_process_auto_restart_set(process,auto_restart); } CATCH (e) { xbt_ex_free(e); } }
void xbt_multidict_remove_ext(xbt_dict_t mdict, xbt_dynar_t keys, xbt_dynar_t lens) { volatile xbt_dict_t thislevel; volatile xbt_dict_t nextlevel = NULL; volatile int i; xbt_ex_t e; unsigned long int thislen; char *thiskey; int keys_len = xbt_dynar_length(keys); xbt_assert(xbt_dynar_length(keys) == xbt_dynar_length(lens)); xbt_assert(xbt_dynar_length(keys), "Can't remove a zero-long key set in a multidict"); for (i = 0, thislevel = mdict; i < keys_len - 1; i++, thislevel = nextlevel) { xbt_dynar_get_cpy(keys, i, &thiskey); xbt_dynar_get_cpy(lens, i, &thislen); /* search the dict of next level */ TRY { nextlevel = xbt_dict_get_ext(thislevel, thiskey, thislen); } CATCH(e) { /* If non-existant entry, nothing to do */ if (e.category == arg_error) xbt_ex_free(e); else RETHROW; } } xbt_dynar_get_cpy(keys, i, &thiskey); xbt_dynar_get_cpy(lens, i, &thislen); xbt_dict_remove_ext(thislevel, thiskey, thislen); }
int smpi_shared_known_call(const char* func, const char* input) { char* loc = bprintf("%s:%s", func, input); xbt_ex_t ex; int known; if(!calls) { calls = xbt_dict_new_homogeneous(NULL); } TRY { xbt_dict_get(calls, loc); /* Succeed or throw */ known = 1; } CATCH(ex) { if(ex.category == not_found_error) { known = 0; xbt_ex_free(ex); } else { RETHROW; } } free(loc); return known; }
/** \ingroup msg_task_usage * \brief Sleep for the specified number of seconds * * Makes the current process sleep until \a time seconds have elapsed. * * \param nb_sec a number of second */ msg_error_t MSG_process_sleep(double nb_sec) { xbt_ex_t e; msg_error_t status = MSG_OK; /*msg_process_t proc = MSG_process_self();*/ #ifdef HAVE_TRACING TRACE_msg_process_sleep_in(MSG_process_self()); #endif /* create action to sleep */ /*proc->simdata->waiting_action = act_sleep; FIXME: check if not setting the waiting_action breaks something on msg proc->simdata->waiting_action = NULL;*/ TRY { simcall_process_sleep(nb_sec); } CATCH(e) { switch (e.category) { case cancel_error: status = MSG_TASK_CANCELED; break; default: RETHROW; } xbt_ex_free(e); } #ifdef HAVE_TRACING TRACE_msg_process_sleep_out(MSG_process_self()); #endif MSG_RETURN(status); }
static int xbt_log_layout_format_doit(xbt_log_layout_t l, xbt_log_event_t ev, const char *msg_fmt) { char *p = ev->buffer; int rem_size = ev->buffer_size; int precision = -1; int length = -1; char *q; for (q = l->data ; *q != '\0' ; q++) { if (*q == '%') { q++; handle_modifier: switch (*q) { case '\0': fprintf(stderr, "Layout format (%s) ending with %%\n", (char *)l->data); xbt_abort(); case '%': *p = '%'; check_overflow(1); break; case 'n': /* platform-dependant line separator; LOG4J compliant */ *p = '\n'; check_overflow(1); break; case 'e': /* plain space; SimGrid extension */ *p = ' '; check_overflow(1); break; case '.': /* precision specifier */ precision = strtol(q + 1, &q, 10); goto handle_modifier; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* length modifier */ length = strtol(q, &q, 10); goto handle_modifier; case 'c': /* category name; LOG4J compliant should accept a precision postfix to show the hierarchy */ show_string(ev->cat->name); break; case 'p': /* priority name; LOG4J compliant */ show_string(xbt_log_priority_names[ev->priority]); break; case 'h': /* host name; SimGrid extension */ show_string(SIMIX_host_self_get_name()); break; case 't': /* thread name; LOG4J compliant */ show_string(xbt_thread_self_name()); break; case 'P': /* process name; SimGrid extension */ show_string(xbt_procname()); break; case 'i': /* process PID name; SimGrid extension */ show_int(xbt_getpid()); break; case 'F': /* file name; LOG4J compliant */ show_string(ev->fileName); break; case 'l': { /* location; LOG4J compliant */ int len, sz; set_sz_from_precision(); len = snprintf(p, sz, "%s:%d", ev->fileName, ev->lineNum); check_overflow(MIN(sz, len)); break; } case 'L': /* line number; LOG4J compliant */ show_int(ev->lineNum); break; case 'M': /* method (ie, function) name; LOG4J compliant */ show_string(ev->functionName); break; case 'b': /* backtrace; called %throwable in LOG4J */ case 'B': /* short backtrace; called %throwable{short} in LOG4J */ #if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE) { xbt_ex_t e; e.used = backtrace((void **) e.bt, XBT_BACKTRACE_SIZE); e.bt_strings = NULL; e.msg = NULL; xbt_ex_setup_backtrace(&e); if (*q == 'B') { show_string(e.bt_strings[1] + 8); } else { xbt_strbuff_t buff = xbt_strbuff_new(); int i; xbt_strbuff_append(buff, e.bt_strings[1] + 8); for (i = 2; i < e.used; i++) { xbt_strbuff_append(buff, "\n"); xbt_strbuff_append(buff, e.bt_strings[i] + 8); } show_string(buff->data); xbt_strbuff_free(buff); } xbt_ex_free(e); } #else show_string("(no backtrace on this arch)"); #endif break; case 'd': /* date; LOG4J compliant */ show_double(surf_get_clock()); break; case 'r': /* application age; LOG4J compliant */ show_double(surf_get_clock() - format_begin_of_time); break; case 'm': { /* user-provided message; LOG4J compliant */ int len, sz; set_sz_from_precision(); len = vsnprintf(p, sz, msg_fmt, ev->ap); check_overflow(MIN(sz, len)); break; } default: fprintf(stderr, ERRMSG, *q, (char *)l->data); xbt_abort(); } } else { *p = *q; check_overflow(1); } } *p = '\0'; return 1; }
int main(int argc, char **argv) { int i; unsigned int ctr; const char *platform_file; const SD_workstation_t *workstations; const char *name1; const char *name2; double computation_amount1; double computation_amount2; double communication_amount12; double communication_amount21; const SD_link_t *route; int route_size; SD_task_t task, taskA, taskB, taskC, taskD, checkB, checkD; xbt_dynar_t changed_tasks; xbt_ex_t ex; const int workstation_number = 2; SD_workstation_t workstation_list[2]; double computation_amount[2]; double communication_amount[4] = { 0 }; double rate = -1.0; SD_workstation_t w1, w2; /* initialization of SD */ SD_init(&argc, argv); /* xbt_log_control_set("sd.thres=debug"); */ if (argc < 2) { XBT_INFO("Usage: %s platform_file", argv[0]); XBT_INFO("example: %s sd_platform.xml", argv[0]); exit(1); } /* creation of the environment */ platform_file = argv[1]; SD_create_environment(platform_file); /* test the estimation functions */ workstations = SD_workstation_get_list(); w1 = workstations[0]; w2 = workstations[1]; SD_workstation_set_access_mode(w2, SD_WORKSTATION_SEQUENTIAL_ACCESS); name1 = SD_workstation_get_name(w1); name2 = SD_workstation_get_name(w2); computation_amount1 = 2000000; computation_amount2 = 1000000; communication_amount12 = 2000000; communication_amount21 = 3000000; XBT_INFO("Computation time for %f flops on %s: %f", computation_amount1, name1, SD_workstation_get_computation_time(w1, computation_amount1)); XBT_INFO("Computation time for %f flops on %s: %f", computation_amount2, name2, SD_workstation_get_computation_time(w2, computation_amount2)); XBT_INFO("Route between %s and %s:", name1, name2); route = SD_route_get_list(w1, w2); route_size = SD_route_get_size(w1, w2); for (i = 0; i < route_size; i++) { XBT_INFO(" Link %s: latency = %f, bandwidth = %f", SD_link_get_name(route[i]), SD_link_get_current_latency(route[i]), SD_link_get_current_bandwidth(route[i])); } XBT_INFO("Route latency = %f, route bandwidth = %f", SD_route_get_current_latency(w1, w2), SD_route_get_current_bandwidth(w1, w2)); XBT_INFO("Communication time for %f bytes between %s and %s: %f", communication_amount12, name1, name2, SD_route_get_communication_time(w1, w2, communication_amount12)); XBT_INFO("Communication time for %f bytes between %s and %s: %f", communication_amount21, name2, name1, SD_route_get_communication_time(w2, w1, communication_amount21)); /* creation of the tasks and their dependencies */ taskA = SD_task_create("Task A", NULL, 10.0); taskB = SD_task_create("Task B", NULL, 40.0); taskC = SD_task_create("Task C", NULL, 30.0); taskD = SD_task_create("Task D", NULL, 60.0); /* try to attach and retrieve user data to a task */ SD_task_set_data(taskA, (void*) &computation_amount1); if (computation_amount1 != (*((double*) SD_task_get_data(taskA)))) XBT_ERROR("User data was corrupted by a simple set/get"); SD_task_dependency_add(NULL, NULL, taskB, taskA); SD_task_dependency_add(NULL, NULL, taskC, taskA); SD_task_dependency_add(NULL, NULL, taskD, taskB); SD_task_dependency_add(NULL, NULL, taskD, taskC); /* SD_task_dependency_add(NULL, NULL, taskA, taskD); /\* deadlock */ TRY { SD_task_dependency_add(NULL, NULL, taskA, taskA); /* shouldn't work and must raise an exception */ xbt_die("Hey, I can add a dependency between Task A and Task A!"); } CATCH(ex) { if (ex.category != arg_error) RETHROW; /* this is a serious error */ xbt_ex_free(ex); } TRY { SD_task_dependency_add(NULL, NULL, taskB, taskA); /* shouldn't work and must raise an exception */ xbt_die("Oh oh, I can add an already existing dependency!"); } CATCH(ex) { if (ex.category != arg_error) RETHROW; xbt_ex_free(ex); } TRY { SD_task_dependency_remove(taskA, taskC); /* shouldn't work and must raise an exception */ xbt_die("Dude, I can remove an unknown dependency!"); } CATCH(ex) { if (ex.category != arg_error) RETHROW; xbt_ex_free(ex); } TRY { SD_task_dependency_remove(taskC, taskC); /* shouldn't work and must raise an exception */ xbt_die("Wow, I can remove a dependency between Task C and itself!"); } CATCH(ex) { if (ex.category != arg_error) RETHROW; xbt_ex_free(ex); } /* if everything is ok, no exception is forwarded or rethrown by main() */ /* watch points */ SD_task_watch(taskD, SD_DONE); SD_task_watch(taskB, SD_DONE); SD_task_unwatch(taskD, SD_DONE); /* scheduling parameters */ workstation_list[0] = w1; workstation_list[1] = w2; computation_amount[0] = computation_amount1; computation_amount[1] = computation_amount2; communication_amount[1] = communication_amount12; communication_amount[2] = communication_amount21; /* estimated time */ task = taskD; XBT_INFO("Estimated time for '%s': %f", SD_task_get_name(task), SD_task_get_execution_time(task, workstation_number, workstation_list, computation_amount, communication_amount)); /* let's launch the simulation! */ SD_task_schedule(taskA, workstation_number, workstation_list, computation_amount, communication_amount, rate); SD_task_schedule(taskB, workstation_number, workstation_list, computation_amount, communication_amount, rate); SD_task_schedule(taskC, workstation_number, workstation_list, computation_amount, communication_amount, rate); SD_task_schedule(taskD, workstation_number, workstation_list, computation_amount, communication_amount, rate); changed_tasks = SD_simulate(-1.0); xbt_dynar_foreach(changed_tasks, ctr, task) { XBT_INFO("Task '%s' start time: %f, finish time: %f", SD_task_get_name(task), SD_task_get_start_time(task), SD_task_get_finish_time(task)); }
int main(int argc, char**argv) { void *heapA; void *pointers[TESTSIZE]; xbt_init(&argc,argv); XBT_INFO("Allocating a new heap"); heapA = xbt_mheap_new(-1, ((char*)sbrk(0)) + BUFFSIZE); if (heapA == NULL) { perror("attach 1 failed"); fprintf(stderr, "bye\n"); exit(1); } XBT_INFO("HeapA allocated"); int i, size; for (i = 0; i < TESTSIZE; i++) { size = size_of_block(i); pointers[i] = mmalloc(heapA, size); XBT_INFO("%d bytes allocated with offset %tx", size, ((char*)pointers[i])-((char*)heapA)); } XBT_INFO("All blocks were correctly allocated. Free every second block"); for (i = 0; i < TESTSIZE; i+=2) { size = size_of_block(i); mfree(heapA,pointers[i]); } XBT_INFO("Memset every second block to zero (yeah, they are not currently allocated :)"); for (i = 0; i < TESTSIZE; i+=2) { size = size_of_block(i); memset(pointers[i],0, size); } XBT_INFO("Re-allocate every second block"); for (i = 0; i < TESTSIZE; i+=2) { size = size_of_block(i); pointers[i] = mmalloc(heapA, size); } XBT_INFO("free all blocks (each one twice, to check that double free are correctly catched)"); for (i = 0; i < TESTSIZE; i++) { xbt_ex_t e; int gotit = 1; mfree(heapA, pointers[i]); TRY { mfree(heapA, pointers[i]); gotit = 0; } CATCH(e) { xbt_ex_free(e); } if (!gotit) xbt_die("FAIL: A double-free went undetected (for size:%d)",size_of_block(i)); } XBT_INFO("free again all blocks (to really check that double free are correctly catched)"); for (i = 0; i < TESTSIZE; i++) { xbt_ex_t e; int gotit = 1; TRY { mfree(heapA, pointers[i]); gotit = 0; } CATCH(e) { xbt_ex_free(e); } if (!gotit) xbt_die("FAIL: A double-free went undetected (for size:%d)",size_of_block(i)); } XBT_INFO("Damnit, I cannot break mmalloc this time. That's SO disappointing."); return 0; }
msg_error_t MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task, double timeout) { msg_error_t ret = MSG_OK; simdata_task_t t_simdata = NULL; msg_process_t process = MSG_process_self(); simdata_process_t p_simdata = SIMIX_process_self_get_data(process); int call_end = TRACE_msg_task_put_start(task); //must be after CHECK_HOST() /* Prepare the task to send */ t_simdata = task->simdata; t_simdata->sender = process; t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host; if (t_simdata->isused != 0) { if (msg_global->debug_multiple_use){ XBT_ERROR("This task is already used in there:"); xbt_backtrace_display(t_simdata->isused); XBT_ERROR("And you try to reuse it from here:"); xbt_backtrace_display_current(); } else { xbt_assert(t_simdata->isused == 0, "This task is still being used somewhere else. You cannot send it now. Go fix your code! (use --cfg=msg/debug_multiple_use:on to get the backtrace of the other process)"); } } if (msg_global->debug_multiple_use) MSG_BT(t_simdata->isused, "Using Backtrace"); else t_simdata->isused = (void*)1; t_simdata->comm = NULL; msg_global->sent_msg++; p_simdata->waiting_task = task; xbt_ex_t e; /* Try to send it by calling SIMIX network layer */ TRY { smx_synchro_t comm = NULL; /* MC needs the comm to be set to NULL during the simix call */ comm = simcall_comm_isend(SIMIX_process_self(), mailbox,t_simdata->bytes_amount, t_simdata->rate, task, sizeof(void *), NULL, NULL, NULL, task, 0); if (TRACE_is_enabled()) simcall_set_category(comm, task->category); t_simdata->comm = comm; simcall_comm_wait(comm, timeout); } CATCH(e) { switch (e.category) { case cancel_error: ret = MSG_HOST_FAILURE; break; case network_error: ret = MSG_TRANSFER_FAILURE; break; case timeout_error: ret = MSG_TIMEOUT; break; default: RETHROW; } xbt_ex_free(e); /* If the send failed, it is not used anymore */ if (msg_global->debug_multiple_use && t_simdata->isused!=0) xbt_ex_free(*(xbt_ex_t*)t_simdata->isused); t_simdata->isused = 0; } p_simdata->waiting_task = NULL; if (call_end) TRACE_msg_task_put_end(); MSG_RETURN(ret); }
/** \ingroup msg_task_usage * \brief Executes a parallel task and waits for its termination. * * \param task a #msg_task_t to execute on the location on which the process is running. * * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED * or #MSG_HOST_FAILURE otherwise */ msg_error_t MSG_parallel_task_execute(msg_task_t task) { xbt_ex_t e; simdata_task_t simdata = task->simdata; msg_process_t self = SIMIX_process_self(); simdata_process_t p_simdata = SIMIX_process_self_get_data(self); e_smx_state_t comp_state; msg_error_t status = MSG_OK; #ifdef HAVE_TRACING TRACE_msg_task_execute_start(task); #endif xbt_assert((!simdata->compute) && (task->simdata->isused == 0), "This task is executed somewhere else. Go fix your code! %d", task->simdata->isused); XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self())); if (simdata->computation_amount == 0 && !simdata->host_nb) { #ifdef HAVE_TRACING TRACE_msg_task_execute_end(task); #endif return MSG_OK; } TRY { simdata->isused=1; if (simdata->host_nb > 0) { simdata->compute = simcall_host_parallel_execute(task->name, simdata->host_nb, simdata->host_list, simdata->comp_amount, simdata->comm_amount, 1.0, -1.0); XBT_DEBUG("Parallel execution action created: %p", simdata->compute); } else { simdata->compute = simcall_host_execute(task->name, p_simdata->m_host, simdata->computation_amount, simdata->priority); } #ifdef HAVE_TRACING simcall_set_category(simdata->compute, task->category); #endif p_simdata->waiting_action = simdata->compute; comp_state = simcall_host_execution_wait(simdata->compute); p_simdata->waiting_action = NULL; simdata->isused=0; XBT_DEBUG("Execution task '%s' finished in state %d", task->name, (int)comp_state); } CATCH(e) { switch (e.category) { case cancel_error: status = MSG_TASK_CANCELED; break; default: RETHROW; } xbt_ex_free(e); } /* action ended, set comm and compute = NULL, the actions is already destroyed * in the main function */ simdata->computation_amount = 0.0; simdata->comm = NULL; simdata->compute = NULL; #ifdef HAVE_TRACING TRACE_msg_task_execute_end(task); #endif MSG_RETURN(status); }
static void xbt_log_layout_format_doit(xbt_log_layout_t l, xbt_log_event_t ev, const char *msg_fmt, xbt_log_appender_t app) { char *p, *q; char tmpfmt[50]; int precision = -1; int length = -1; p = ev->buffer; q = l->data; while (*q != '\0') { if (*q == '%') { q++; handle_modifier: switch (*q) { case '\0': fprintf(stderr, "Layout format (%s) ending with %%\n", (char *) l->data); abort(); case '%': *p++ = '%'; break; case 'n': /* platform-dependant line separator (LOG4J compliant) */ p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "\n"); check_overflow; break; case 'e': /* plain space (SimGrid extension) */ p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), " "); check_overflow; break; case '.': /* precision specifyier */ q++; sscanf(q, "%d", &precision); q += (precision>9?2:1); goto handle_modifier; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* length modifier */ sscanf(q, "%d", &length); q += (length>9?2:1); goto handle_modifier; case 'c': /* category name; LOG4J compliant should accept a precision postfix to show the hierarchy */ show_string(ev->cat->name); break; case 'p': /* priority name; LOG4J compliant */ show_string(xbt_log_priority_names[ev->priority]); break; case 'h': /* host name; SimGrid extension */ show_string(gras_os_myname()); break; case 't': /* thread name; LOG4J compliant */ show_string(xbt_thread_self_name()); break; case 'P': /* process name; SimGrid extension */ show_string(xbt_procname()); break; case 'i': /* process PID name; SimGrid extension */ show_int((*xbt_getpid) ()); break; case 'F': /* file name; LOG4J compliant */ show_string(ev->fileName); break; case 'l': /* location; LOG4J compliant */ if (precision == -1) { p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s:%d", ev->fileName, ev->lineNum); check_overflow; } else { p += snprintf(p, (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), precision), "%s:%d", ev->fileName, ev->lineNum); check_overflow; precision = -1; } break; case 'L': /* line number; LOG4J compliant */ show_int(ev->lineNum); break; case 'M': /* method (ie, function) name; LOG4J compliant */ show_string(ev->functionName); break; case 'b': /* backtrace; called %throwable in LOG4J */ case 'B': /* short backtrace; called %throwable{short} in LOG4J */ #if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE) { xbt_ex_t e; int i; e.used = backtrace((void **) e.bt, XBT_BACKTRACE_SIZE); e.bt_strings = NULL; e.msg = NULL; e.remote = 0; xbt_backtrace_current(&e); if (*q == 'B') { show_string(e.bt_strings[2] + 8); } else { for (i = 2; i < e.used; i++) if (precision == -1) { p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "%s\n", e.bt_strings[i] + 8); check_overflow; } else { p += sprintf(p, "%.*s\n", (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), precision), e.bt_strings[i] + 8); check_overflow; precision = -1; } } xbt_ex_free(e); } #else p += snprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), "(no backtrace on this arch)"); check_overflow; #endif break; case 'd': /* date; LOG4J compliant */ show_double(gras_os_time()); break; case 'r': /* application age; LOG4J compliant */ show_double(gras_os_time() - format_begin_of_time); break; case 'm': /* user-provided message; LOG4J compliant */ if (precision == -1) { p += vsnprintf(p, XBT_LOG_BUFF_SIZE - (p - ev->buffer), msg_fmt, ev->ap); check_overflow; } else { p += vsnprintf(p, (int) MIN(XBT_LOG_BUFF_SIZE - (p - ev->buffer), precision), msg_fmt, ev->ap); check_overflow; precision = -1; } break; default: fprintf(stderr, ERRMSG, *q, (char *) l->data); abort(); } q++; } else { *(p++) = *(q++); check_overflow; } } *p = '\0'; app->do_append(app, ev->buffer); }
msg_error_t MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task, double timeout) { xbt_ex_t e; msg_error_t ret = MSG_OK; simdata_task_t t_simdata = NULL; msg_process_t process = MSG_process_self(); simdata_process_t p_simdata = SIMIX_process_self_get_data(process); #ifdef HAVE_TRACING int call_end = TRACE_msg_task_put_start(task); //must be after CHECK_HOST() #endif /* Prepare the task to send */ t_simdata = task->simdata; t_simdata->sender = process; t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host; xbt_assert(t_simdata->isused == 0, "This task is still being used somewhere else. You cannot send it now. Go fix your code!"); t_simdata->isused=1; t_simdata->comm = NULL; msg_global->sent_msg++; p_simdata->waiting_task = task; /* Try to send it by calling SIMIX network layer */ TRY { smx_action_t comm = simcall_comm_isend(mailbox, t_simdata->message_size, t_simdata->rate, task, sizeof(void *), NULL, NULL, task, 0); #ifdef HAVE_TRACING if (TRACE_is_enabled()) { simcall_set_category(comm, task->category); } #endif t_simdata->comm = comm; simcall_comm_wait(comm, timeout); } CATCH(e) { switch (e.category) { case network_error: ret = MSG_TRANSFER_FAILURE; break; case timeout_error: ret = MSG_TIMEOUT; break; default: RETHROW; } xbt_ex_free(e); /* If the send failed, it is not used anymore */ t_simdata->isused = 0; } p_simdata->waiting_task = NULL; #ifdef HAVE_TRACING if (call_end) TRACE_msg_task_put_end(); #endif MSG_RETURN(ret); }
/** \ingroup msg_task_usage * \brief Executes a parallel task and waits for its termination. * * \param task a #msg_task_t to execute on the location on which the process is running. * * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED * or #MSG_HOST_FAILURE otherwise */ msg_error_t MSG_parallel_task_execute(msg_task_t task) { xbt_ex_t e; simdata_task_t simdata = task->simdata; msg_process_t self = SIMIX_process_self(); simdata_process_t p_simdata = SIMIX_process_self_get_data(self); e_smx_state_t comp_state; msg_error_t status = MSG_OK; TRACE_msg_task_execute_start(task); xbt_assert((!simdata->compute) && (task->simdata->isused == 0), "This task is executed somewhere else. Go fix your code! %d", task->simdata->isused!=NULL); XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self())); if (simdata->flops_amount == 0 && !simdata->host_nb) { TRACE_msg_task_execute_end(task); return MSG_OK; } TRY { if (msg_global->debug_multiple_use) MSG_BT(simdata->isused, "Using Backtrace"); else simdata->isused = (void*)1; if (simdata->host_nb > 0) { simdata->compute = simcall_process_parallel_execute(task->name, simdata->host_nb, simdata->host_list, simdata->flops_parallel_amount, simdata->bytes_parallel_amount, 1.0, -1.0); XBT_DEBUG("Parallel execution action created: %p", simdata->compute); } else { unsigned long affinity_mask = (unsigned long) xbt_dict_get_or_null_ext(simdata->affinity_mask_db, (char *) p_simdata->m_host, sizeof(msg_host_t)); XBT_DEBUG("execute %s@%s with affinity(0x%04lx)", MSG_task_get_name(task), MSG_host_get_name(p_simdata->m_host), affinity_mask); simdata->compute = simcall_process_execute(task->name, simdata->flops_amount, simdata->priority, simdata->bound, affinity_mask ); } simcall_set_category(simdata->compute, task->category); p_simdata->waiting_action = simdata->compute; comp_state = simcall_process_execution_wait(simdata->compute); p_simdata->waiting_action = NULL; if (msg_global->debug_multiple_use && simdata->isused!=0) xbt_ex_free(*(xbt_ex_t*)simdata->isused); simdata->isused = 0; XBT_DEBUG("Execution task '%s' finished in state %d", task->name, (int)comp_state); } CATCH(e) { switch (e.category) { case cancel_error: status = MSG_TASK_CANCELED; break; case host_error: status = MSG_HOST_FAILURE; break; default: RETHROW; } xbt_ex_free(e); } /* action ended, set comm and compute = NULL, the actions is already destroyed * in the main function */ simdata->flops_amount = 0.0; simdata->comm = NULL; simdata->compute = NULL; TRACE_msg_task_execute_end(task); MSG_RETURN(status); }
int client(int argc, char *argv[]) { xbt_ex_t e; gras_socket_t toserver = NULL; /* peer */ int connected = 0; gras_socket_t from; int ping, pong; const char *host = "127.0.0.1"; int port = 4000; /* 1. Init the GRAS's infrastructure */ gras_init(&argc, argv); /* 2. Get the server's address. The command line override defaults when specified */ if (argc == 3) { host = argv[1]; port = atoi(argv[2]); } XBT_INFO("Launch client (server on %s:%d)", host, port); /* 3. Create a socket to speak to the server */ while (!connected) { TRY { toserver = gras_socket_client(host, port); connected = 1; } CATCH(e) { if (e.category != system_error) /* dunno what happened, let the exception go through */ RETHROWF("Unable to connect to the server: %s"); xbt_ex_free(e); gras_os_sleep(0.05); } } XBT_INFO("Connected to %s:%d.", host, port); /* 4. Register the messages. See, it doesn't have to be done completely at the beginning, only before use */ ping_register_messages(); /* 5. Keep the user informed of what's going on */ XBT_INFO(">>>>>>>> Connected to server which is on %s:%d <<<<<<<<", gras_socket_peer_name(toserver), gras_socket_peer_port(toserver)); /* 6. Prepare and send the ping message to the server */ ping = 1234; TRY { gras_msg_send(toserver, "ping", &ping); } CATCH(e) { gras_socket_close(toserver); RETHROWF("Failed to send PING to server: %s"); } XBT_INFO(">>>>>>>> Message PING(%d) sent to %s:%d <<<<<<<<", ping, gras_socket_peer_name(toserver), gras_socket_peer_port(toserver)); /* 7. Wait for the answer from the server, and deal with issues */ TRY { gras_msg_wait(6000, "pong", &from, &pong); } CATCH(e) { gras_socket_close(toserver); RETHROWF("Why can't I get my PONG message like everyone else: %s"); } /* 8. Keep the user informed of what's going on, again */ XBT_INFO(">>>>>>>> Got PONG(%d) from %s:%d <<<<<<<<", pong, gras_socket_peer_name(from), gras_socket_peer_port(from)); /* 9. Free the allocated resources, and shut GRAS down */ gras_socket_close(toserver); XBT_INFO("Done."); gras_exit(); return 0; } /* end_of_client */
static void xbt_log_layout_format_dynamic(xbt_log_layout_t l, xbt_log_event_t ev, const char *fmt, xbt_log_appender_t app) { xbt_strbuff_t buff = xbt_strbuff_new(); char tmpfmt[50]; int precision = -1; int length = -1; char *q = l->data; char *tmp; char *tmp2; while (*q != '\0') { if (*q == '%') { q++; handle_modifier: switch (*q) { case '\0': fprintf(stderr, "Layout format (%s) ending with %%\n", (char *) l->data); abort(); case '%': xbt_strbuff_append(buff, "%"); break; case 'n': /* platform-dependant line separator (LOG4J compliant) */ xbt_strbuff_append(buff, "\n"); break; case 'e': /* plain space (SimGrid extension) */ xbt_strbuff_append(buff, " "); break; case '.': /* precision specifyier */ q++; sscanf(q, "%d", &precision); q += (precision>9?2:1); goto handle_modifier; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* length modifier */ sscanf(q, "%d", &length); q += (length>9?2:1); goto handle_modifier; case 'c': /* category name; LOG4J compliant should accept a precision postfix to show the hierarchy */ append_string(ev->cat->name); break; case 'p': /* priority name; LOG4J compliant */ append_string(xbt_log_priority_names[ev->priority]); break; case 'h': /* host name; SimGrid extension */ append_string(gras_os_myname()); break; case 't': /* thread name; LOG4J compliant */ append_string(xbt_thread_self_name()); break; case 'P': /* process name; SimGrid extension */ append_string(xbt_procname()); break; case 'i': /* process PID name; SimGrid extension */ append_int((*xbt_getpid) ()); break; case 'F': /* file name; LOG4J compliant */ append_string(ev->fileName); break; case 'l': /* location; LOG4J compliant */ append2("%s:%d", ev->fileName, ev->lineNum); precision = -1; /* Ignored */ break; case 'L': /* line number; LOG4J compliant */ append_int(ev->lineNum); break; case 'M': /* method (ie, function) name; LOG4J compliant */ append_string(ev->functionName); break; case 'b': /* backtrace; called %throwable in LOG4J */ case 'B': /* short backtrace; called %throwable{short} in LOG4J */ #if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE) { xbt_ex_t e; int i; e.used = backtrace((void **) e.bt, XBT_BACKTRACE_SIZE); e.bt_strings = NULL; e.msg = NULL; e.remote = 0; xbt_backtrace_current(&e); if (*q == 'B') { append_string(e.bt_strings[2] + 8); } else { for (i = 2; i < e.used; i++) { append_string(e.bt_strings[i] + 8); xbt_strbuff_append(buff, "\n"); } } xbt_ex_free(e); } #else append_string("(no backtrace on this arch)"); #endif break; case 'd': /* date; LOG4J compliant */ append_double(gras_os_time()); break; case 'r': /* application age; LOG4J compliant */ append_double(gras_os_time() - format_begin_of_time); break; case 'm': /* user-provided message; LOG4J compliant */ tmp2 = bvprintf(fmt, ev->ap_copy); append_string(tmp2); free(tmp2); break; default: fprintf(stderr, ERRMSG, *q, (char *) l->data); abort(); } q++; } else { char tmp2[2]; tmp2[0] = *(q++); tmp2[1] = '\0'; xbt_strbuff_append(buff, tmp2); } } app->do_append(app, buff->data); xbt_strbuff_free(buff); }