Exec

From Amiga Development Wiki
Jump to: navigation, search

Memory allocation

Memory types

Flags Description
MEMF_ANY The best available memory is allocated.
MEMF_CHIP Allocate memory accessible by Amiga custom chips. This memory is always slow to the CPU.
MEMF_FAST Allocate only the fastest memory available to the CPU. This memory cannot be accessed by Amiga custom chips and allocation fails on Amigas without the fast memory.

Memory attributes

Attribute Description
MEMF_24BITDMA Allocate memory used for Zorro-II DMA. Only applicable to real Amiga.
MEMF_CLEAR Allocated memory is cleared to zeros.
MEMF_LOCAL The memory is allocated in a manner it can survive reset. Only applicable to real Amiga.
MEMF_NO_EXPUNGE Prevents flushing unused memory.
MEMF_PUBLIC Deprecated This memory flag is not used by any Amiga operating systems.
MEMF_REVERSE The memory is allocated from the end of memory list. Only applicable to operating systems using memory list based memory allocator.
MEMF_SEM_PROTECTED Enable thread safe allocation. This can be used with CreatePool() only where pools are not thread safe by default.

Allocating memory

struct MsgPort *port = AllocMem(sizeof(*port), MEMF_ANY);

Freeing memory

if (port)
   FreeMem(port, sizeof(*port));

Messages and ports

Create message port

There are two ways to create message port: create it manually or use CreateMsgPort() call.

 struct MsgPort *port = CreateMsgPort();
If you want to create it manually you can use following code:
struct MsgPort *CreatePort()
{
   struct MsgPort *port = AllocMem(sizeof(*port), MEMF_ANY);
 
   if (port)
   {
      NEWLIST(&port->mp_MsgList);
 
      port->mp_Flags = PA_SIGNAL;
      port->mp_SigBit = AllocSignal(-1);
      port->mp_SigTask = SysBase->ThisTask;
 
      if (port->mp_SigBit == (UBYTE)-1)
      {
         FreeMem(port, sizeof(*port));
         return NULL;
      }
   }
 
   return port;
}

Delete message port

If you created message port using CreageMsgPort():

 DeleteMsgPort(port);

If it was created manually:

void DeletePort(struct MsgPort *port)
{
   if (port)
   {
      FreeSignal(port->mp_SigBit);
      FreeMem(port, sizeof(*port));
   }
}

Sending a message

void SendMessage(struct MsgPort *source, struct MsgPort *destination)
{
   struct Message *msg = AllocMem(sizeof(*msg), MEMF_ANY);
 
   if (msg)
   {
      msg->mn_ReplyPort = source;
      PutMsg(destination, &msg);
      WaitPort(source);
      GetMsg(source);
      FreeMem(msg, sizeof(*msg));
   }
}

Example

#include <exec/execbase.h>
#include <exec/ports.h>
#include <proto/exec.h>
 
static struct Message *WaitMessage(struct MsgPort *port)
{
   WaitPort(port);
   return GetMsg(port);
}
 
int main()
{
   struct MsgPort *port1, *port2;
 
   port1 = CreateMsgPort();
   port2 = CreateMsgPort();
 
   if (port1 && port2)
   {
      // Send a message to port 2...
      struct Message msg, *m;
      msg.mn_ReplyPort = port1;
      PutMsg(port2, &msg);
 
      // Wait for a message at port 2...
      m = WaitMessage(port2);
 
      // Reply message back to sender
      ReplyMsg(m);
 
      // Wait for a reply at port 1
      WaitMessage(port1);
   }
 
   DeleteMsgPort(port1);
   DeleteMsgPort(port2);
 
   return 0;
}

Semaphores

Semaphores are used to protect critical sections. Despite its name they are actually monitors by definition.

Creating semaphore

To create a semaphore allocate a SignalSemaphore structure and initialize it using InitSemaphore() function. Please note that the structure must be initialized to zero before the call to InitSemaphore(). Use calloc() or Exec allocator with MEMF_CLEAR option.

struct SignalSemaphore *CreateSemaphore()
{
   struct SignalSemaphore *sem = AllocMem(sizeof(*sem), MEMF_ANY | MEMF_CLEAR);
 
   if (sem)
   {
      InitSemaphore(sem);
   }
 
   return sem;
}

Delete semaphore

void DeleteSemaphore(struct SignalSemaphore *sem)
{
   if (sem)
      FreeMem(sem, sizeof(*sem));
}

Function reference

AttemptSemaphore

Attempt to get an exclusive access to the semaphore.

AttemptSemaphore(semaphore);

ObtainSemaphore

Obtain an exclusive access to the semaphore. This call blocks if semaphore is not available.

ObtainSemaphore(semaphore);

ObtainSemaphoreShared

Obtain a shared access to the semaphore. This call blocks if semaphore is not available.

ObtainSemaphoreShared(semaphore);

ReleaseSemaphore

Release shared or exclusive access to the semaphore.

ReleaseSemaphore(semaphore);

Example

#include <exec/semaphores.h>
#include <proto/exec.h>
 
int main()
{
   struct SignalSemaphore *sem = AllocMem(sizeof(*sem), MEMF_ANY | MEMF_CLEAR);
 
   if (sem != NULL)
   {
      InitSemaphore(sem);
      ObtainSemaphore(sem);
 
      // Protected area...
 
      ReleaseSemaphore(sem);
      FreeMem(sem, sizeof(*sem));
   }
 
   return 0;
}