thread* thread_new(int32_t flag, void *(*routine)(void*), void *ud) { pthread_attr_t attr; pthread_attr_init(&attr); if(flag | JOINABLE) pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE); else pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); thread *t = calloc(1,sizeof(*t)); struct start_arg starg; starg.routine = routine; starg.arg = ud; starg.running = 0; starg.mtx = mutex_new(); starg.cond = condition_new(starg.mtx); pthread_create(&t->threadid,&attr,start_routine,&starg); mutex_lock(starg.mtx); while(!starg.running){ condition_wait(starg.cond); } mutex_unlock(starg.mtx); condition_del(starg.cond); mutex_del(starg.mtx); pthread_attr_destroy(&attr); return t; }
struct skbuf *recvq_rm (struct sockbase *sb) { struct skbuf *msg = 0; struct sockbase_vfptr *vfptr = sb->vfptr; i64 sz; u32 events = 0; mutex_lock (&sb->lock); while (!sb->fepipe && list_empty (&sb->rcv.head) && !sb->fasync) { sb->rcv.waiters++; condition_wait (&sb->cond, &sb->lock); sb->rcv.waiters--; } if (!list_empty (&sb->rcv.head) ) { msg = list_first (&sb->rcv.head, struct skbuf, item); list_del_init (&msg->item); sz = skbuf_len (msg); sb->rcv.buf -= sz; events |= XMQ_POP; if (sb->rcv.wnd - sb->rcv.buf <= sz) events |= XMQ_NONFULL; if (list_empty (&sb->rcv.head) ) { BUG_ON (sb->rcv.buf); events |= XMQ_EMPTY; } }
int sp_recv (int eid, char **ubuf) { struct epbase *ep = eid_get (eid); if (!ep) { ERRNO_RETURN (EBADF); } mutex_lock (&ep->lock); /* All the received message would saved in the rcv.head. if the endpoint * status ok and the rcv.head is empty, we wait here. when the endpoint * status is bad or has messages come, the wait return. * TODO: can condition_wait support timeout. */ while (!ep->status.shutdown && list_empty (&ep->rcv.head)) { ep->rcv.waiters++; condition_wait (&ep->cond, &ep->lock); ep->rcv.waiters--; } /* Check the endpoint status, maybe it's bad */ if (ep->status.shutdown) { mutex_unlock (&ep->lock); eid_put (eid); ERRNO_RETURN (EBADF); } msgbuf_head_out (&ep->rcv, ubuf); mutex_unlock (&ep->lock); eid_put (eid); return 0; }
void bio_wait(struct bio *bio) { mutex_lock(&bio->mutex); while (bio->status == BIO_NONE) condition_wait(&bio->mutex, &bio->cond); mutex_unlock(&bio->mutex); }
void thread_suspend(thread_t t,int32_t ms) { pthread_t self = pthread_self(); #ifdef _MINGW_ if(self.p != t->threadid.p || self.x != t->threadid.x) return; #else if(self != t->threadid) return;//只能挂起自己 #endif mutex_lock(t->mtx); if(0 >= ms) { t->is_suspend = 1; while(t->is_suspend) { condition_wait(t->cond,t->mtx); } } else { t->is_suspend = 1; condition_timedwait(t->cond,t->mtx,ms); t->is_suspend = 0; } mutex_unlock(t->mtx); }
/* 销毁线程池 */ void threadpool_destroy( threadpool_t* pool ) { if ( pool->quit ) { return ; } /************************** 进入临界区 ***********************/ condition_lock( &pool->ready ) ; // 设置退出标志为真 pool->quit = 1 ; // 如果线程池中正在运行着线程,那么我们需要等待线程执行完毕再销毁 if ( pool->counter > 0 ) { if ( pool->idle > 0 ) { condition_broadcast( &pool->ready ) ; } while ( pool->counter > 0 ) { condition_wait( &pool->ready ) ; // 主线程(main 函数所在线程)将等待在条件变量上 } } condition_unlock( &pool->ready ) ; /************************** 退出临界区 ***********************/ // 销毁条件变量 condition_destroy( &pool->ready ) ; }
int waitgroup_wait(waitgroup_t *wg) { mutex_lock(&wg->mutex); while (wg->ref > 0) condition_wait(&wg->cond, &wg->mutex); mutex_unlock(&wg->mutex); return 0; }
void thread_join(struct thread* target){ mutex_lock(target->mutexLock); if(target->state != DONE){ condition_wait(target->condList, target->mutexLock); }else condition_broadcast(target->condList); }
/* Fetch a message from queue 'q' and store it in 'm' */ int mbox_recv(int q, msg_t * m) { lock_acquire(&Q[q].l); print_trace("Recv", q, -1); /* If no messages available, wait until there is one */ while (Q[q].count == 0) { condition_wait(&Q[q].l, &Q[q].moreData); } /* copy header from mbox.buffer to m */ buffer_to_msg(Q[q].buffer, Q[q].tail, (char *) &m->size, MSG_T_HEADER_SIZE); /* Move tail to the body of message */ Q[q].tail = (Q[q].tail + MSG_T_HEADER_SIZE) % BUFFER_SIZE; /* Copy body of message from mbox.buffer to m->body */ buffer_to_msg(Q[q].buffer, Q[q].tail, (char *) &m->body[0], m->size); /* Move tail to the next message */ Q[q].tail = (Q[q].tail + MSG_SIZE(m) - MSG_T_HEADER_SIZE) % BUFFER_SIZE; /* Freeing space can satisy more than one writter */ condition_broadcast(&Q[q].moreSpace); Q[q].count--; lock_release(&Q[q].l); return 1; }
void tWindow_create_thread(tWindow *p){ DWORD dwThreadId; mutex_create(&p->mutex); if(vb) printf("window create beginning thread\n"); p->thread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)WindowThreadFunc, (LPVOID)p, 0, &dwThreadId); if (p->thread==NULL){ printf("couldn't create thread\n"); return; } if(vb) printf("window create init cond waiting\n"); condition_create(&p->thread_init_cond); condition_wait(&p->thread_init_cond,NULL); if(vb) printf("window create init cond return\n"); condition_destroy(&p->thread_init_cond); }
int ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, ldap_pvt_thread_mutex_t *mutex ) { condition_wait( cond, mutex ); return( 0 ); }
void event_wait_enter(Event *event) { char *message; puts("Press [Enter] to continue"); lock(event); while ((message = event_peek_message(event)) == NULL) { condition_wait(event); } unlock(event); free(message); }
void barrior_wait(barrior_t b) { mutex_lock(b->mtx); --b->wait_count; if(0 == b->wait_count) { condition_broadcast(b->cond); } else { while(b->wait_count > 0) { condition_wait(b->cond,b->mtx); } } mutex_unlock(b->mtx); }
/* otherwise return -1 */ int decrease_count(int count) { sem_wait(&lock); while (available_resources < count) { condition_wait(); } printf("d curr:%d -%d\n", available_resources, count); available_resources -= count; if (next_count > 0) sem_post(&next); else sem_post(&lock); return 0; }
void WA_lock(WA_recursiveLock _lock) #endif { CThreadRecursiveLock *lock = (CThreadRecursiveLock *)_lock; cthread_t self = cthread_self(); #ifdef EXTRA_DEBUGGING_LOGS if (_lock != logMutex) WOLog(WO_DBG, "thread %x locking %s from %s:%d", self, lock->name, file, line); #endif mutex_lock(&lock->m); while (lock->lockingThread != self && lock->lockingThread != NULL) condition_wait(&lock->c, &lock->m); lock->lockingThread = self; lock->lockCount++; mutex_unlock(&lock->m); }
void thread_suspend(thread_t t,int ms) { pthread_t self = pthread_self(); if(self != t->threadid) return;//只能挂起自己 mutex_lock(t->mtx); if(0 >= ms) { t->is_suspend = 1; while(t->is_suspend) { condition_wait(t->cond,t->mtx); } } else { t->is_suspend = 1; condition_timedwait(t->cond,t->mtx,ms); t->is_suspend = 0; } mutex_unlock(t->mtx); }
static struct bio *dequeue_bio(void) { struct bio *bio = 0; mutex_lock(&ide_bio_queue_mutex); while (!done && list_empty(&ide_bio_queue)) condition_wait(&ide_bio_queue_mutex, &ide_bio_queue_condition); if (!list_empty(&ide_bio_queue)) { struct list_head *head = list_first(&ide_bio_queue); list_del(head); bio = LIST_ENTRY(head, struct bio, link); } mutex_unlock(&ide_bio_queue_mutex); return bio; }
int snd_msgbuf_head_add (struct sockbase *sb, struct msgbuf *msg) { int rc = -1; mutex_lock (&sb->lock); while (!sb->flagset.epipe && !msgbuf_can_in (&sb->snd) && !sb->flagset.non_block) { sb->snd.waiters++; condition_wait (&sb->cond, &sb->lock); sb->snd.waiters--; } if (1 || msgbuf_can_in (&sb->snd)) { rc = msgbuf_head_in_msg (&sb->snd, msg); SKLOG_NOTICE (sb, "%d socket sndbuf add %d", sb->fd, msgbuf_len (msg)); } __emit_pollevents (sb); mutex_unlock (&sb->lock); return rc; }
int cpu_idle(void *unused) { for(;;) #ifdef CONFIG_OSFMACH3 { extern struct condition osfmach3_idle_condition; if (intr_count == 0 && (bh_active & bh_mask)) { intr_count++; do_bottom_half(); intr_count--; } uniproc_will_exit(); condition_wait(&osfmach3_idle_condition, &uniproc_mutex); uniproc_has_entered(); } #else /* CONFIG_OSFMACH3 */ idle(); #endif /* CONFIG_OSFMACH3 */ }
void threadpool_destroy(threadpool_t* pool) { if(pool->quit) return; condition_lock(&pool->ready); pool->quit = 1; if(pool->counter > 0) { if(pool->idle > 0) condition_broadcast(&pool->ready); //waiting working thread exit while(pool->counter > 0) condition_wait(&pool->ready); } condition_unlock(&pool->ready); condition_destroy(&pool->ready); }
void tWindow_create_thread(tWindow *p){ pthread_attr_t* att=NULL; mutex_create(&p->mutex); mutex_create(&p->thread_init_mutex); condition_create(&p->thread_init_cond); mutex_lock(&p->thread_init_mutex); if(vb) printf("window create beginning thread\n"); if (vb) printf("tWindow create thread %p %p \n", (void*)p, (void*)WindowThreadFunc); if ((pthread_create(&p->thread, att, WindowThreadFunc, (void*)p ))!=0){ fprintf(stderr,"pthread create error\n"); exit(1); } if (vb) printf("tWindow create thread called\n"); condition_wait(&p->thread_init_cond,&p->thread_init_mutex); mutex_destroy(&p->thread_init_mutex); if(vb) printf("window create init cond return\n"); condition_destroy(&p->thread_init_cond); }
/** * @brief Wait input. * * @param event Event. * @param cmd Command. * @param param Command's parameters. */ void event_wait(Event *event, char **cmd, char **param) { int n; char *message; lock(event); while ((message = event_peek_message(event)) == NULL) { condition_wait(event); } unlock(event); free(*cmd); free(*param); info("<event wait: %s>\n", message); n = strlen(message); *cmd = (char*) malloc(n + 1); *param = (char*) malloc(n + 1); parse_command(message, *cmd, *param, n); free(message); }
//销毁线程池 void threadpool_destory(threadpool_t *pool) { if(pool -> quit) { return; } condition_lock(&pool -> ready); pool->quit = 1; if(pool -> counter > 0) { if(pool -> idle > 0) condition_broadcast(&pool->ready); while(pool -> counter > 0) { condition_wait(&pool->ready); } } condition_unlock(&pool->ready); condition_destory(&pool -> ready); }
/* Insert 'm' into the mailbox 'q' */ int mbox_send(int q, msg_t * m) { int msgSize = MSG_SIZE(m); lock_acquire(&Q[q].l); print_trace("Send", q, msgSize); /* Wait until there is enough space */ while (space_available(&Q[q]) < msgSize) { condition_wait(&Q[q].l, &Q[q].moreSpace); } /* copy from message m (header and body) to Q[q].buffer */ msg_to_buffer((char *) m, msgSize, Q[q].buffer, Q[q].head); Q[q].head = (Q[q].head + msgSize) % BUFFER_SIZE; /* Send of one message can only satisfy one reader. */ condition_signal(&Q[q].moreData); Q[q].count++; lock_release(&Q[q].l); return 1; }
/* Implement the object termination call from the kernel as described in <mach/memory_object.defs>. */ kern_return_t _pager_seqnos_memory_object_terminate (mach_port_t object, mach_port_seqno_t seqno, mach_port_t control, mach_port_t name) { struct pager *p; p = ports_lookup_port (0, object, _pager_class); if (!p) return EOPNOTSUPP; mutex_lock (&p->interlock); _pager_wait_for_seqno (p, seqno); if (control != p->memobjcntl) { printf ("incg terminate: wrong control port"); goto out; } if (name != p->memobjname) { printf ("incg terminate: wrong name port"); goto out; } while (p->noterm) { p->termwaiting = 1; condition_wait (&p->wakeup, &p->interlock); } /* Destry the ports we received; mark that in P so that it doesn't bother doing it again. */ mach_port_destroy (mach_task_self (), control); mach_port_destroy (mach_task_self (), name); p->memobjcntl = p->memobjname = MACH_PORT_NULL; _pager_free_structure (p); #ifdef KERNEL_INIT_RACE if (p->init_head) { struct pending_init *i = p->init_head; p->init_head = i->next; if (!i->next) p->init_tail = 0; p->memobjcntl = i->control; p->memobjname = i->name; memory_object_ready (i->control, p->may_cache, p->copy_strategy); p->pager_state = NORMAL; free (i); } #endif out: _pager_release_seqno (p, seqno); mutex_unlock (&p->interlock); ports_port_deref (p); return 0; }
/* Find the location on disk of page OFFSET in pager UPI. Return the disk address (in disk block) in *ADDR. If *NPLOCK is set on return, then release that mutex after I/O on the data has completed. Set DISKSIZE to be the amount of valid data on disk. (If this is an unallocated block, then set *ADDR to zero.) ISREAD is non-zero iff this is for a pagein. */ static error_t find_address (struct user_pager_info *upi, vm_address_t offset, daddr_t *addr, int *disksize, struct rwlock **nplock, int isread) { error_t err; struct rwlock *lock; assert (upi->type == DISK || upi->type == FILE_DATA); if (upi->type == DISK) { *disksize = __vm_page_size; *addr = offset / DEV_BSIZE; *nplock = 0; return 0; } else { struct iblock_spec indirs[NIADDR + 1]; struct node *np; np = upi->np; if (isread) { try_again: /* If we should allow an unlocked pagein, do so. (This still has a slight race; there could be a pageout in progress which is blocked on NP->np->allocptrlock itself. In that case the pagein that should proceed unimpeded is blocked in the pager library waiting for the pageout to complete. I think this is sufficiently rare to put it off for the time being.) */ spin_lock (&unlocked_pagein_lock); if (offset >= upi->allow_unlocked_pagein && (offset + vm_page_size <= upi->allow_unlocked_pagein + upi->unlocked_pagein_length)) { spin_unlock (&unlocked_pagein_lock); *nplock = 0; goto have_lock; } spin_unlock (&unlocked_pagein_lock); /* Block on the rwlock if necessary; but when we wake up, don't acquire it; check again from the top. This is mutated inline from rwlock.h. */ lock = &np->dn->allocptrlock; mutex_lock (&lock->master); if (lock->readers == -1 || lock->writers_waiting) { lock->readers_waiting++; condition_wait (&lock->wakeup, &lock->master); lock->readers_waiting--; mutex_unlock (&lock->master); goto try_again; } lock->readers++; mutex_unlock (&lock->master); *nplock = lock; } else { rwlock_reader_lock (&np->dn->allocptrlock); *nplock = &np->dn->allocptrlock; } have_lock: if (offset >= np->allocsize) { if (*nplock) rwlock_reader_unlock (*nplock); if (isread) return EIO; else { *addr = 0; *disksize = 0; return 0; } } if (offset + __vm_page_size > np->allocsize) *disksize = np->allocsize - offset; else *disksize = __vm_page_size; err = fetch_indir_spec (np, lblkno (sblock, offset), indirs); if (err && *nplock) rwlock_reader_unlock (*nplock); else { if (indirs[0].bno) *addr = (fsbtodb (sblock, indirs[0].bno) + blkoff (sblock, offset) / DEV_BSIZE); else *addr = 0; } return err; } }
void syscall_condition_wait(cond_t* cond, lock_t* lock) { condition_wait(cond, lock); }