예제 #1
0
/* 销毁线程池 */
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 ) ;
}
예제 #2
0
파일: waitgroup.c 프로젝트: wbsabc/xio
static inline int __waitgroup_decr(waitgroup_t *wg, int refs) {
    mutex_lock(&wg->mutex);
    if ((wg->ref -= refs) == 0)
	condition_broadcast(&wg->cond);
    mutex_unlock(&wg->mutex);
    return 0;
}
예제 #3
0
파일: mbox.c 프로젝트: robertsami/proj
/* 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;
}
예제 #4
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);
}
예제 #5
0
void thread_wrap(){
	mutex_lock(current_thread->mutexLock);
	current_thread->initial_function(current_thread->initial_argument);
	current_thread->state = DONE;
	mutex_unlock(current_thread->mutexLock);
	condition_broadcast(current_thread->condList);
	yield();
};
예제 #6
0
파일: send.c 프로젝트: liexusong/xio
struct msgbuf *__snd_msgbuf_head_rm (struct sockbase *sb) {
	int rc;
	struct msgbuf *msg = 0;

	if ((rc = msgbuf_head_out_msg (&sb->snd, &msg)) == 0) {
		if (sb->snd.waiters > 0)
			condition_broadcast (&sb->cond);
		SKLOG_NOTICE (sb, "%d socket sndbuf rm %d", sb->fd, msgbuf_len (msg));
	}
	__emit_pollevents (sb);
	return msg;
}
예제 #7
0
파일: sync.c 프로젝트: Sim-szm/YunDu
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);
}
예제 #8
0
파일: rep_ep.c 프로젝트: tniuli/xio
static int repep_add (struct epbase *ep, struct tgtd *tg, char *ubuf)
{
	struct rtentry *rt = rt_cur (ubuf);

	if (uuid_compare (rt->uuid, get_rep_tgtd (tg)->uuid) )
		uuid_copy (get_rep_tgtd (tg)->uuid, rt->uuid);
	DEBUG_OFF ("ep %d recv req %10.10s from socket %d", ep->eid, ubuf, tg->fd);
	mutex_lock (&ep->lock);
	skbuf_head_in (&ep->rcv, ubuf);
	BUG_ON (ep->rcv.waiters < 0);
	if (ep->rcv.waiters)
		condition_broadcast (&ep->cond);
	mutex_unlock (&ep->lock);
	return 0;
}
void
ports_resume_port_rpcs (void *portstruct)
{
  struct port_info *pi = portstruct;
  
  mutex_lock (&_ports_lock);
  
  assert (pi->flags & PORT_INHIBITED);
  pi->flags &= ~PORT_INHIBITED;
  if (pi->flags & PORT_BLOCKED)
    {
      pi->flags &= ~PORT_BLOCKED;
      condition_broadcast (&_ports_block);
    }
  mutex_unlock (&_ports_lock);
}
예제 #10
0
/* If there are characters on the output queue, then send them.  Is
   called with global lock held.  */
static error_t
hurdio_start_output ()
{
  /* If the output was suspended earlier and not anymore, we have to
     tell the underlying port to resume it.  */
  if (output_stopped && !(termflags & USER_OUTPUT_SUSP))
    {
      if (tioc_caps & TIOC_CAP_START)
	{
	  error_t err = tioctl_tiocstart (ioport);
	  if (err && (err == EMIG_BAD_ID || err == EOPNOTSUPP))
	    tioc_caps &= ~TIOC_CAP_START;
	}
      output_stopped = 0;
    }
  condition_broadcast (&hurdio_writer_condition);
  return 0;
}
예제 #11
0
/* Shared code for termination from memory_object_terminate and
   no-senders.  The pager must be locked.  This routine will
   deallocate all the ports and memory that pager P references.  */
void
_pager_free_structure (struct pager *p)
{
  int wakeup;
  struct lock_request *lr;
  struct attribute_request *ar;

  wakeup = 0;
  for (lr = p->lock_requests; lr; lr = lr->next)
    {
      lr->locks_pending = 0;
      if (!lr->pending_writes)
	wakeup = 1;
    }
  for (ar = p->attribute_requests; ar; ar = ar->next)
    {
      ar->attrs_pending = 0;
      wakeup = 1;
    }

  if (wakeup)
    condition_broadcast (&p->wakeup);

  if (p->memobjcntl != MACH_PORT_NULL)
    {
      mach_port_deallocate (mach_task_self (), p->memobjcntl);
      p->memobjcntl = MACH_PORT_NULL;
    }
  if (p->memobjname != MACH_PORT_NULL)
    {
      mach_port_deallocate (mach_task_self (), p->memobjname);
      p->memobjname = MACH_PORT_NULL;
    }

  /* Free the pagemap */
  if (p->pagemapsize)
    {
      munmap (p->pagemap, p->pagemapsize * sizeof (* p->pagemap));
      p->pagemapsize = 0;
      p->pagemap = 0;
    }
  
  p->pager_state = NOTINIT;
}
예제 #12
0
/* Assert the DTR if necessary.  Must be called with global lock held.  */
static void
wait_for_dtr (void)
{
  while (!assert_dtr)
    hurd_condition_wait (&hurdio_assert_dtr_condition, &global_lock);
  assert_dtr = 0;

  if (tty_arg == 0)
    ioport = termctl->underlying;
  else
    {
      /* Open the file in blocking mode, so that the carrier is
	 established as well.  */
      ioport = file_name_lookup (tty_arg, O_READ|O_WRITE, 0);
      if (ioport == MACH_PORT_NULL)
	{
	  report_carrier_error (errno);
	  return;
	}
    }


  error_t err;
  struct termios state = termstate;

  /* Assume that we have a full blown terminal initially.  */
  tioc_caps = ~0;

  /* Set terminal in raw mode etc.  */
  err = hurdio_set_bits (&state);
  if (err)
    report_carrier_error (err);
  else
    {
      termstate = state;

      /* Signal that we have a carrier.  */
      report_carrier_on ();

      /* Signal that the writer thread should resume its work.  */
      condition_broadcast (&hurdio_writer_condition);
    }
}
예제 #13
0
/* A process is dying.  Send SIGCHLD to the parent.
   Wake the parent if it is waiting for us to exit. */
void
alert_parent (struct proc *p)
{
  /* We accumulate the aggregate usage stats of all our dead children.  */
  rusage_add (&p->p_parent->p_child_rusage, &p->p_rusage);

  send_signal (p->p_parent->p_msgport, SIGCHLD, p->p_parent->p_task);

  if (!p->p_exiting)
    {
      p->p_status = W_EXITCODE (0, SIGKILL);
      p->p_sigcode = -1;
    }

  if (p->p_parent->p_waiting)
    {
      condition_broadcast (&p->p_parent->p_wakeup);
      p->p_parent->p_waiting = 0;
    }
}
예제 #14
0
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);
}
예제 #15
0
//销毁线程池
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);
}
예제 #16
0
/* Place the mouse event EVNT in the mouse event buffer.  */
static void
repeat_event (kd_event *evt)
{
  kd_event *ev;

  mutex_lock (&global_lock);
  while (mousebuf.size + sizeof (kd_event) > MOUSEBUFSZ)
    {
      /* The input buffer is full, wait until there is some space.  */
      if (hurd_condition_wait (&mousebuf.writecond, &global_lock))
	{
	  mutex_unlock (&global_lock);
	  /* Interrupt, silently continue.  */
	}
    }
  ev = (kd_event *) &mousebuf.evtbuffer[MOUSEBUF_POS (mousebuf.pos 
						      + mousebuf.size)];
  mousebuf.size += sizeof (kd_event);
  memcpy (ev, evt, sizeof (kd_event));
  
  condition_broadcast (&mousebuf.readcond);
  mutex_unlock (&global_lock);
}
예제 #17
0
static void
close_hook (struct trivfs_peropen *po)
{
    int was_active, detach = 0;
    int flags = po->openmodes;
    struct pipe *pipe = po->hook;

    if (!pipe)
        return;

    mutex_lock (&active_fifo_lock);
    was_active = (active_fifo == pipe);

    if (was_active)
        /* See if PIPE should cease to be the user-visible face of this fifo.  */
        detach =
            ((flags & O_READ) && pipe->readers == 1)
            || ((flags & O_WRITE) && pipe->writers == 1);
    else
        /* Let others have their fun.  */
        mutex_unlock (&active_fifo_lock);

    if (flags & O_READ)
        pipe_remove_reader (pipe);
    if (flags & O_WRITE)
        pipe_remove_writer (pipe);
    /* At this point, PIPE may be gone, so we can't look at it again.  */

    if (was_active)
    {
        if (detach)
            active_fifo = NULL;
        condition_broadcast (&active_fifo_changed);
        mutex_unlock (&active_fifo_lock);
    }
}
예제 #18
0
/* Implement proc_mark_stop as described in <hurd/process.defs>. */
kern_return_t
S_proc_mark_stop (struct proc *p,
		  int signo,
		  int sigcode)
{
  if (!p)
    return EOPNOTSUPP;

  p->p_stopped = 1;
  p->p_status = W_STOPCODE (signo);
  p->p_sigcode = sigcode;
  p->p_waited = 0;

  if (p->p_parent->p_waiting)
    {
      condition_broadcast (&p->p_parent->p_wakeup);
      p->p_parent->p_waiting = 0;
    }

  if (!p->p_parent->p_nostopcld)
    send_signal (p->p_parent->p_msgport, SIGCHLD, p->p_parent->p_task);

  return 0;
}
예제 #19
0
static error_t
open_hook (struct trivfs_peropen *po)
{
    error_t err = 0;
    int flags = po->openmodes;

    if (flags & (O_READ | O_WRITE))
    {
        mutex_lock (&active_fifo_lock);

        /* Wait until the active fifo has changed so that CONDITION is true.  */
#define WAIT(condition, noblock_err)					      \
  while (!err && !(condition))						      \
    {									      \
      if (flags & O_NONBLOCK)						      \
	{								      \
	  err = noblock_err;						      \
	  break;							      \
	}								      \
      else if (hurd_condition_wait (&active_fifo_changed, &active_fifo_lock)) \
	err = EINTR;							      \
    }

        if (flags & O_READ)
            /* When opening for read, what we do depends on what mode this server
               is running in.  The default (if ONE_READER is set) is to only
               allow one reader at a time, with additional opens for read
               blocking here until the old reader goes away; otherwise, we allow
               multiple readers.  If WAIT_FOR_WRITER is true, then once we've
               created a fifo, we also block until someone opens it for writing;
               otherwise, the first read will block until someone writes
               something.  */
        {
            if (one_reader)
                /* Wait until there isn't any active fifo, so we can make one. */
                WAIT (!active_fifo || !active_fifo->readers, EWOULDBLOCK);

            if (!err && active_fifo == NULL)
                /* No other readers, and indeed, no fifo; make one.  */
            {
                err = pipe_create (fifo_pipe_class, &active_fifo);
                if (! err)
                    active_fifo->flags &= ~PIPE_BROKEN; /* Avoid immediate EOF. */
            }
            if (!err)
            {
                pipe_add_reader (active_fifo);
                condition_broadcast (&active_fifo_changed);
                /* We'll unlock ACTIVE_FIFO_LOCK below; the writer code won't
                make us block because we've ensured that there's a reader
                 for it.  */

                if (wait_for_writer)
                    /* Wait until there's a writer.  */
                {
                    WAIT (active_fifo->writers, 0);
                    if (err)
                        /* Back out the new pipe creation.  */
                    {
                        pipe_remove_reader (active_fifo);
                        active_fifo = NULL;
                        condition_broadcast (&active_fifo_changed);
                    }
                }
            }
        }

        if (!err && (flags & O_WRITE))
            /* Open the active_fifo for writing.  If WAIT_FOR_READER is true,
               then we block until there's someone to read what we wrote,
               otherwise, if there's no fifo, we create one, which we just write
               into and leave it for someone to read later.  */
        {
            if (wait_for_reader)
                /* Wait until there's a fifo to write to.  */
                WAIT (active_fifo && active_fifo->readers, ENXIO);
            if (!err && active_fifo == NULL)
                /* No other readers, and indeed, no fifo; make one.  */
            {
                err = pipe_create (fifo_pipe_class, &active_fifo);
                if (!err)
                    active_fifo->flags &= ~PIPE_BROKEN;
            }
            if (!err)
            {
                pipe_add_writer (active_fifo);
                condition_broadcast (&active_fifo_changed);
            }
        }

        po->hook = active_fifo;

        mutex_unlock (&active_fifo_lock);
    }

    return err;
}
예제 #20
0
/* Output characters.  */
static any_t
hurdio_writer_loop (any_t arg)
{
  /* XXX The output buffer has 256 bytes.  */
#define BUFFER_SIZE 256
  char *bufp;
  char pending_output[BUFFER_SIZE];
  size_t amount;
  error_t err;
  int size;
  int npending_output_copy;
  mach_port_t ioport_copy;

  mutex_lock (&global_lock);
  writer_thread = mach_thread_self ();

  while (1)
    {
      while (writer_thread != MACH_PORT_NULL
	     && (ioport == MACH_PORT_NULL || !qsize (outputq)
		 || output_stopped))
	hurd_condition_wait (&hurdio_writer_condition, &global_lock);
      if (writer_thread == MACH_PORT_NULL) /* A sign to die.  */
	return 0;

      /* Copy characters onto PENDING_OUTPUT, not bothering
	 those already there. */
      size = qsize (outputq);

      if (size + npending_output > BUFFER_SIZE)
	size = BUFFER_SIZE - npending_output;

      bufp = pending_output + npending_output;
      npending_output += size;
      /* We need to save these values, as otherwise there are races
	 with hurdio_abandon_physical_output or hurdio_desert_dtr,
	 which might overwrite the static variables.  */
      npending_output_copy = npending_output;
      ioport_copy = ioport;
      mach_port_mod_refs (mach_task_self (), ioport_copy,
			  MACH_PORT_RIGHT_SEND, 1);

      while (size--)
	*bufp++ = dequeue (outputq);

      /* Submit all the outstanding characters to the I/O port.  */
      mutex_unlock (&global_lock);
      err = io_write (ioport_copy, pending_output, npending_output_copy,
		      -1, &amount);
      mutex_lock (&global_lock);

      mach_port_mod_refs (mach_task_self (), ioport_copy,
			  MACH_PORT_RIGHT_SEND, -1);
      if (err)
	hurdio_desert_dtr ();
      else
	{
	  /* Note that npending_output might be set to null in the
	     meantime by hurdio_abandon_physical_output.  */
	  if (amount >= npending_output)
	    {
	      npending_output = 0;
	      condition_broadcast (outputq->wait);
	    }
	  else
	    {
	      /* Copy the characters that didn't get output
		 to the front of the array.  */
	      npending_output -= amount;
	      memmove (pending_output, pending_output + amount,
		       npending_output);
	    }
	}
    }
#undef BUFFER_SIZE

  return 0;
}
예제 #21
0
static error_t
repeater_read (struct protid *cred, char **data,
	       mach_msg_type_number_t *datalen, off_t offset,
	       mach_msg_type_number_t amount)
{
  /* Deny access if they have bad credentials. */
  if (! cred)
    return EOPNOTSUPP;
  else if (! (cred->po->openstat & O_READ))
    return EBADF;
  
  mutex_lock (&global_lock);
  while (!mousebuf.size)
    {
      if (cred->po->openstat & O_NONBLOCK && mousebuf.size == 0)
	{
	  mutex_unlock (&global_lock);
	  return EWOULDBLOCK;
	}
      
      if (hurd_condition_wait (&mousebuf.readcond, &global_lock))
	{
	  mutex_unlock (&global_lock);
	  return EINTR;
	}
    }
  
  amount = (amount / sizeof (kd_event) - 1) * sizeof (kd_event);
  if (amount > mousebuf.size)
    amount = mousebuf.size;
  
  if (amount > 0)
    {
      char *mousedata;
      unsigned int i = 0;

      /* Allocate a buffer when this is required.  */
      if (*datalen < amount)
	{
	  *data = mmap (0, amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
	  if (*data == MAP_FAILED)
	    {
	      mutex_unlock (&global_lock);
	      return ENOMEM;
	    }
	}
      
      /* Copy the bytes to the user's buffer and remove them from the
	 mouse events buffer.  */
      mousedata = *data;
      while (i != amount)
	{
	  mousedata[i++] = mousebuf.evtbuffer[mousebuf.pos++];
	  mousebuf.pos = MOUSEBUF_POS (mousebuf.pos);
	}
      mousebuf.size -= amount;
      condition_broadcast (&mousebuf.writecond);
    }
  
  *datalen = amount;
  mutex_unlock (&global_lock);

  return 0;
}
예제 #22
0
파일: thr_cthreads.c 프로젝트: 1ack/Impala
int
ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
{
	condition_broadcast( cond );
	return( 0 );
}
예제 #23
0
파일: syscall.c 프로젝트: bjornua/OSM
void syscall_condition_broadcast(cond_t* cond, lock_t* lock)
{
    condition_broadcast(cond, lock);
}