Welcome, Guest. Please login or register.

Author Topic: Using timer.device in C (VBCC)  (Read 4246 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show all replies
    • http://www.iki.fi/sintonen/
Re: Using timer.device in C (VBCC)
« on: June 28, 2011, 06:13:40 PM »
First, try linking with libauto (-lauto). If that doesn't help you'll need to set up TimerBase by yourself, see into CreateMsgPort, CreateIORequest and OpenDevice. Once the timer.device unit is opened you can find the TimerBase from the iorequest's io_Device field [TimerBase =  ioreq->io_Device;]

At clean up perform CloseDevice, DeleteIORequest and DeleteMsgPort.

PS. It's also possible to take a shortcut with timer.device and set up a fake iorequest for OpenDevice. While strictly speaking legal it's a bit confusing for a beginner and might give you some bad ideas on how to use exec devices.
« Last Edit: June 28, 2011, 06:25:24 PM by Piru »
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show all replies
    • http://www.iki.fi/sintonen/
Re: Using timer.device in C (VBCC)
« Reply #1 on: June 28, 2011, 07:03:50 PM »
Quote from: DBAlex;647489
Hi Piru,

Some code would be helpful!

Sorry, I'm too tired today. Someone else can easily cook it up.

Quote
EDIT: Tried linking with -lauto, the program still crashes. :-(

Try changing "struct Library *TimerBase;" to "extern struct Library *TimerBase;". That with -lauto might do the trick.

Your code doesn't check if malloc or realloc fail. They can fail and your code should back out nicely if they do. However, that's not the cause of the problem here, I think.
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show all replies
    • http://www.iki.fi/sintonen/
Re: Using timer.device in C (VBCC)
« Reply #2 on: June 28, 2011, 08:14:21 PM »
Quote from: DBAlex;647505
Ok, no problem. Thanks for the help so far. :)



That gives me errors about TimerBase. The same errors I had when I didn't have TimerBase defined.
So VBCC does have a sucky libauto after all. Go figure.

Well this should work regardless:

Code: [Select]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#include <devices/timer.h>
#include <proto/exec.h>
#include <proto/timer.h>

struct MsgPort *timer_msgport;
struct timerequest *timer_ioreq;
struct Library *TimerBase;

static int opentimer(ULONG unit){
timer_msgport = CreateMsgPort();
timer_ioreq = CreateIORequest(timer_msgport, sizeof(*timer_ioreq));
if (timer_ioreq){
if (OpenDevice(TIMERNAME, unit, (APTR) timer_ioreq, 0) == 0){
TimerBase = (APTR) timer_ioreq->tr_node.io_Device;
return 1;
}
}
return 0;
}
static void closetimer(void){
if (TimerBase){
CloseDevice((APTR) timer_ioreq);
}
DeleteIORequest(timer_ioreq);
DeleteMsgPort(timer_msgport);
TimerBase = 0;
timer_ioreq = 0;
timer_msgport = 0;
}

static struct timeval startTime;

void startup(){
GetSysTime(&startTime);
}

ULONG getMilliseconds(){
struct timeval endTime;

GetSysTime(&endTime);
SubTime(&endTime,&startTime);

return (endTime.tv_secs * 1000 + endTime.tv_micro / 1000);
}

char* realloc_strcat(char *s1, char * s2){
int len = (strlen(s1) + strlen(s2));
s1 = (char *) realloc(s1, len + 1);
if (s1 == 0){
perror(&quot;realloc&quot;);
exit(10);
}
strncat(s1,s2,len);
return s1;
}

int main(int argc, char * argv[]){
int i;
char* str;

if (atexit(closetimer) == -1){
exit(10);
}
if (opentimer(UNIT_VBLANK) == 0){
exit(10);
}

// Start timer
startup();

// Initialise string
str = (char *) malloc(7);
if (str == 0){
perror(&quot;malloc&quot;);
exit(10);
}
strcpy(str,&quot;Hello &quot;);

// Call timer (1)
printf(&quot;Time 1: %lu\n&quot;,getMilliseconds());

// Computation
for(i=0; i<100; i++){
str = realloc_strcat(str,&quot;Appending string...!)&quot;);
}

// Call timer (2)
printf(&quot;Time 2: %lu\n&quot;,getMilliseconds());

return 0;
}

Some notes:
  • I fixed the potential crashes due to malloc/realloc failing.
  • I made the code compile without C99 extensions.
  • Mixing clib and amigaos calls is quite akward. You should stick with one of them. If you mix you need to do all sort of extra trickery (such as that atexit() to ensure that amigaos resources are freed).
« Last Edit: June 28, 2011, 08:25:03 PM by Piru »
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show all replies
    • http://www.iki.fi/sintonen/
Re: Using timer.device in C (VBCC)
« Reply #3 on: June 29, 2011, 05:32:36 PM »
Quote from: DBAlex;647625
@Piru
However I think C99 was still needed for the // comments.

Actually most compilers supported // comments even before C99.

Quote
I noticed AmigaOS has functions to allocate memory (E.g. AllocMem, AllocVec).

Does malloc just map to these functions?

malloc doesn't just map to those functions. Typical malloc implementations call AllocMem internally to grab large chunks of memory which they then serve to malloc callers (simplified explanation).

Also note that malloc()ed memory is released automagically at application exit. AllocMem/AllocVec memory is not.

Quote
Or should I use the AmigaOS versions?

It depends on what you do. If you use standard C libraries (stdio, stdlib etc) then you should use malloc. If you use amigaos functions you should preferably only use amigaos functions.

As said before mixing them is a bad idea.
« Last Edit: June 29, 2011, 06:01:43 PM by Piru »