/* ************************************************** */ int do_configuration(void) { xmlSchemaValidCtxtPtr sv_ctxt = NULL; xmlSchemaParserCtxtPtr sp_ctxt = NULL; xmlSchemaPtr schema = NULL; xmlParserCtxtPtr p_ctxt = NULL; xmlDocPtr doc = NULL; xmlXPathContextPtr xp_ctx = NULL; xmlXPathObjectPtr simul_xobj = NULL; xmlXPathObjectPtr entity_xobj = NULL; xmlXPathObjectPtr environment_xobj = NULL; xmlXPathObjectPtr bundle_xobj = NULL; xmlXPathObjectPtr node_xobj = NULL; xmlNodeSetPtr nodeset; xmlpathobj_t xpathobj[] = {{&simul_xobj, (xmlChar *) XML_X_SIMULATION}, {&entity_xobj, (xmlChar *) XML_X_ENTITY}, {&environment_xobj, (xmlChar *) XML_X_ENVIRONMENT}, {&bundle_xobj, (xmlChar *) XML_X_BUNDLE}, {&node_xobj, (xmlChar *) XML_X_NODE}}; int ok = 0, i; /* Check XML version */ LIBXML_TEST_VERSION; /* Initialise and parse schema */ sp_ctxt = xmlSchemaNewParserCtxt(schemafile); if (sp_ctxt == NULL) { fprintf(stderr, "config: XML schema parser initialisation failure (do_configuration())\n"); ok = -1; goto cleanup; } xmlSchemaSetParserErrors(sp_ctxt, (xmlSchemaValidityErrorFunc) xml_error, (xmlSchemaValidityWarningFunc) xml_warning, NULL); schema = xmlSchemaParse(sp_ctxt); if (schema == NULL) { fprintf(stderr, "config: error in schema %s (do_configuration())\n", schemafile); ok = -1; goto cleanup; } xmlSchemaSetValidErrors(sv_ctxt, (xmlSchemaValidityErrorFunc) xml_error, (xmlSchemaValidityWarningFunc) xml_warning, NULL); sv_ctxt = xmlSchemaNewValidCtxt(schema); if (sv_ctxt == NULL) { fprintf(stderr, "config: XML schema validator initialisation failure (do_configuration())\n"); ok = -1; goto cleanup; } /* Initialise and parse document */ p_ctxt = xmlNewParserCtxt(); if (p_ctxt == NULL) { fprintf(stderr, "config: XML parser initialisation failure (do_configuration())\n"); ok = -1; goto cleanup; } doc = xmlCtxtReadFile(p_ctxt, configfile, NULL, XML_PARSE_NONET | XML_PARSE_NOBLANKS | XML_PARSE_NSCLEAN); if (doc == NULL) { fprintf(stderr, "config: failed to parse %s (do_configuration())\n", configfile); ok = -1; goto cleanup; } /* Validate document */ if (xmlSchemaValidateDoc(sv_ctxt, doc)) { fprintf(stderr, "config: error in configuration file %s (do_configuration())\n", configfile); ok = -1; goto cleanup; } /* Create xpath context */ xp_ctx = xmlXPathNewContext(doc); if (xp_ctx == NULL) { fprintf(stderr, "config: XPath initialisation failure (do_configuration())\n"); ok = -1; goto cleanup; } xmlXPathRegisterNs(xp_ctx, (xmlChar *) XML_NS_ID, (xmlChar *) XML_NS_URL); /* Get xpath obj */ for (i = 0 ; i < (int) (sizeof(xpathobj) / sizeof(xpathobj[0])); i++) { *xpathobj[i].ptr = xmlXPathEvalExpression(xpathobj[i].expr, xp_ctx); if (*xpathobj[i].ptr == NULL) { fprintf(stderr, "config: unable to evaluate xpath \"%s\" (do_configuration())\n", xpathobj[i].expr); ok = -1; goto cleanup; } } /***************/ /* Counting... */ /***************/ nodeset = entity_xobj->nodesetval; if ((entities.size = (nodeset) ? nodeset->nodeNr : 0) == 0) { fprintf(stderr, "config: no entity defined (do_configuration())\n"); ok = -1; goto cleanup; } fprintf(stderr, "\nFound %d entities...\n", entities.size); nodeset = environment_xobj->nodesetval; if (((nodeset) ? nodeset->nodeNr : 0) == 0) { fprintf(stderr, "config: no environment defined (do_configuration())\n"); ok = -1; goto cleanup; } fprintf(stderr, "Found 1 environment...\n"); nodeset = bundle_xobj->nodesetval; if ((bundles.size = (nodeset) ? nodeset->nodeNr : 0) == 0) { fprintf(stderr, "config: no bundle defined (do_configuration())\n"); ok = -1; goto cleanup; } fprintf(stderr, "Found %d bundles...\n", bundles.size); if ((dflt_params = das_create()) == NULL) { ok = -1; goto cleanup; } /**************/ /* Simulation */ /**************/ if (parse_simulation(simul_xobj->nodesetval)) { ok = -1; goto cleanup; } /**********/ /* Entity */ /**********/ /* initialize library paths */ config_set_usr_modulesdir(); user_path_list = g_strsplit(user_modulesdir, ":", 0); /* TOCLEAN */ sys_path_list = g_strsplit(sys_modulesdir, ":", 0); /* TOCLEAN */ /* parse */ if (parse_entities(entity_xobj->nodesetval)) { ok = -1; goto cleanup; } /**************/ /* Measure */ /**************/ if (parse_measure()) { ok = -1; goto cleanup; } /***************/ /* Environment */ /***************/ if (parse_environment(environment_xobj->nodesetval)) { ok = -1; goto cleanup; } /***************/ /* Bundle */ /***************/ if (parse_bundles(bundle_xobj->nodesetval)) { ok = -1; goto cleanup; } /***************/ /* Nodes */ /***************/ if (parse_nodes(node_xobj->nodesetval)) { ok = -1; goto cleanup; } /* edit by Quentin Lampin <*****@*****.**> */ gchar **path = NULL; for (path = user_path_list ; *path ; path++) { g_free(*path); } path = NULL; for (path = sys_path_list ; *path ; path++) { g_free(*path); } /* end of edition */ cleanup: clean_params(); for (i = 0 ; i < (int) (sizeof(xpathobj) / sizeof(xpathobj[0])); i++) { xmlXPathFreeObject(*xpathobj[i].ptr); } if (xp_ctx) { xmlXPathFreeContext(xp_ctx); } if (sp_ctxt) { xmlSchemaFreeParserCtxt(sp_ctxt); } if (schema) { xmlSchemaFree(schema); } if (sv_ctxt) { xmlSchemaFreeValidCtxt(sv_ctxt); } if (doc) { xmlFreeDoc(doc); } if (p_ctxt) { xmlFreeParserCtxt(p_ctxt); } xmlCleanupParser(); return ok; }
/* Main */ int main (int argc, char *argv[]) { int ret, nth; long dur; /* Initialize the measure list */ mes_t sentinel; mes_t *m_cur, *m_tmp; m_cur = &sentinel; m_cur->next = NULL; /* Initialize the output */ output_init(); /* Test machine capabilities */ /* -> clockid_t; pshared; ... */ altclk_ok = sysconf(_SC_CLOCK_SELECTION); if (altclk_ok > 0) altclk_ok = sysconf(_SC_MONOTONIC_CLOCK); #ifndef USE_ALTCLK if (altclk_ok > 0) output("Implementation supports the MONOTONIC CLOCK but option is disabled in test.\n"); #endif pshared_ok = sysconf(_SC_THREAD_PROCESS_SHARED); #if VERBOSE > 0 output("Test starting\n"); output(" Process-shared primitive %s be tested\n", (pshared_ok>0)?"will":"won't"); output(" Alternative clock for cond %s be tested\n", (altclk_ok>0)?"will":"won't"); #endif /* Prepare thread attribute */ ret = pthread_attr_init(&ta); if (ret != 0) { UNRESOLVED(ret, "Unable to initialize thread attributes"); } ret = pthread_attr_setstacksize(&ta, sysconf(_SC_THREAD_STACK_MIN)); if (ret != 0) { UNRESOLVED(ret, "Unable to set stack size to minimum value"); } #ifdef PLOT_OUTPUT output("# COLUMNS %d #threads", NSCENAR + 1); for (nth=0; nth<NSCENAR; nth++) output(" %s", test_scenar[nth].desc); output("\n"); #endif /* Do the testing */ nth = 0; do { nth += 100 * SCALABILITY_FACTOR; /* Create a new measure item */ m_tmp = (mes_t *) malloc(sizeof(mes_t)); if (m_tmp == NULL) { UNRESOLVED(errno, "Unable to alloc memory for measure saving"); } m_tmp->nthreads = nth; m_tmp->next = NULL; /* Run the test */ dur = do_threads_test(nth, m_tmp); /* If test was success, add this measure to the list. Otherwise, free the mem */ if (dur >= 0) { m_cur->next = m_tmp; m_cur = m_tmp; } else { free(m_tmp); } } while (dur >= 0); /* We will now parse the results to determine if the measure is ~ constant or is growing. */ ret = parse_measure(&sentinel); /* Free the memory from the list */ m_cur = sentinel.next; while (m_cur != NULL) { m_tmp = m_cur; m_cur = m_tmp->next; free(m_tmp); } if (ret != 0) { FAILED("This function is not scalable"); } #if VERBOSE > 0 output("The function is scalable\n"); #endif PASSED; }
int main (int argc, char *argv[]) { int ret, status; pid_t pidctl; pid_t *pr; int nprocesses, i; struct timespec ts_ref, ts_fin; mes_t sentinel; mes_t *m_cur, *m_tmp; long CHILD_MAX = sysconf(_SC_CHILD_MAX); long my_max = 1000 * SCALABILITY_FACTOR ; /* Initialize the measure list */ m_cur = &sentinel; m_cur->next = NULL; /* Initialize output routine */ output_init(); if (CHILD_MAX > 0) my_max = CHILD_MAX; pr = (pid_t *) calloc(1 + my_max, sizeof(pid_t)); if (pr == NULL) { UNRESOLVED(errno, "Not enough memory for process IDs storage"); } #if VERBOSE > 1 output("CHILD_MAX: %d\n", CHILD_MAX); #endif #ifdef PLOT_OUTPUT output("# COLUMNS 2 #Process Duration\n"); #endif /* Initilaize the semaphores */ sem_synchro = sem_open("/fork_scal_sync", O_CREAT, O_RDWR, 0); if (sem_synchro == SEM_FAILED) { UNRESOLVED(errno, "Failed to open a named semaphore\n"); } sem_unlink("/fork_scal_sync"); sem_ending = sem_open("/fork_scal_end", O_CREAT, O_RDWR, 0); if (sem_ending == SEM_FAILED) { UNRESOLVED(errno, "Failed to open a named semaphore\n"); } sem_unlink("/fork_scal_end"); nprocesses = 0; m_cur = &sentinel; while (1) /* we will break */ { /* read clock */ ret = clock_gettime(CLOCK_REALTIME, &ts_ref); if (ret != 0) { UNRESOLVED(errno, "Unable to read clock"); } /* create a new child */ pr[nprocesses] = fork(); if (pr[nprocesses] == -1) { if (errno == EAGAIN || errno == ENOMEM) break; FAILED("Failed to fork and received an unexpected error"); /* Post the semaphore so running processes will terminate */ do { ret = sem_post(sem_ending); } while (ret != 0 && errno == EINTR); if (ret != 0) output("Failed to post the semaphore on termination: error %d\n", errno); } if (pr[nprocesses] == 0) { /* Child */ /* Post the synchro semaphore*/ do { ret = sem_post(sem_synchro); } while ((ret != 0) && (errno == EINTR)); if (ret != 0) { /* In this case the test will hang... */ UNRESOLVED(errno, "Failed post the sync semaphore"); } /* Wait the end semaphore */ do { ret = sem_wait(sem_ending); } while ((ret != 0) && (errno == EINTR)); if (ret != 0) { UNRESOLVED(errno, "Failed wait for the end semaphore"); } /* Cascade-post the end semaphore */ do { ret = sem_post(sem_ending); } while ((ret != 0) && (errno == EINTR)); if (ret != 0) { UNRESOLVED(errno, "Failed post the end semaphore"); } /* Exit */ exit(PTS_PASS); } /* Parent */ nprocesses++; /* FAILED if nprocesses > CHILD_MAX */ if (nprocesses > my_max) { errno = 0; if (CHILD_MAX > 0) { #if VERBOSE > 0 output("WARNING! We were able to create more than CHILD_MAX processes\n"); #endif } break; } /* wait for the semaphore */ do { ret = sem_wait(sem_synchro); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { sem_post(sem_ending); UNRESOLVED(errno, "Failed to wait for the sync semaphore"); } /* read clock */ ret = clock_gettime(CLOCK_REALTIME, &ts_fin); if (ret != 0) { UNRESOLVED(errno, "Unable to read clock"); } /* add to the measure list if nprocesses % resolution == 0 */ if (((nprocesses % RESOLUTION) == 0) && (nprocesses != 0)) { /* Create an empty new element */ m_tmp = (mes_t *) malloc(sizeof(mes_t)); if (m_tmp == NULL) { sem_post(sem_ending); UNRESOLVED(errno, "Unable to alloc memory for measure saving"); } m_tmp->nprocess = nprocesses; m_tmp->next = NULL; m_tmp->_data = 0; m_cur->next = m_tmp; m_cur = m_cur->next; m_cur->_data = ((ts_fin.tv_sec - ts_ref.tv_sec) * 1000000) + ((ts_fin.tv_nsec - ts_ref.tv_nsec) / 1000) ; #if VERBOSE > 5 output("Added the following measure: n=%i, v=%li\n", nprocesses, m_cur->_data); #endif } } #if VERBOSE > 3 if (errno) output("Could not create anymore processes. Current count is %i\n", nprocesses); else output("Should not create anymore processes. Current count is %i\n", nprocesses); #endif /* Unblock every created children: post once, then cascade signaling */ do { ret = sem_post(sem_ending); } while ((ret != 0) && (errno == EINTR)); if (ret != 0) { UNRESOLVED(errno, "Failed post the end semaphore"); } #if VERBOSE > 3 output("Waiting children termination\n"); #endif for (i = 0; i < nprocesses; i++) { pidctl = waitpid(pr[ i ], &status, 0); if (pidctl != pr[ i ]) { UNRESOLVED(errno, "Waitpid returned the wrong PID"); } if ((!WIFEXITED(status)) || (WEXITSTATUS(status) != PTS_PASS)) { FAILED("Child exited abnormally"); } } /* Free some memory before result parsing */ free(pr); /* Compute the results */ ret = parse_measure(&sentinel); /* Free the resources and output the results */ #if VERBOSE > 5 output("Dump : \n"); output(" nproc | dur \n"); #endif while (sentinel.next != NULL) { m_cur = sentinel.next; #if (VERBOSE > 5) || defined(PLOT_OUTPUT) output("%8.8i %1.1li.%6.6li\n", m_cur->nprocess, m_cur->_data / 1000000, m_cur->_data % 1000000); #endif sentinel.next = m_cur->next; free(m_cur); } if (ret != 0) { FAILED("The function is not scalable, add verbosity for more information"); } #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
int main (int argc, char *argv[]) { int ret=0; pthread_t child; pthread_t *th; int nthreads, ctl, i, tmp; struct timespec ts_ref, ts_fin; mes_t sentinel; mes_t *m_cur, *m_tmp; long PTHREAD_THREADS_MAX = sysconf(_SC_THREAD_THREADS_MAX); long my_max = 1000 * SCALABILITY_FACTOR ; /* Initialize the measure list */ m_cur = &sentinel; m_cur->next = NULL; /* Initialize output routine */ output_init(); if (PTHREAD_THREADS_MAX > 0) my_max = PTHREAD_THREADS_MAX; th = (pthread_t *)calloc(1 + my_max, sizeof(pthread_t)); if (th == NULL) { UNRESOLVED(errno, "Not enough memory for thread storage"); } /* Initialize thread attribute objects */ scenar_init(); #ifdef PLOT_OUTPUT printf("# COLUMNS %d #threads", NSCENAR + 1); for (sc=0; sc<NSCENAR; sc++) printf(" %i", sc); printf("\n"); #endif for (sc=0; sc < NSCENAR; sc++) { if (scenarii[sc].bottom == NULL) /* skip the alternate stacks as we could create only 1 */ { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", sc, scenarii[sc].descr); #endif /* Block every (about to be) created threads */ ret = pthread_mutex_lock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex lock failed"); } ctl=0; nthreads=0; m_cur = &sentinel; /* Create 1 thread for testing purpose */ ret = pthread_create(&child, &scenarii[sc].ta, threaded, &ctl); switch (scenarii[sc].result) { case 0: /* Operation was expected to succeed */ if (ret != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (ret == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 0 if (ret == 0) { output("Thread has been created successfully for this scenario\n"); } else { output("Thread creation failed with the error: %s\n", strerror(ret)); } #endif ; } if (ret == 0) /* The new thread is running */ { while (1) /* we will break */ { /* read clock */ ret = clock_gettime(CLOCK_REALTIME, &ts_ref); if (ret != 0) { UNRESOLVED(errno, "Unable to read clock"); } /* create a new thread */ ret = pthread_create(&th[nthreads], &scenarii[sc].ta, threaded, &ctl); /* stop here if we've got EAGAIN */ if (ret == EAGAIN) break; // temporary hack if (ret == ENOMEM) break; nthreads++; /* FAILED if error is != EAGAIN or nthreads > PTHREAD_THREADS_MAX */ if (ret != 0) { output("pthread_create returned: %i (%s)\n", ret, strerror(ret)); FAILED("pthread_create did not return EAGAIN on a lack of resource"); } if (nthreads > my_max) { if (PTHREAD_THREADS_MAX > 0) { FAILED("We were able to create more than PTHREAD_THREADS_MAX threads"); } else { break; } } /* wait for the semaphore */ do { ret = sem_wait(&scenarii[sc].sem); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to wait for the semaphore"); } /* read clock */ ret = clock_gettime(CLOCK_REALTIME, &ts_fin); if (ret != 0) { UNRESOLVED(errno, "Unable to read clock"); } /* add to the measure list if nthreads % resolution == 0 */ if ((nthreads % RESOLUTION) == 0) { if (m_cur->next == NULL) { /* Create an empty new element */ m_tmp = (mes_t *) malloc(sizeof(mes_t)); if (m_tmp == NULL) { UNRESOLVED(errno, "Unable to alloc memory for measure saving"); } m_tmp->nthreads = nthreads; m_tmp->next = NULL; for (tmp=0; tmp<NSCENAR; tmp++) m_tmp->_data[tmp]= 0; m_cur->next = m_tmp; } /* Add this measure to the next element */ m_cur = m_cur->next; m_cur->_data[sc] = ((ts_fin.tv_sec - ts_ref.tv_sec) * 1000000) + ((ts_fin.tv_nsec - ts_ref.tv_nsec) / 1000) ; #if VERBOSE > 5 output("Added the following measure: sc=%i, n=%i, v=%li\n", sc, nthreads, m_cur->_data[sc]); #endif } } #if VERBOSE > 3 output("Could not create anymore thread. Current count is %i\n", nthreads); #endif /* Unblock every created threads */ ret = pthread_mutex_unlock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex unlock failed"); } if (scenarii[sc].detached == 0) { #if VERBOSE > 3 output("Joining the threads\n"); #endif for (i = 0; i < nthreads; i++) { ret = pthread_join(th[i], NULL); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } } ret = pthread_join(child, NULL); if (ret != 0) { UNRESOLVED(ret, "Unalbe to join a thread"); } } #if VERBOSE > 3 output("Waiting for threads (almost) termination\n"); #endif do { ret = pthread_mutex_lock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex lock failed"); } tmp = ctl; ret = pthread_mutex_unlock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex unlock failed"); } } while (tmp != nthreads + 1); } /* The thread was created */ } } /* next scenario */ /* Free some memory before result parsing */ free(th); /* Compute the results */ ret = parse_measure(&sentinel); /* Free the resources and output the results */ #if VERBOSE > 5 printf("Dump : \n"); printf("%8.8s", "nth"); for (i = 0; i<NSCENAR; i++) printf("| %2.2i ", i); printf("\n"); #endif while (sentinel.next != NULL) { m_cur = sentinel.next; #if (VERBOSE > 5) || defined(PLOT_OUTPUT) printf("%8.8i", m_cur->nthreads); for (i=0; i<NSCENAR; i++) printf(" %1.1li.%6.6li", m_cur->_data[i] / 1000000, m_cur->_data[i] % 1000000); printf("\n"); #endif sentinel.next = m_cur->next; free(m_cur); } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }