summaryrefslogtreecommitdiff
path: root/minix/lib/libddekit/src/condvar.c
blob: ffea3571785f884f3b8220726a98671c0e9e0c3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "common.h"

#include <ddekit/condvar.h> 
#include <ddekit/lock.h> 
#include <ddekit/memory.h> 

#ifdef DDEBUG_LEVEL_CONDVAR
#undef DDEBUG
#define DDEBUG DDEBUG_LEVEL_CONDVAR
#endif

#include "debug.h"
#include "util.h"
#include "thread.h"

struct ddekit_condvar {
	ddekit_thread_t * wait_queue;
};

/*****************************************************************************/
/*      ddekit_condvar_init                                                  */
/*****************************************************************************/
ddekit_condvar_t * ddekit_condvar_init(void) { 
	ddekit_condvar_t *cv;
	cv = (ddekit_condvar_t *) ddekit_simple_malloc(sizeof(ddekit_condvar_t));
	DDEBUG_MSG_VERBOSE("cv: %p", cv);
	return cv;
}

/*****************************************************************************/
/*      ddekit_condvar_deinit                                                */
/*****************************************************************************/
void ddekit_condvar_deinit(ddekit_condvar_t *cvp) {
	DDEBUG_MSG_VERBOSE("cv: %p", cvp);
	ddekit_simple_free(cvp); 
}

/*****************************************************************************/
/*      ddekit_condvar_wait                                                  */
/*****************************************************************************/
void ddekit_condvar_wait(ddekit_condvar_t *cv, ddekit_lock_t *mp) {
	
	DDEBUG_MSG_VERBOSE("wait cv: %p, thread id: %d, name: %s",
		cv, ddekit_thread_myself()->id,  ddekit_thread_myself()->name);

	ddekit_lock_unlock(mp);
	
	if(cv->wait_queue == NULL) {
			cv->wait_queue = ddekit_thread_myself();
	} else {
		ddekit_thread_t *pos = cv->wait_queue;
		while(pos->next != NULL) {
			pos = pos->next;
		}
		pos->next = ddekit_thread_myself();
	}

	_ddekit_thread_schedule();

	DDEBUG_MSG_VERBOSE("wakeup cv: %p, thread id: %d, name: %s",
		cv, ddekit_thread_myself()->id,  ddekit_thread_myself()->name);

	ddekit_lock_lock(mp);
}
/*****************************************************************************/
/*      ddekit_condvar_wait_timed                                            */
/*****************************************************************************/
int ddekit_condvar_wait_timed
(ddekit_condvar_t *cvp, ddekit_lock_t *mp, int timo)
{
	/* 
	 * Only used by ddefbsd, so not implemented
	 */
	WARN_UNIMPL;
	return 0;
}


/*****************************************************************************/
/*      ddekit_condvar_signal                                                */
/*****************************************************************************/
void ddekit_condvar_signal(ddekit_condvar_t *cv) 
{
	
	DDEBUG_MSG_VERBOSE("cv: %p", cv);
	
	if(cv->wait_queue) {
		ddekit_thread_t *th = cv->wait_queue;
		cv->wait_queue = th->next;
		th->next = NULL;
		_ddekit_thread_enqueue(th);

		DDEBUG_MSG_VERBOSE("waking up cv: %p, thread id: %d, name: %s",
			cv, th->id, th->name);
	}
	ddekit_thread_schedule();
}


/*****************************************************************************/
/*      ddekit_condvar_broadcast                                             */
/*****************************************************************************/
void ddekit_condvar_broadcast(ddekit_condvar_t *cv) { 
	
	DDEBUG_MSG_VERBOSE("cv: %p", cv);
	
	while (cv->wait_queue) {
		ddekit_thread_t *th = cv->wait_queue;
		cv->wait_queue = th->next;
		th->next = NULL;
		_ddekit_thread_enqueue(th);
		
		DDEBUG_MSG_VERBOSE("waking up cv: %p, thread id: %d, name: %s",
			cv, th->id, th->name);

	}
	ddekit_thread_schedule();
}