| 1 | #include "PrecompiledHeaders.h"
|
|---|
| 2 | #include "Mil.h"
|
|---|
| 3 | #include "Thread.h"
|
|---|
| 4 | #include "ModuleCommon.h"
|
|---|
| 5 | #include "FilterException.h"
|
|---|
| 6 | #include "Intl.h"
|
|---|
| 7 |
|
|---|
| 8 | #undef filter_exception_and_start
|
|---|
| 9 |
|
|---|
| 10 | //#include <fecti/Utility/FBlockMemoryAllocator/FAllocatorImpl_Block.cpp>
|
|---|
| 11 | //#include <fecti/Utility/FThread.cpp>
|
|---|
| 12 |
|
|---|
| 13 | namespace mil {
|
|---|
| 14 |
|
|---|
| 15 | post_tfree_memory_function posts[MIL_MAX_THREADS];
|
|---|
| 16 |
|
|---|
| 17 | #if MIL_TBB_PRODUCER
|
|---|
| 18 | #ifdef _MSC_VER
|
|---|
| 19 | #ifdef _DEBUG
|
|---|
| 20 | #pragma comment(lib, "ix86/tbb_debug.lib")
|
|---|
| 21 | #else
|
|---|
| 22 | #pragma comment(lib, "ix86/tbb.lib")
|
|---|
| 23 | #endif
|
|---|
| 24 | #endif
|
|---|
| 25 | namespace pool {
|
|---|
| 26 | tbb::tbb_allocator<TBBMemoryUnit> tbb_a;
|
|---|
| 27 | }
|
|---|
| 28 | #endif
|
|---|
| 29 |
|
|---|
| 30 | namespace thread {
|
|---|
| 31 | Serial<id_t> id_serial(MIL_MAX_THREADS);
|
|---|
| 32 | static atomic<void*> threads[MIL_MAX_THREADS];
|
|---|
| 33 |
|
|---|
| 34 | void* get(id_t thread_id) {
|
|---|
| 35 | if (!is_valid_id(thread_id)) {
|
|---|
| 36 | halt << "thread_id is out of range";
|
|---|
| 37 | }
|
|---|
| 38 | return threads[thread_id].load();
|
|---|
| 39 | }
|
|---|
| 40 |
|
|---|
| 41 | void set(id_t thread_id, void* object) {
|
|---|
| 42 | if (!is_valid_id(thread_id)) {
|
|---|
| 43 | halt << "thread_id is out of range";
|
|---|
| 44 | }
|
|---|
| 45 | threads[thread_id].store(object);
|
|---|
| 46 | }
|
|---|
| 47 |
|
|---|
| 48 | void assert_id(id_t thread_id) {
|
|---|
| 49 | assert(is_valid_id(thread_id));
|
|---|
| 50 | }
|
|---|
| 51 |
|
|---|
| 52 | bool is_valid_id(id_t thread_id) {
|
|---|
| 53 | if (thread_id >= static_cast<id_t>(_countof(threads)) ||
|
|---|
| 54 | thread_id == Serial<id_t>::INVALID_VALUE) {
|
|---|
| 55 | return false;
|
|---|
| 56 | }
|
|---|
| 57 | return true;
|
|---|
| 58 | }
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | ExitNotifier exitNotifier /* XXX depends on id_serial */;
|
|---|
| 62 | int auto_joiner_index = 0;
|
|---|
| 63 | AutoJoiner auto_joiners[MIL_MAX_THREADS];
|
|---|
| 64 | atomic<int> auto_join_native_id_once;
|
|---|
| 65 | atomic<thread::native_id_t> auto_join_native_id;
|
|---|
| 66 |
|
|---|
| 67 | static void check_id() {
|
|---|
| 68 | if (!auto_join_native_id_once.load()) {
|
|---|
| 69 | auto_join_native_id_once.store(1);
|
|---|
| 70 | auto_join_native_id.store(thread::get_native_id());
|
|---|
| 71 | }
|
|---|
| 72 | if (auto_join_native_id.load() != thread::get_native_id()) {
|
|---|
| 73 | halt << "native thread id is not match [" << auto_join_native_id.load() << "] != [" << thread::get_native_id() << "]";
|
|---|
| 74 | }
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | void set_auto_join_body(AutoJoiner& a) {
|
|---|
| 78 | check_id();
|
|---|
| 79 |
|
|---|
| 80 | auto_joiners[auto_joiner_index] = a;
|
|---|
| 81 | auto_joiner_index++;
|
|---|
| 82 | if (auto_joiner_index >= MIL_MAX_THREADS) {
|
|---|
| 83 | halt << "auto_joiner_index is too big [" << auto_joiner_index << "]";
|
|---|
| 84 | return;
|
|---|
| 85 | }
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | void do_auto_join() {
|
|---|
| 89 | check_id();
|
|---|
| 90 |
|
|---|
| 91 | for (int i = 0; i < auto_joiner_index; i++) {
|
|---|
| 92 | auto_joiners[i].post_exit(auto_joiners[i].obj, auto_joiners[i].event_memory);
|
|---|
| 93 | }
|
|---|
| 94 | for (int i = 0; i < auto_joiner_index; i++) {
|
|---|
| 95 | auto_joiners[i].join(auto_joiners[i].obj);
|
|---|
| 96 | }
|
|---|
| 97 | auto_joiner_index = 0;
|
|---|
| 98 | }
|
|---|
| 99 |
|
|---|
| 100 |
|
|---|
| 101 | }
|
|---|
| 102 |
|
|---|
| 103 | int filter_exception_and_start(
|
|---|
| 104 | int (*start)(int, char**), int argc, char** argv) {
|
|---|
| 105 |
|
|---|
| 106 | #ifdef __OBJC__
|
|---|
| 107 | {
|
|---|
| 108 | NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
|---|
| 109 | int result = 0;
|
|---|
| 110 | id exception = filter_exception_and_start_objc(
|
|---|
| 111 | &result, start, argc, argv);
|
|---|
| 112 | if (exception != nil) {
|
|---|
| 113 | const char* userInfoString = NULL;
|
|---|
| 114 | //if ([exception userInfo] != nil) {
|
|---|
| 115 | // userInfoString = [[[exception userInfo] description] UTF8String];
|
|---|
| 116 | //}
|
|---|
| 117 | fprintf(
|
|---|
| 118 | stderr,
|
|---|
| 119 | _("Objective-C Exception\n name = %s\n reason = %s\n userInfo = %s\n"),
|
|---|
| 120 | [[exception name] UTF8String],
|
|---|
| 121 | [[exception reason] UTF8String],
|
|---|
| 122 | userInfoString);
|
|---|
| 123 | result = EXIT_FAILURE;
|
|---|
| 124 | }
|
|---|
| 125 | [pool release];
|
|---|
| 126 | return result;
|
|---|
| 127 | }
|
|---|
| 128 | #else
|
|---|
| 129 | return start(argc, argv);
|
|---|
| 130 | #endif
|
|---|
| 131 |
|
|---|
| 132 | /*
|
|---|
| 133 | try {
|
|---|
| 134 | return start(argc, argv);
|
|---|
| 135 | }
|
|---|
| 136 | //catch (boost::exception& e)
|
|---|
| 137 | //{
|
|---|
| 138 | // debug << "c++ boost::exception [" << boost::diagnostic_information(e) << "]";
|
|---|
| 139 | //}
|
|---|
| 140 | catch (std::exception& e) {
|
|---|
| 141 | //debug << "c++ std::exception [" << e.what() << "]";
|
|---|
| 142 | //_ftprintf(stderr, gettext("c++ std::exception [%s]\n"), e.what());
|
|---|
| 143 | fprintf(stderr, gettext("c++ std::exception [%s]\n"), e.what()); // e.what() -> char
|
|---|
| 144 | }
|
|---|
| 145 | return 1;
|
|---|
| 146 | */
|
|---|
| 147 | }
|
|---|
| 148 |
|
|---|
| 149 | #ifdef __OBJC__
|
|---|
| 150 |
|
|---|
| 151 | @implementation WorkerThread
|
|---|
| 152 | - (void)setData:(void* (*)(void*))routine_ arg:(void*)arg_ {
|
|---|
| 153 | routine = routine_;
|
|---|
| 154 | arg = arg_;
|
|---|
| 155 | }
|
|---|
| 156 | - (void)start {
|
|---|
| 157 | routine(arg);
|
|---|
| 158 | }
|
|---|
| 159 | @end
|
|---|
| 160 |
|
|---|
| 161 | namespace mil {
|
|---|
| 162 | class CocoaThreadManager : boost::noncopyable {
|
|---|
| 163 | Mutex mutex;
|
|---|
| 164 | NSPort* port_matrix[MIL_MAX_THREADS][MIL_MAX_THREADS];
|
|---|
| 165 | NSConnection* send_connection_matrix[MIL_MAX_THREADS][MIL_MAX_THREADS];
|
|---|
| 166 | NSConnection* receive_connection_matrix[MIL_MAX_THREADS][MIL_MAX_THREADS];
|
|---|
| 167 | id proxies[MIL_MAX_THREADS][MIL_MAX_THREADS];
|
|---|
| 168 | public:
|
|---|
| 169 | CocoaThreadManager() {
|
|---|
| 170 | synchronized (mutex) {
|
|---|
| 171 | }
|
|---|
| 172 | }
|
|---|
| 173 |
|
|---|
| 174 | ~CocoaThreadManager() {
|
|---|
| 175 | synchronized (mutex) {
|
|---|
| 176 | }
|
|---|
| 177 | }
|
|---|
| 178 |
|
|---|
| 179 | id getProxy(int sender, int receiver) {
|
|---|
| 180 | synchronized (mutex) {
|
|---|
| 181 | if (proxies[sender][receiver]) {
|
|---|
| 182 | return proxies[sender][receiver];
|
|---|
| 183 | }
|
|---|
| 184 | port_matrix[sender][receiver] = [NSPort port];
|
|---|
| 185 | port_matrix[receiver][sender] = [NSPort port];
|
|---|
| 186 | send_connection_matrix[sender][receiver] =
|
|---|
| 187 | [NSConnection connectionWithReceivePort:port_matrix[sender][receiver] sendPort:port_matrix[receiver][sender]];
|
|---|
| 188 |
|
|---|
| 189 | proxies[sender][receiver] = [send_connection_matrix[sender][receiver] rootProxy];
|
|---|
| 190 | return proxies[sender][receiver];
|
|---|
| 191 | }
|
|---|
| 192 | }
|
|---|
| 193 |
|
|---|
| 194 | void setProxy(int receiver, id object) {
|
|---|
| 195 | synchronized (mutex) {
|
|---|
| 196 | for (unsigned int sender = 0; sender < _countof(send_connection_matrix[0]); sender++) {
|
|---|
| 197 | if (send_connection_matrix[sender][receiver] && !receive_connection_matrix[sender][receiver]) {
|
|---|
| 198 | receive_connection_matrix[sender][receiver] =
|
|---|
| 199 | [NSConnection connectionWithReceivePort:port_matrix[receiver][sender] sendPort:port_matrix[sender][receiver]];
|
|---|
| 200 | [receive_connection_matrix[sender][receiver] setRootObject: object];
|
|---|
| 201 | }
|
|---|
| 202 | }
|
|---|
| 203 | }
|
|---|
| 204 | }
|
|---|
| 205 | };
|
|---|
| 206 |
|
|---|
| 207 | }
|
|---|
| 208 | #endif
|
|---|