123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- /********************************************************************** <BR>
- This file is part of Crack dot Com's free source code release of
- Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
- information about compiling & licensing issues visit this URL</a>
- <PRE> If that doesn't help, contact Jonathan Clark at
- golgotha_source@usa.net (Subject should have "GOLG" in it)
- ***********************************************************************/
- #include "threads/threads.hh"
- #include "error/error.hh"
- #include "init/init.hh"
- #include "main/main.hh"
- #include <stdio.h>
- #include <windows.h>
- #include <process.h>
- static w32 i4_thread_count=0;
- static i4_critical_section_class i4_thread_lock;
- static i4_critical_section_class thread_list_lock;
- struct thread_node
- {
- HANDLE h;
- w32 thread_id;
- thread_node *next;
- void *base, *top;
- thread_node(HANDLE h, w32 thread_id, void *base, void *top, thread_node *next)
- : h(h), thread_id(thread_id), next(next), base(base), top(top) {}
- };
- static thread_node *thread_list=0;
- int i4_main_thread_id;
- void i4_wait_threads() // waits for all threads to terminate (don't call from a thread!)
- {
- while (i4_thread_count!=0)
- i4_thread_yield();
- }
- static i4_thread_func_type i4_thread_to_start=0;
- static int i4_thread_size;
- void remove_thread(int id)
- {
- thread_list_lock.lock();
- thread_node *p=0;
- if (thread_list->thread_id==id)
- {
- p=thread_list;
- thread_list=thread_list->next;
- }
- else
- {
- for (thread_node *q=thread_list; q->next->thread_id!=id; q=q->next);
- p=q->next;
- q->next=p->next;
- }
- CloseHandle(p->h);
- delete p;
- thread_list_lock.unlock();
- }
- void i4_thread_starter(void *arg)
- {
- i4_thread_func_type start=i4_thread_to_start;
- int size=i4_thread_size;
- size-=200;
- i4_thread_to_start=0;
- thread_list_lock.lock();
- w32 thread_id=GetCurrentThreadId();
- HANDLE h;
- DuplicateHandle(GetCurrentProcess(),
- GetCurrentThread(),
- GetCurrentProcess(),
- &h,
- DUPLICATE_SAME_ACCESS,
- FALSE,
- DUPLICATE_SAME_ACCESS);
-
- thread_node *p=new thread_node(h, thread_id,
- (void *)&size,
- (void *)(((char *)&size)-size),
- thread_list);
- thread_list=p;
- thread_list_lock.unlock();
- start(arg);
- remove_thread(p->thread_id);
- i4_thread_lock.lock();
- i4_thread_count--;
- i4_thread_lock.unlock();
- _endthread();
- }
- void i4_add_thread(i4_thread_func_type fun, w32 stack_size, void *arg_list)
- {
- while (i4_thread_to_start!=0)
- i4_thread_yield();
- i4_thread_to_start=fun;
- i4_thread_size=stack_size;
-
- i4_thread_lock.lock();
- i4_thread_count++;
- i4_thread_lock.unlock();
- _beginthread(i4_thread_starter, stack_size, arg_list);
- }
- void i4_thread_yield()
- {
- Sleep(0);
- }
- int i4_get_thread_id()
- {
- return GetCurrentThreadId();
- }
- void i4_suspend_other_threads()
- {
- thread_list_lock.lock();
- w32 thread_id=GetCurrentThreadId();
- for (thread_node *p=thread_list; p; p=p->next)
- if (p->thread_id!=thread_id)
- SuspendThread(p->h);
- thread_list_lock.unlock();
- }
- void i4_resume_other_threads()
- {
- thread_list_lock.lock();
- w32 thread_id=GetCurrentThreadId();
- for (thread_node *p=thread_list; p; p=p->next)
- if (p->thread_id!=thread_id)
- ResumeThread(p->h);
- thread_list_lock.unlock();
- }
- int i4_get_main_thread_id()
- {
- return i4_main_thread_id;
- }
- i4_bool i4_get_first_thread_id(int &id);
- i4_bool i4_get_next_thread_id(int last_id, int &id);
- int i4_get_first_thread_id() { return thread_list->thread_id; }
- i4_bool i4_get_next_thread_id(int last_id, int &id)
- {
- for (thread_node *p=thread_list; p; p=p->next)
- if (p->thread_id==last_id)
- if (p->next)
- {
- id=p->next->thread_id;
- return i4_T;
- }
- else
- return i4_F;
- return i4_F;
- }
- void i4_get_thread_stack(int thread_id, void *&base, void *&top)
- {
- base=0;
- top=0;
- if (thread_id==i4_main_thread_id)
- {
- base=i4_stack_base;
- if (i4_get_thread_id()!=i4_main_thread_id)
- i4_error("Can't get main thread stack from thread");
-
- int t;
- top=(void *)(&t);
- }
- else
- {
- for (thread_node *p=thread_list; p; p=p->next)
- if (p->thread_id==thread_id)
- {
- base=p->base;
- top=p->top;
- }
- }
- }
- class thread_initer : public i4_init_class
- {
- public:
- virtual int init_type() { return I4_INIT_TYPE_THREADS; }
- void init()
- {
- i4_main_thread_id=i4_get_thread_id();
- HANDLE h;
- DuplicateHandle(GetCurrentProcess(),
- GetCurrentThread(),
- GetCurrentProcess(),
- &h,
- DUPLICATE_SAME_ACCESS,
- FALSE,
- DUPLICATE_SAME_ACCESS);
-
- thread_list=new thread_node(h, i4_main_thread_id,
- i4_stack_base, i4_stack_base, 0);
- }
- void uninit()
- {
- remove_thread(i4_main_thread_id);
- }
- };
- static thread_initer thread_initer_instance;
- ////////////// Critical section stuff
- i4_critical_section_class::i4_critical_section_class()
- {
- data[0]=0;
- }
- void I4_FAST_CALL i4_critical_section_class::lock()
- {
- __asm
- {
- start:
- bts [ecx], 0
- jnc success
- call i4_thread_yield // give up our time-slice
- jmp start
- success:
- }
- }
- void I4_FAST_CALL i4_critical_section_class::unlock()
- {
- __asm mov [ecx], 0
- }
- i4_critical_section_class::~i4_critical_section_class()
- {
- }
- ///////////// signal stuff
- i4_signal_object::i4_signal_object(char *name)
- {
- char buf[100];
- sprintf(buf,"%s-%d",name,_getpid()); // make sure name doesn't interfere with other
- *((HANDLE *)data)=CreateSemaphore(0, 0, 1, buf); // processes using this library
- }
- void i4_signal_object::wait_signal()
- {
- WaitForSingleObject(*((HANDLE *)data), INFINITE);
- }
- void i4_signal_object::signal()
- {
- ReleaseSemaphore(*((HANDLE *)data), 1, 0);
- }
- i4_signal_object::~i4_signal_object()
- {
- CloseHandle(*((HANDLE *)data));
- }
- i4_bool i4_threads_supported() { return i4_T; }
- void i4_set_thread_priority(int thread_id, i4_thread_priority_type priority)
- {
- thread_list_lock.lock();
- for (thread_node *p=thread_list; p && p->thread_id!=thread_id; p=p->next);
- if (p)
- {
- switch (priority)
- {
- case I4_THREAD_PRIORITY_HIGH :
- SetThreadPriority(p->h, THREAD_PRIORITY_HIGHEST);
- break;
- case I4_THREAD_PRIORITY_NORMAL :
- SetThreadPriority(p->h, THREAD_PRIORITY_NORMAL);
- break;
- case I4_THREAD_PRIORITY_LOW :
- SetThreadPriority(p->h, THREAD_PRIORITY_BELOW_NORMAL);
- }
- }
- thread_list_lock.unlock();
- }
|