inline bool spin_recursive_mutex::try_lock() { typedef ipcdetail::OS_systemwide_thread_id_t handle_t; handle_t thr_id(ipcdetail::get_current_systemwide_thread_id()); handle_t old_id; ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id); if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) { // we own it if((unsigned int)(m_nLockCount+1) == 0){ //Overflow, throw an exception throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow"); } ++m_nLockCount; return true; } if(m_mutex.try_lock()){ ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner); m_nLockCount = 1; return true; } return false; }
/* * Traveling Salesman Problem */ int main(int argc, char* argv[]) { int num_threads = 1; int start_city = 0; FILE *infile = NULL, *outfile = NULL; verbose_flag = false; // ******************************************************************* // Argument parsing // ******************************************************************* if (argc == 1) { fprintf(stderr, "Usage: %s [-v] [-t seconds] inputfile [outfile]\n", argv[0]); fprintf(stderr, "-v # Prints results of each full path computation\n" "-s N # Use city N to begin the path search\n" "-T N # Stops computing paths once N seconds exceeded\n" "-t N # Specifies the number of threads to execute\n"); exit(0); } for (int i=1; i<argc; i++) { if (strcmp(argv[i], "-v") == 0) verbose_flag = true; else if (strcmp(argv[i], "-s") == 0) { i++; start_city = atoi(argv[i]); } else if (strcmp(argv[i], "-T") == 0) { i++; int timelimit = atoi(argv[i]); global_stop_time = time(NULL) + timelimit; } else if (strcmp(argv[i], "-t") == 0) { i++; num_threads = atoi(argv[i]); } else if (infile == NULL) { if ( (infile = fopen(argv[i], "r")) == NULL) perror("failed to open input file"), exit(-1); } else if (outfile == NULL) { if ( (outfile = fopen(argv[i], "w")) == NULL ) perror("failed to open output file"), exit(-1); } else { fprintf(stderr, "Error on argument: '%s'\n", argv[i]); exit(-1); } } if (!infile) { fprintf(stderr, "%s : No input file specified ... exiting\n", argv[0]); exit(-1); } // ******************************************************************* // Basic Algorithm -- call "calcPath" // ******************************************************************* cities.read(infile); cities.initCosts(); // We will replace this single call to "calcPath()" with a threaded // search, testing every city as a starting point. // int best_length = best_path->calcPath(cities, start_city); // ******************************************************************* // Threaded Algorithm // // For M cities, divide them across N threads and calculate the path // length using each city as a different starting point. // ******************************************************************* std::vector<bounds_t> bounds(num_threads); // We will run from start_city to cities.size() int range = (cities.size() - start_city) / num_threads; std::vector<pthread_t> thr_id(num_threads); for (int i=0; i<num_threads; i++) { // Calculate the range of "start cities" for each thread to work on // If the cities don't divide evenly into the number of threads, then // have the last thread clean up the left over. bounds[i].start = i*range + start_city; bounds[i].end = bounds[i].start + range; if (i == num_threads -1) // if last thread ... bounds[i].end = cities.size() + 1; // ... finish all the cities // Start each thread on their respective range of start cities if (pthread_create(&thr_id[i], NULL, runthread, &bounds[i]) < 0) perror("pthread_create"), exit(-1); } // Wait for all of the threads to complete for (int i=0; i<num_threads; i++) { if (pthread_join(thr_id[i], NULL) < 0) perror("pthread_join"), exit(-1); } // printf("length = %d\n", best_length); global_best_path->printPath(outfile); delete global_best_path; return 0; }