glutTimerFunc cleanup

This commit is contained in:
Daniel Borca
2004-01-26 10:41:39 +00:00
parent d3682ce376
commit 8d2cfa9ea0
4 changed files with 162 additions and 151 deletions
+5 -3
View File
@@ -20,7 +20,7 @@
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# DOS/DJGPP glut makefile v1.4 for Mesa
# DOS/DJGPP glut makefile v1.5 for Mesa
#
# Copyright (C) 2002 - Borca Daniel
# Email : dborca@users.sourceforge.net
@@ -34,7 +34,9 @@
# CFLAGS
#
# MKGLUT absolute path to original GLUT.
# default = $(TOP)/src-glut
# default = $(TOP)/src/glut/glx
# GLIDE path to Glide3 SDK; used to resolve DXEs.
# default = $(TOP)/glide3
#
# Targets:
# all: build GLUT
@@ -46,7 +48,7 @@
.PHONY: all clean
TOP = ../../..
GLIDE ?= $(TOP)/include/glide3
GLIDE ?= $(TOP)/glide3
MKGLUT ?= $(TOP)/src/glut/glx
LIBDIR = $(TOP)/lib
GLUT_LIB = libglut.a
+136 -132
View File
@@ -1,5 +1,5 @@
/*
* PC/HW routine collection v1.4 for DOS/DJGPP
* PC/HW routine collection v1.5 for DOS/DJGPP
*
* Copyright (C) 2002 - Borca Daniel
* Email : dborca@yahoo.com
@@ -93,6 +93,137 @@ void pc_remove_timer (void)
/* Desc: remove timerfunc
*
* In : timerfunc id
* Out : 0 if success
*
* Note: tries to relax the main timer whenever possible
*/
int pc_remove_int (int fid)
{
int i;
unsigned int freq = 0;
/* are we installed? */
if (!timer_installed) {
return -1;
}
/* sanity check */
if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {
return -1;
}
timer_func[fid].func = NULL;
/* scan for maximum frequency */
for (i = 0; i < MAX_TIMERS; i++) {
TIMER *t = &timer_func[i];
if (t->func) {
if (freq < t->freq) {
freq = t->freq;
}
}
}
/* if there are no callbacks left, cleanup */
if (!freq) {
pc_remove_timer();
return 0;
}
/* if we just lowered the maximum frequency, try to relax the timer engine */
if (freq < timer_main.freq) {
unsigned int new_counter = PIT_FREQ / freq;
DISABLE();
for (i = 0; i < MAX_TIMERS; i++) {
if (timer_func[i].func) {
ADJUST(timer_func[i], freq);
}
}
outportb(0x43, 0x34);
outportb(0x40, (unsigned char)new_counter);
outportb(0x40, (unsigned char)(new_counter>>8));
timer_main.clock_ticks = 0;
timer_main.counter = new_counter;
timer_main.freq = freq;
ENABLE();
}
return 0;
} ENDOFUNC(pc_remove_int)
/* Desc: adjust timerfunc
*
* In : timerfunc id, new frequency (Hz)
* Out : 0 if success
*
* Note: might change the main timer frequency
*/
int pc_adjust_int (int fid, unsigned int freq)
{
int i;
/* are we installed? */
if (!timer_installed) {
return -1;
}
/* sanity check */
if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {
return -1;
}
timer_func[fid].freq = freq;
/* scan for maximum frequency */
freq = 0;
for (i = 0; i < MAX_TIMERS; i++) {
TIMER *t = &timer_func[i];
if (t->func) {
if (freq < t->freq) {
freq = t->freq;
}
}
}
/* update main timer / sons to match highest frequency */
DISABLE();
/* using '>' is correct still (and avoids updating
* the HW timer too often), but doesn't relax the timer!
*/
if (freq != timer_main.freq) {
unsigned int new_counter = PIT_FREQ / freq;
for (i = 0; i < MAX_TIMERS; i++) {
if (timer_func[i].func) {
ADJUST(timer_func[i], freq);
}
}
outportb(0x43, 0x34);
outportb(0x40, (unsigned char)new_counter);
outportb(0x40, (unsigned char)(new_counter>>8));
timer_main.clock_ticks = 0;
timer_main.counter = new_counter;
timer_main.freq = freq;
} else {
ADJUST(timer_func[fid], timer_main.freq);
}
ENABLE();
return 0;
} ENDOFUNC(pc_adjust_int)
/* Desc: install timer engine
*
* In : -
@@ -110,6 +241,8 @@ static int install_timer (void)
LOCKDATA(timer_func);
LOCKDATA(timer_main);
LOCKFUNC(timer);
LOCKFUNC(pc_adjust_int);
LOCKFUNC(pc_remove_int);
timer_main.counter = 0x10000;
@@ -186,138 +319,9 @@ int pc_install_int (PFUNC func, void *parm, unsigned int freq)
ADJUST(timer_func[i], timer_main.freq);
}
ENABLE();
return t - timer_func;
}
/* Desc: remove timerfunc
*
* In : timerfunc id
* Out : 0 if success
*
* Note: tries to relax the main timer whenever possible
*/
int pc_remove_int (int fid)
{
int i;
unsigned int freq = 0;
/* are we installed? */
if (!timer_installed) {
return -1;
}
/* sanity check */
if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {
return -1;
}
timer_func[fid].func = NULL;
/* scan for maximum frequency */
for (i = 0; i < MAX_TIMERS; i++) {
TIMER *t = &timer_func[i];
if (t->func) {
if (freq < t->freq) {
freq = t->freq;
}
}
}
/* if there are no callbacks left, cleanup */
if (!freq) {
pc_remove_timer();
return 0;
}
/* if we just lowered the maximum frequency, try to relax the timer engine */
if (freq < timer_main.freq) {
unsigned int new_counter = PIT_FREQ / freq;
DISABLE();
for (i = 0; i < MAX_TIMERS; i++) {
if (timer_func[i].func) {
ADJUST(timer_func[i], freq);
}
}
outportb(0x43, 0x34);
outportb(0x40, (unsigned char)new_counter);
outportb(0x40, (unsigned char)(new_counter>>8));
timer_main.clock_ticks = 0;
timer_main.counter = new_counter;
timer_main.freq = freq;
ENABLE();
}
return 0;
}
/* Desc: adjust timerfunc
*
* In : timerfunc id, new frequency (Hz)
* Out : 0 if success
*
* Note: might change the main timer frequency
*/
int pc_adjust_int (int fid, unsigned int freq)
{
int i;
/* are we installed? */
if (!timer_installed) {
return -1;
}
/* sanity check */
if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {
return -1;
}
timer_func[fid].freq = freq;
/* scan for maximum frequency */
freq = 0;
for (i = 0; i < MAX_TIMERS; i++) {
TIMER *t = &timer_func[i];
if (t->func) {
if (freq < t->freq) {
freq = t->freq;
}
}
}
/* update main timer / sons to match highest frequency */
DISABLE();
/* using '>' is correct still (and avoids updating
* the HW timer too often), but doesn't relax the timer!
*/
if (freq != timer_main.freq) {
unsigned int new_counter = PIT_FREQ / freq;
for (i = 0; i < MAX_TIMERS; i++) {
if (timer_func[i].func) {
ADJUST(timer_func[i], freq);
}
}
outportb(0x43, 0x34);
outportb(0x40, (unsigned char)new_counter);
outportb(0x40, (unsigned char)(new_counter>>8));
timer_main.clock_ticks = 0;
timer_main.counter = new_counter;
timer_main.freq = freq;
} else {
ADJUST(timer_func[fid], timer_main.freq);
}
i = t - timer_func;
ENABLE();
return 0;
return i;
}
+19 -14
View File
@@ -19,7 +19,7 @@
*/
/*
* DOS/DJGPP glut driver v1.4 for Mesa
* DOS/DJGPP glut driver v1.5 for Mesa
*
* Copyright (C) 2002 - Borca Daniel
* Email : dborca@yahoo.com
@@ -38,8 +38,6 @@ typedef struct {
int fid; /* func-id as returned from PCHW */
} GLUTSShotCB;
static GLboolean g_sscb_semaphore;
GLUTidleCB g_idle_func = NULL;
@@ -47,11 +45,12 @@ GLUTidleCB g_idle_func = NULL;
static void g_single_shot_callback (void *opaque)
{
GLUTSShotCB *cb = (GLUTSShotCB *)opaque;
while (g_sscb_semaphore) {
}
if (!--cb->ttl) {
cb->func(cb->value);
pc_remove_int(cb->fid);
/* We won't be needing this slot anymore, so free it. This operation
* must be the last thing, and must be atomic, to mutex `glutTimerFunc'
*/
cb->func = NULL;
}
} ENDOFUNC(g_single_shot_callback)
@@ -139,7 +138,6 @@ void APIENTRY glutTimerFunc (unsigned int millis, GLUTtimerCB func, int value)
if (virgin) {
virgin = GL_FALSE;
LOCKDATA(g_sscb);
LOCKDATA(g_sscb_semaphore);
LOCKFUNC(g_single_shot_callback);
/* we should lock the callee also... */
}
@@ -153,20 +151,27 @@ void APIENTRY glutTimerFunc (unsigned int millis, GLUTtimerCB func, int value)
freq = 1000 / millis;
ttl = 1;
}
g_sscb_semaphore++;
for (i = 0; i < MAX_SSHOT_CB; i++) {
if (g_sscb[i].func == NULL) {
int fid = pc_install_int((PFUNC)func, &g_sscb[i], freq);
if (fid >= 0) {
g_sscb[i].func = func;
g_sscb[i].value = value;
g_sscb[i].ttl = ttl;
g_sscb[i].fid = fid;
/* We will be needing this slot, so alloc it. This operation
* must be the first thing, and must be atomic, to mutex callbacks!
*/
g_sscb[i].func = func;
g_sscb[i].value = value;
g_sscb[i].ttl = ttl;
/* There is a very small gap here: `pc_install_int' enables
* interrupts just before returning FID value (which will be
* used inside callback). The critical gap is 1 millisecond
* - which I'm sure we won't overrun...
*/
g_sscb[i].fid = pc_install_int((PFUNC)func, &g_sscb[i], freq);
if (g_sscb[i].fid < 0) {
/* Interrupt could not be set! Release the slot back */
g_sscb[i].func = NULL;
}
break;
}
}
g_sscb_semaphore--;
}
}
+2 -2
View File
@@ -19,7 +19,7 @@
*/
/*
* DOS/DJGPP glut driver v1.5 for Mesa
* DOS/DJGPP glut driver v1.6 for Mesa
*
* Copyright (C) 2002 - Borca Daniel
* Email : dborca@users.sourceforge.net
@@ -146,7 +146,7 @@ extern void *__glutFont(void *font);
#define MAX_WINDOWS 2
#define MAX_SSHOT_CB 10
#define MAX_SSHOT_CB 8
#define RESERVED_COLORS 0