예제 #1
0
void
rpc_ctx_ack_xfer(rpc_ctx_t *ctx)
{
    struct x_vc_data *xd = (struct x_vc_data *) ctx->ctx_u.clnt.clnt->cl_p1;
    rpc_dplx_lock_t *lk = &xd->rec->recv.lock;

    ctx->flags |= RPC_CTX_FLAG_ACKSYNC;
    cond_signal(&lk->we.cv); /* XXX we hold lk->we.mtx */
}
예제 #2
0
파일: worker.c 프로젝트: russross/envoy
void worker_multistep_transfer_request(Worker *worker,
                                       void (*func)(Worker *, void *), void *arg)
{
    assert(worker->func == NULL);
    assert(worker->arg == NULL);
    worker->func = func;
    worker->arg = arg;
    cond_signal(worker->sleep);
}
예제 #3
0
파일: control.c 프로젝트: eldesh/smlsharp
static void
sync1_action()
{
	if (fetch_sub(relaxed, &sync_counter, 1) - 1 == 0) {
		mutex_lock(&sync_wait_lock);
		cond_signal(&sync_wait_cond);
		mutex_unlock(&sync_wait_lock);
	}
}
예제 #4
0
파일: synch.c 프로젝트: ITSophia/Pintos
/* Wakes up all threads, if any, waiting on COND (protected by
   LOCK).  LOCK must be held before calling this function.

   An interrupt handler cannot acquire a lock, so it does not
   make sense to try to signal a condition variable within an
   interrupt handler. */
void
cond_broadcast (struct condition *cond, struct lock *lock)
{
  ASSERT (cond != NULL);
  ASSERT (lock != NULL);

  while (!list_empty (&cond->waiters))
    cond_signal (cond, lock);
}
예제 #5
0
파일: semaphore.c 프로젝트: jgibson5/Olin
/* Increments the semaphore */
void incr_semaphore(Semaphore *semaphore) {
  mutex_lock(semaphore->mutex);
  printf("PLUS-----%d\n", semaphore->value);
  semaphore->value++;
  printf("PLUS-----%d\n", semaphore->value);
  mutex_unlock(semaphore->mutex);
  if (semaphore->value == 1)
    cond_signal(semaphore->cond);
}
예제 #6
0
/*
 *	force_media - unload a drive. Issued as a delayed request.
 *
 */
req_comp_t
force_media(
	library_t *library,
	drive_state_t *drive)
{
	req_comp_t 	err;
	ibm_req_info_t 	*ibm_info;
	robo_event_t 	*force, *tmp;
	xport_state_t 	*transport;

	ibm_info = (ibm_req_info_t *)malloc_wait(sizeof (ibm_req_info_t), 2, 0);
	memset(ibm_info, 0, sizeof (ibm_req_info_t));
	ibm_info->drive_id = drive->drive_id;

	/* Build transport thread request */

	force = malloc_wait(sizeof (robo_event_t), 5, 0);
	(void) memset(force, 0, sizeof (robo_event_t));

	force->request.internal.command = ROBOT_INTRL_FORCE_MEDIA;
	force->request.internal.address = (void *)ibm_info;

	if (DBG_LVL(SAM_DBG_TMOVE))
		sam_syslog(LOG_DEBUG, "force_media: from %s.", drive->un->name);

	force->type = EVENT_TYPE_INTERNAL;
	force->status.bits = REST_SIGNAL;
	force->completion = REQUEST_NOT_COMPLETE;

	transport = library->transports;
	mutex_lock(&force->mutex);
	mutex_lock(&transport->list_mutex);
	if (transport->active_count == 0)
		transport->first = force;
	else {
		LISTEND(transport, tmp);
		append_list(tmp, force);
	}
	transport->active_count++;
	cond_signal(&transport->list_condit);
	mutex_unlock(&transport->list_mutex);

	/* Wait for the transport to do the unload */
	while (force->completion == REQUEST_NOT_COMPLETE)
		cond_wait(&force->condit, &force->mutex);
	mutex_unlock(&force->mutex);

	err = (req_comp_t)force->completion;
	if (DBG_LVL(SAM_DBG_TMOVE))
		sam_syslog(LOG_DEBUG,
		    "Return from transport force (%#x).", force->completion);

	free(ibm_info);
	mutex_destroy(&force->mutex);
	free(force);
	return (err);
}
예제 #7
0
void phi_test_condvar (i) { 
    if(state_condvar[i]==HUNGRY&&state_condvar[LEFT]!=EATING
            &&state_condvar[RIGHT]!=EATING) {
        cprintf("phi_test_condvar: state_condvar[%d] will eating\n",i);
        state_condvar[i] = EATING ;
        cprintf("phi_test_condvar: signal self_cv[%d] \n",i);
        cond_signal(&mtp->cv[i]) ;
    }
}
예제 #8
0
void bounded_buffer_put(bounded_buffer_t *b, void* ptr) {
    mutex_lock(&b->mutex);
    while (b->count == b->size)
        cond_wait(&b->empty, &b->mutex);
    b->buffer[b->tail] = ptr;
    b->tail = (b->tail + 1) % b->size;
    b->count++;
    cond_signal(&b->fill);
    mutex_unlock(&b->mutex);
}
예제 #9
0
void sl_append(struct SynchList *sl, void *item)
{
  lock_acquire(&sl->sl_lock);                // enforce mutual exclusive access to the list 
  struct SL_element *sl_elem = malloc(sizeof(struct SL_element));
  sl_elem->item = item;
  list_push_back(&sl->sl_list, &sl_elem->elem);
  cond_signal(&sl->sl_empty,&sl->sl_lock);  // wake up a waiter, if any
  lock_release(&sl->sl_lock);              
  return;
}
예제 #10
0
void cache_shared_post(struct cache_block * curr_block, uint8_t dirty) {
    lock_acquire(&curr_block->modify_variables);
    curr_block->accessors--;
    curr_block->use = 1;
    if (dirty) {
        curr_block->dirty = dirty;
    }
    cond_signal(&curr_block->need_to_evict, &curr_block->modify_variables);
    lock_release(&curr_block->modify_variables);
}
void sem_signal (Semaphore *semaphore) {
  mutex_lock (semaphore->mutex);
  semaphore->value++;

  if (semaphore->value <= 0) {
    semaphore->wakeups++;
    cond_signal (semaphore->cond);
  }
  mutex_unlock (semaphore->mutex);
}
예제 #12
0
/*
 * set new state for a device.
 *
 * Programming note:  The parameter passed in was malloc'ed, be sure
 * to free it before thr_exit.
 */
void *
set_state(
	void *vcmd)
{
	int old_state;
	sam_cmd_fifo_t *command = (sam_cmd_fifo_t *)vcmd;
	dev_ent_t *device, *robot = NULL;
	message_request_t *message = NULL;

	/* equipment was verified in the caller */

	device = DEV_ENT(command->eq);
	if (device->fseq) {
		robot = DEV_ENT(device->fseq);
	}
	if (command->state >= DEV_ON && command->state <= DEV_DOWN &&
	    command->state != DEV_NOALLOC) {
		old_state = device->state;
		if (robot != NULL) {
			device = robot;
			if (IS_ROBOT(device) && device->status.b.present) {
				message = (message_request_t *)SHM_REF_ADDR(
				    device->dt.rb.message);
			}
		} else if (IS_OPTICAL(device) || IS_TAPE(device)) {
			/* send to scanner */
			message = (message_request_t *)SHM_REF_ADDR(
			    ((shm_ptr_tbl_t *)master_shm.shared_memory)->
			    scan_mess);
		}
		if (message != NULL) {
			(void) mutex_lock(&message->mutex);
			while (message->mtype != MESS_MT_VOID) {
				cond_wait(&message->cond_i, &message->mutex);
			}
			memset(&message->message, 0, sizeof (sam_message_t));
			message->message.magic = MESSAGE_MAGIC;
			message->message.command = MESS_CMD_STATE;
			message->message.exit_id = command->exit_id;
			message->message.param.state_change.flags =
			    command->flags;
			message->message.param.state_change.eq = command->eq;
			message->message.param.state_change.old_state =
			    old_state;
			message->message.param.state_change.state =
			    command->state;
			message->mtype = MESS_MT_NORMAL;
			cond_signal(&message->cond_r);
			mutex_unlock(&message->mutex);
		}
	}
	free(command);			/* free the command buffer */
	thr_exit(NULL);
/* LINTED Function has no return statement */
}
예제 #13
0
파일: worker.c 프로젝트: vivekp/minix-1
/*===========================================================================*
 *				worker_wake				     *
 *===========================================================================*/
PRIVATE void worker_wake(struct worker_thread *worker)
{
/* Signal a worker to wake up */
  ASSERTW(worker);
  if (mutex_lock(&worker->w_event_mutex) != 0)
	panic("unable to lock event mutex");
  if (cond_signal(&worker->w_event) != 0)
	panic("unable to signal conditional variable");
  if (mutex_unlock(&worker->w_event_mutex) != 0)
	panic("unable to unlock event mutex");
}
예제 #14
0
파일: control.c 프로젝트: eldesh/smlsharp
static void
control_leave(struct sml_control *control)
{
	assert(load_relaxed(&control->state) == ACTIVE(ASYNC));
	/* unlock; all updates so far must be released */
	store_release(&control->state, INACTIVE(ASYNC));
	if (load_relaxed(&stop_the_world_flag)) {
		mutex_lock(&control->inactive_wait_lock);
		cond_signal(&control->inactive_wait_cond);
		mutex_unlock(&control->inactive_wait_lock);
	}
}
예제 #15
0
/*
 * add catalog command
 *
 * Programming note:  The parameter passed in was malloc'ed, be sure
 * to free it before thr_exit.
 */
void *
add_catalog_cmd(
	void *vcmd)
{
	sam_cmd_fifo_t *command = (sam_cmd_fifo_t *)vcmd;
	dev_ent_t *device;
	message_request_t *message;

	if (command->vsn[0] == '\0' && !(command->flags & ADDCAT_BARCODE)) {
		sam_syslog(LOG_INFO,
		    catgets(catfd, SET, 11008,
		    "Add catalog, vsn not supplied."));
	} else {
		device = DEV_ENT(DEV_ENT(command->eq)->fseq);
		if ((IS_GENERIC_API(device->type) ||
		    device->type == DT_STKAPI ||
		    device->type == DT_SONYPSC ||
		    device->type == DT_IBMATL) ||
		    device->type == DT_HISTORIAN &&
		    (device->state < DEV_IDLE) &&
		    (device->status.b.ready && device->status.b.present)) {
			message = (message_request_t *)
			    SHM_REF_ADDR(device->dt.rb.message);
			(void) mutex_lock(&message->mutex);
			while (message->mtype != MESS_MT_VOID) {
				cond_wait(&message->cond_i, &message->mutex);
			}
			memset(&message->message, 0, sizeof (sam_message_t));
			message->message.magic = MESSAGE_MAGIC;
			message->message.command = MESS_CMD_ADD;
			message->message.exit_id = command->exit_id;
			message->mtype = MESS_MT_NORMAL;
			message->message.param.addcat_request.media =
			    command->media;
			message->message.param.addcat_request.flags =
			    command->flags;
			memmove(&message->message.param.addcat_request.vsn[0],
			    &command->vsn[0], sizeof (vsn_t));
			if (command->flags & ADDCAT_BARCODE) {
				memccpy(&message->
				    message.param.addcat_request.bar_code[0],
				    &command->info[0], '\0', BARCODE_LEN);
			}
			cond_signal(&message->cond_r);
			mutex_unlock(&message->mutex);
		}
	}

	free(command);			/* free the command buffer */
	thr_exit(NULL);
/* LINTED Function has no return statement */
}
예제 #16
0
void unbounded_buffer_put(unbounded_buffer_t *b, void *ptr) {
    node_t *node = (node_t *)mem_malloc(sizeof(node_t));
    node->ptr = ptr;
    node->next = NULL;
    mutex_lock(&b->tail_mutex);
    b->tail->next = node;
    b->tail = node;
    mutex_lock(&b->mutex);
    mutex_unlock(&b->tail_mutex);
    b->count++;
    cond_signal(&b->fill);
    mutex_unlock(&b->mutex);
}
예제 #17
0
파일: slp_utils.c 프로젝트: andreiw/polaris
void slp_end_call(slp_handle_impl_t *hp) {
	(void) mutex_lock(&(hp->outcall_lock));
	if (hp->close_on_end) {
	    /* SLPClose() called from callback */
	    (void) mutex_unlock(&(hp->outcall_lock));
	    slp_cleanup_handle(hp);
	    return;
	}

	hp->pending_outcall = SLP_FALSE;
	(void) cond_signal(&(hp->outcall_cv));
	(void) mutex_unlock(&(hp->outcall_lock));
}
예제 #18
0
/*
 *Cierra un /proc en el modo especificado por el parametro de entrada
 *bool lectura ==> 1 cierra en modo lectura, 0 cierra en modo escritura
 */
void fifoproc_release(bool lectura) {
	lock(mtx);
		/*Si queremos cerrar un fichero en modo lectura, reducimos
		 *el numero de consumidores en una unidad y, en caso de que
		 *ya no existan productores, limpiamos el buffer*/
		if(lectura) {
			cons_count--;
			cond_signal(prod);
		}

		/*Si queremos cerrar un fichero en modo escritura, reducimos
		 *el numero de productores en una unidad y, en caso de que
		 *ya no existan consumidores, limpiamos el buffer*/
		else {
			prod_count--;
			cond_signal(cons);
		}

		if((prod_count ==0) && (cons_count ==0))
			clear_cbuffer_t(cbuffer);
	unlock(mtx);
}
예제 #19
0
/* Child process monitoring function */
void *process_monitor() {
  pid_t child_pid; /* pid of zombie child */
  int status, time_interval; /* child exit status; interval between time_t's */
  
  while(true) {
    
    mutex_lock(&g_mutex);
    if(g_num_children > 0) {
      mutex_unlock(&g_mutex);
      
      child_pid = wait(&status);
      
      if(child_pid < 0) {
          if(errno == EINTR) /* Waiting interrupted */
            continue;
          else
            handle_error("wait");
      }
      
      mutex_lock(&g_mutex);
      time_interval = update_terminated_process(g_lst_children,
        child_pid, status, time(NULL));
      
      if(time_interval < 0) {
        fprintf(stderr, "update_terminated_process: interval is negative\n");
        fprintf(stderr, "Not logging process %d..\n", child_pid);
      } else {
        g_total_time += time_interval;
  
        fprintf(g_log_file, "iteracao %d\n" \
                "PID: %d execution time: %02d s\n" \
                "total execution time: %02d s\n",
                g_iterations++, child_pid, time_interval, g_total_time);
        f_flush(g_log_file);
      }
      --g_num_children;
      
      cond_signal(&g_child_cv);
      mutex_unlock(&g_mutex);
      
    } else if(g_monitoring) {
      while(g_num_children == 0 && g_monitoring)
        cond_wait(&g_monitoring_cv, &g_mutex);
      mutex_unlock(&g_mutex);
    }
    else break;
  }
  mutex_unlock(&g_mutex);
  
  return NULL;
}
예제 #20
0
static void
lxt_server_loop(void)
{
	lxt_req_t		*lxt_req;
	lxt_server_arg_t	*request;
	size_t			request_size;
	char			*door_result;
	size_t			door_result_size;

	for (;;) {
		/* Wait for a request from a doors server thread. */
		(void) mutex_lock(&lxt_req_lock);
		while (lxt_req_ptr == NULL)
			(void) cond_wait(&lxt_req_cv, &lxt_req_lock);

		/* We got a request, get a local pointer to it. */
		lxt_req = lxt_req_ptr;
		lxt_req_ptr = NULL;
		(void) cond_broadcast(&lxt_req_cv);
		(void) mutex_unlock(&lxt_req_lock);

		/* Get a pointer to the request. */
		request = lxt_req->lxtr_request;
		request_size = lxt_req->lxtr_request_size;

		lx_debug("lxt_server_loop: Linux thread request recieved, "
		    "request = %p", request);

		/* Dispatch the request. */
		assert((request->lxt_sa_op > LXT_SERVER_OP_PING) ||
		    (request->lxt_sa_op < LXT_SERVER_OP_MAX));
		lxt_operations[request->lxt_sa_op].lxto_fp(
		    request, request_size, &door_result, &door_result_size);

		lx_debug("lxt_server_loop: Linux thread request completed, "
		    "request = %p", request);

		(void) mutex_lock(&lxt_req_lock);

		/* Set the result pointers for the calling door thread. */
		lxt_req->lxtr_result = door_result;
		lxt_req->lxtr_result_size = door_result_size;

		/* Let the door thread know we're done. */
		lxt_req->lxtr_complete = 1;
		(void) cond_signal(&lxt_req->lxtr_complete_cv);

		(void) mutex_unlock(&lxt_req_lock);
	}
	/*NOTREACHED*/
}
예제 #21
0
static void *
soaker(void *arg)
{
	struct tstate	*state = arg;
	pcparms_t	pcparms;
	fxparms_t	*fx = (fxparms_t *)pcparms.pc_clparms;

	if (processor_bind(P_LWPID, P_MYID, state->cpuid, NULL) != 0)
		(void) fprintf(stderr, gettext("%s: couldn't bind soaker "
		    "thread to cpu%d: %s\n"), opts->pgmname, state->cpuid,
		    strerror(errno));

	/*
	 * Put the soaker thread in the fixed priority (FX) class so it runs
	 * at the lowest possible global priority.
	 */
	pcparms.pc_cid = fxinfo.pc_cid;
	fx->fx_upri = 0;
	fx->fx_uprilim = 0;
	fx->fx_tqsecs = fx->fx_tqnsecs = FX_TQDEF;

	if (priocntl(P_LWPID, P_MYID, PC_SETPARMS, &pcparms) != 0)
		(void) fprintf(stderr, gettext("%s: couldn't put soaker "
		    "thread in FX sched class: %s\n"), opts->pgmname,
		    strerror(errno));

	/*
	 * Let the parent thread know we're ready to roll.
	 */
	(void) mutex_lock(&state->soak_lock);
	state->soak_state = SOAK_RUN;
	(void) cond_signal(&state->soak_cv);
	(void) mutex_unlock(&state->soak_lock);

	for (;;) {
spin:
		(void) mutex_lock(&state->soak_lock);
		if (state->soak_state == SOAK_RUN) {
			(void) mutex_unlock(&state->soak_lock);
			goto spin;
		}

		while (state->soak_state == SOAK_PAUSE)
			(void) cond_wait(&state->soak_cv,
			    &state->soak_lock);
		(void) mutex_unlock(&state->soak_lock);
	}

	/*NOTREACHED*/
	return (NULL);
}
예제 #22
0
static int qemu_paio_submit(struct qemu_paiocb *aiocb, int is_write)
{
    aiocb->is_write = is_write;
    aiocb->ret = -EINPROGRESS;
    aiocb->active = 0;
    mutex_lock(&lock);
    if (idle_threads == 0 && cur_threads < max_threads)
        spawn_thread();
    TAILQ_INSERT_TAIL(&request_list, aiocb, node);
    mutex_unlock(&lock);
    cond_signal(&cond);

    return 0;
}
예제 #23
0
void *cond_signaler(void *cookie)
{
	unsigned long long start;
	struct cond_mutex *cm = cookie;

	start = rt_timer_tsc();
	check("mutex_lock", mutex_lock(cm->mutex), 0);
	check_sleep("mutex_lock", start);
	thread_msleep(10);
	check("cond_signal", cond_signal(cm->cond), 0);
	check("mutex_unlock", mutex_unlock(cm->mutex), 0);

	return NULL;
}
예제 #24
0
파일: cvtest.c 프로젝트: jakefriedman/cs637
void *producer(void *arg) {
    int i;
    for (i = 0; i < loops; i++) {
        mutex_lock(&mutex);            // p1
        while (numfilled == MAX)       // p2
            cond_wait(&empty, &mutex); // p3
        put(i);                        // p4
        printf(1, "put %d\n", i);
        cond_signal(&fill);            // p5
        //printf(1, "ret\n");
        mutex_unlock(&mutex);          // p6
    }
exit();
}
예제 #25
0
파일: control.c 프로젝트: eldesh/smlsharp
static void
sync2_action(struct sml_control *control)
{
	if (control->thread_local_heap)
		sml_heap_mutator_sync2(control, control->thread_local_heap);

	/* all updates performed by this mutator happen before time that
	 * collector checks sync_counter. */
	if (fetch_sub(release, &sync_counter, 1) - 1 == 0) {
		mutex_lock(&sync_wait_lock);
		cond_signal(&sync_wait_cond);
		mutex_unlock(&sync_wait_lock);
	}
}
예제 #26
0
/* ARGSUSED */
void
sm_simu_crash_svc(void *myidp)
{
	int i;
	struct mon_entry *monitor_q;
	int found = 0;

	/* Only one crash should be running at a time. */
	mutex_lock(&crash_lock);
	if (debug)
		(void) printf("proc sm_simu_crash\n");
	if (in_crash) {
		cond_wait(&crash_finish, &crash_lock);
		mutex_unlock(&crash_lock);
		return;
	} else {
		in_crash = 1;
	}
	mutex_unlock(&crash_lock);

	for (i = 0; i < MAX_HASHSIZE; i++) {
		mutex_lock(&mon_table[i].lock);
		monitor_q = mon_table[i].sm_monhdp;
		if (monitor_q != (struct mon_entry *)NULL) {
			mutex_unlock(&mon_table[i].lock);
			found = 1;
			break;
		}
		mutex_unlock(&mon_table[i].lock);
	}
	/*
	 * If there are entries found in the monitor table,
	 * initiate a crash, else zero out the in_crash variable.
	 */
	if (found) {
		mutex_lock(&crash_lock);
		die = 1;
		/* Signal sm_retry() thread if sleeping. */
		cond_signal(&retrywait);
		mutex_unlock(&crash_lock);
		rw_wrlock(&thr_rwlock);
		sm_crash();
		rw_unlock(&thr_rwlock);
	} else {
		mutex_lock(&crash_lock);
		in_crash = 0;
		mutex_unlock(&crash_lock);
	}
}
예제 #27
0
void phi_put_forks_condvar(int i) {
     down(&(mtp->mutex));

//--------into routine in monitor--------------
     // LAB7 EXERCISE1: YOUR CODE
     // I ate over
     // test left and right neighbors
//--------leave routine in monitor--------------
	state_condvar[i] = THINKING;
	if ((state_condvar[(i+4)%5] == HUNGRY) && (state_condvar[(i+3)%5] != EATING)) {
		state_condvar[(i+4)%5] = EATING;
		cond_signal(&mtp->cv[(i+4)%5]);
	}

	if ((state_condvar[(i+1)%5] == HUNGRY) && (state_condvar[(i+2)%5] != EATING)) {
		state_condvar[(i+1)%5] = EATING;
		cond_signal(&mtp->cv[(i+1)%5]);
	}

	 if(mtp->next_count>0)
        up(&(mtp->next));
     else
        up(&(mtp->mutex));
}
예제 #28
0
/** @brief Notifies an update event should occur
 *
 *  This function sets the update pending flag, then signals an update
 *
 **/
void scheduleUpdate(void)
{
	/** lock the update flag **/
	mutex_lock(&updateLock);

	/** set the pending update flag **/
	updatePending=1;

	/** signal update if it was waiting **/
	cond_signal(&updates);
	
	/** unlock update flag **/
	mutex_unlock(&updateLock);

}
예제 #29
0
/*
 *Abre un /proc en el modo especificado por el parametro de entrada
 *bool abre_para_lectura ==> 1 abre en modo lectura, 0 abre en modo escritura
 */
void fifoproc_open(bool abre_para_lectura) {
	lock(mtx);
		/*Si es para lectura, aumentamos el numero de consumidores,
		 *mandamos un signal a los productores para despertarlos 
		 *en el caso de que estuvieran bloqueados por falta de consumidores
		 *y en el caso de que no haya productores bloqueamos el proceso
		 */
		if(abre_para_lectura) {
			cons_count++;
			cond_signal(prod);
			while(prod_count==0)
				cond_wait(cons,mtx);
		}
		/*Realizamos el mismo algoritmo previamente explicado intercambiando
		 *los productores por los consumidores en el modo de operacion
		 */
		else {
			prod_count++;
			cond_signal(cons);
			while(cons_count==0)
				cond_wait(prod,mtx);
		}
	unlock(mtx);
}
예제 #30
0
/*
 * This function should be called while holding the sphere mutex
 */
void demux_chunk_end(demux_t *dm, struct mutex *mutex, chunk_t *chunk) {
        demux_ent_t *ent;
        int ret;
        demux_chunk_t *dchunk = (demux_chunk_t *) chunk;

        ent = dm->entries + chunk->processor_id;

        // clear the chunk we just processed so that the next chunk can run on
        // this processor
        ret = kfifo_out(&ent->fifo, dchunk, sizeof(demux_chunk_t));
        BUG_ON(ret != sizeof(demux_chunk_t));
        inc_current_ticket(dm, dchunk->chunk.thread_id);

        cond_broadcast(&dm->next_chunk_cond);
        cond_signal(&ent->fifo_full_cond);
}