int pthread_mutex_unlock(pthread_mutex_t *m) { int r = mutex_ref_unlock(m); if(r) return r; mutex_t *_m = (mutex_t *)*m; if (_m->type == PTHREAD_MUTEX_NORMAL) { if (!COND_LOCKED(_m)) return mutex_unref(m,EPERM); } else if (!COND_LOCKED(_m) || !COND_OWNER(_m)) return mutex_unref(m,EPERM); if (_m->type == PTHREAD_MUTEX_RECURSIVE) { if(InterlockedDecrement(&_m->count)) return mutex_unref(m,0); } #if defined USE_MUTEX_Mutex UNSET_OWNER(_m); if (_m->h != NULL && !ReleaseSemaphore(_m->h, 1, NULL)) { SET_OWNER(_m); /* restore our own bookkeeping */ return mutex_unref(m,EPERM); } #else /* USE_MUTEX_CriticalSection */ UNSET_OWNER(_m); LeaveCriticalSection(&_m->cs.cs); #endif return mutex_unref(m,0); }
static __attribute__((noinline)) int _mutex_trylock(pthread_mutex_t *m) { int r = 0; mutex_t *_m = (mutex_t *)*m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE && COND_OWNER(_m)) { InterlockedIncrement(&_m->count); return 0; } return EBUSY; } } else if (COND_LOCKED(_m)) return EBUSY; #if defined USE_MUTEX_Mutex r = do_sema_b_wait_intern (_m->h, 1, 0); if (r == ETIMEDOUT) r = EBUSY; #else /* USE_MUTEX_CriticalSection */ r = TryEnterCriticalSection(&_m->cs.cs) ? 0 : EBUSY; #endif if (!r) { _m->count = 1; SET_OWNER(_m); } return r; }
mono_handle_new_interior (gpointer rawptr, const char *owner) #endif { MonoThreadInfo *info = mono_thread_info_current (); HandleStack *handles = (HandleStack *)info->handle_stack; HandleChunk *top = handles->interior; #ifdef MONO_HANDLE_TRACK_SP mono_handle_chunk_leak_check (handles); #endif g_assert (top); /* * Don't extend the chunk now, interior handles are * only used for icall arguments, they shouldn't * overflow. */ g_assert (top->size < OBJECTS_PER_HANDLES_CHUNK); int idx = top->size; gpointer *objslot = &top->elems [idx].o; *objslot = NULL; mono_memory_write_barrier (); top->size++; mono_memory_write_barrier (); *objslot = rawptr; SET_OWNER (top,idx); SET_SP (handles, top, idx); return objslot; }
static WINPTHREADS_ATTRIBUTE((noinline)) int _mutex_trylock(pthread_mutex_t *m) { int r = 0; mutex_t *_m = (mutex_t *)*m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE && COND_OWNER(_m)) { InterlockedIncrement(&_m->count); return 0; } return EBUSY; } } else if (COND_LOCKED(_m)) return EBUSY; r = do_sema_b_wait_intern (_m->h, 1, 0); if (r == ETIMEDOUT) r = EBUSY; else if (!r) { _m->count = 1; SET_OWNER(_m); } return r; }
int pthread_mutex_unlock(pthread_mutex_t *m) { mutex_t *_m; int r = mutex_ref_unlock(m); if(r) { #if 0 printf("thread %d, la pool, no user unset in mutex %p\n", GetCurrentThreadId(), m); #endif return r; } _m = (mutex_t *)*m; if (_m->type == PTHREAD_MUTEX_NORMAL) { if (!COND_LOCKED(_m)) { #if 0 printf("thread %d, mutex %p never locked, actually :p\n", GetCurrentThreadId(), m); #endif return mutex_unref(m, EPERM); } } else if (!COND_LOCKED(_m) || !COND_OWNER(_m)) { #if 0 printf("thread %d, mutex %p never locked or not owner, actually :p\n", GetCurrentThreadId(), m); #endif return mutex_unref(m,EPERM); } if (_m->type == PTHREAD_MUTEX_RECURSIVE) { if(InterlockedDecrement(&_m->count)) { #if 0 printf("thread %d, mutex %p decreasing recursive\n", GetCurrentThreadId(), m); #endif return mutex_unref(m,0); } } #if 0 printf("thread %d,unsetting owner of mutex %p\n", GetCurrentThreadId(), m); #endif UNSET_OWNER(_m); if (_m->h != NULL && !ReleaseSemaphore(_m->h, 1, NULL)) { SET_OWNER(_m); #if 0 printf("Error, not released! thread %d, setting owner of mutex m\n", GetCurrentThreadId(), m); #endif /* restore our own bookkeeping */ return mutex_unref(m,EPERM); } return mutex_unref(m,0); }
mono_handle_new (MonoObject *obj, MonoThreadInfo *info, const char *owner) #endif { info = info ? info : mono_thread_info_current (); HandleStack *handles = info->handle_stack; HandleChunk *top = handles->top; #ifdef MONO_HANDLE_TRACK_SP mono_handle_chunk_leak_check (handles); #endif retry: if (G_LIKELY (top->size < OBJECTS_PER_HANDLES_CHUNK)) { int idx = top->size; gpointer* objslot = &top->elems [idx].o; /* can be interrupted anywhere here, so: * 1. make sure the new slot is null * 2. make the new slot scannable (increment size) * 3. put a valid object in there * * (have to do 1 then 3 so that if we're interrupted * between 1 and 2, the object is still live) */ *objslot = NULL; SET_OWNER (top,idx); SET_SP (handles, top, idx); mono_memory_write_barrier (); top->size++; mono_memory_write_barrier (); *objslot = obj; return objslot; } if (G_LIKELY (top->next)) { top->next->size = 0; /* make sure size == 0 is visible to a GC thread before it sees the new top */ mono_memory_write_barrier (); top = top->next; handles->top = top; goto retry; } HandleChunk *new_chunk = new_handle_chunk (); new_chunk->size = 0; new_chunk->prev = top; new_chunk->next = NULL; /* make sure size == 0 before new chunk is visible */ mono_memory_write_barrier (); top->next = new_chunk; handles->top = new_chunk; goto retry; }
static int pthread_mutex_lock_intern(pthread_mutex_t *m, DWORD timeout) { mutex_t *_m; int r; r = mutex_ref(m); if(r) return r; _m = (mutex_t *)*m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (COND_OWNER(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE) { InterlockedIncrement(&_m->count); return mutex_unref(m,0); } return mutex_unref(m, EDEADLK); } } } else { #if !defined USE_MUTEX_Mutex if (COND_OWNER(_m)) { do { Sleep(0); /* waiter that owner gets released. */ } while (COND_OWNER(_m)); } #endif } #if defined USE_MUTEX_Mutex r = do_sema_b_wait_intern (_m->h, 1, timeout); #else /* USE_MUTEX_CriticalSection */ EnterCriticalSection(&_m->cs.cs); r = 0; #endif if (r == 0) { _m->count = 1; SET_OWNER(_m); } return mutex_unref(m,r); }
static int pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD timeout) { mutex_t *_m; int r; HANDLE h; r = mutex_ref (m); if (r) return r; _m = (mutex_t *) *m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (COND_OWNER(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE) { InterlockedIncrement(&_m->count); return mutex_unref(m,0); } return mutex_unref(m, EDEADLK); } } } h = _m->h; mutex_unref (m, 0); r = do_sema_b_wait_intern (h, 1, timeout); if (r != 0) return r; r = mutex_ref (m); if (r) return r; _m->count = 1; SET_OWNER(_m); return mutex_unref (m, r); }
mono_handle_new (MonoObject *object, const char *owner) #endif { MonoThreadInfo *info = mono_thread_info_current (); HandleStack *handles = (HandleStack *)info->handle_stack; HandleChunk *top = handles->top; retry: if (G_LIKELY (top->size < OBJECTS_PER_HANDLES_CHUNK)) { int idx = top->size; MonoObject** objslot = chunk_element_objslot (top, idx); /* can be interrupted anywhere here, so: * 1. make sure the new slot is null * 2. make the new slot scannable (increment size) * 3. put a valid object in there * * (have to do 1 then 3 so that if we're interrupted * between 1 and 2, the object is still live) */ *objslot = NULL; mono_memory_write_barrier (); top->size++; mono_memory_write_barrier (); *objslot = object; SET_OWNER (top,idx); return objslot; } if (G_LIKELY (top->next)) { top->next->size = 0; /* make sure size == 0 is visible to a GC thread before it sees the new top */ mono_memory_write_barrier (); top = top->next; handles->top = top; goto retry; } HandleChunk *new_chunk = g_new (HandleChunk, 1); new_chunk->size = 0; new_chunk->prev = top; new_chunk->next = NULL; /* make sure size == 0 before new chunk is visible */ mono_memory_write_barrier (); top->next = new_chunk; handles->top = new_chunk; goto retry; }
int pthread_mutex_unlock(pthread_mutex_t *m) { mutex_t *_m; int r = mutex_ref_unlock(m); if(r) { return r; } _m = (mutex_t *)*m; if (_m->type == PTHREAD_MUTEX_NORMAL) { if (!COND_LOCKED(_m)) { return mutex_unref(m, EPERM); } } else if (!COND_LOCKED(_m) || !COND_OWNER(_m)) { return mutex_unref(m,EPERM); } if (_m->type == PTHREAD_MUTEX_RECURSIVE) { if(InterlockedDecrement(&_m->count)) { return mutex_unref(m,0); } } UNSET_OWNER(_m); if (_m->h != NULL && !ReleaseSemaphore(_m->h, 1, NULL)) { SET_OWNER(_m); /* restore our own bookkeeping */ return mutex_unref(m,EPERM); } return mutex_unref(m,0); }
int __server_bind_port(int port) { loop_t *loop = NULL; listener_t *listener = NULL; #if 0 loop_t *loop = __get_main_loop(); //@{get_best_loop} #else sched_t* sched = __get_main_sched(); if (!sched) { goto _error; } loop = get_best_loop2(sched); if (!loop) {//@{not need free loop, because loop is own to sched} goto _error; } LOG_I("get best loop:%p", loop); #endif listener = listener_new(port, NULL); if (!listener) { goto _error; } SET_OWNER(listener, (void*)loop); // set listen's loop LOOP_ADD_WEIGHT(loop); listener->stat = STAT_ACCEPT; if(gettid() == loop->set_tid) { fd_set_add_node3(loop->_set, (fd_node_t *)listener, FD_R_FLAGS, listener->timeout); } else { #ifdef WIN32 EnterCriticalSection(&loop->set_mutex); #else pthread_mutex_lock(&loop->set_mutex); #endif fd_set_add_node3(loop->_set, (fd_node_t *)listener, FD_R_FLAGS, listener->timeout); #ifdef WIN32 LeaveCriticalSection(&loop->set_mutex); #else pthread_mutex_unlock(&loop->set_mutex); #endif } return 0; _error: if (sched) { printf("sched:%p g_sched: %p\n", sched, __get_main_sched()); sched_del(sched); printf("g_sched: %p\n", __get_main_sched()); } if(listener) { listener_del(listener); } return -1; }
static int pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD timeout) { mutex_t *_m; int r; HANDLE h; #if 0 int waited = 0; #endif r = mutex_ref (m); if (r) return r; _m = (mutex_t *) *m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (COND_OWNER(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE) { #if 0 printf("thread %d, recursive increment %p\n", GetCurrentThreadId(), m); #endif InterlockedIncrement(&_m->count); return mutex_unref(m,0); } #if 0 printf("thread %d, non recursive increment?!? %p\n", GetCurrentThreadId(), m); #endif return mutex_unref(m, EDEADLK); } } } h = _m->h; mutex_unref (m, 0); if(_m->owner) { #if 0 waited = 1; printf("thread %d, waiting for thread: %d on mutex %p for %d time\n", GetCurrentThreadId(), _m->owner, m, timeout); #endif } r = do_sema_b_wait_intern (h, 1, timeout); #if 0 if(waited) { printf("thread %d, resumed\n", GetCurrentThreadId()); } #endif if (r != 0) return r; r = mutex_ref (m); if (r) return r; _m->count = 1; SET_OWNER(_m); #if 0 printf("thread %d, setting owner of mutex %p\n", GetCurrentThreadId(), m); #endif return mutex_unref (m, r); }