Difference between revisions of "Exec"

From Amiga Development Wiki
Jump to: navigation, search
(Created page with "= Standard types = == Integral types == {| class="wikitable" ! Type ! Description |- | UBYTE | 8-bit unsigned |- | BYTE | 8-bit signed |- | UWORD | 16-bit unsigned |- | WORD |...")
 
m (Moved data storage types to other article)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Standard types =
 
== Integral types ==
 
{| class="wikitable"
 
! Type
 
! Description
 
|-
 
| UBYTE
 
| 8-bit unsigned
 
|-
 
| BYTE
 
| 8-bit signed
 
|-
 
| UWORD
 
| 16-bit unsigned
 
|-
 
| WORD
 
| 16-bit signed
 
|-
 
| ULONG
 
| 32-bit unsigned
 
|-
 
| LONG
 
| 32-bit signed
 
|-
 
| UQUAD
 
| 64-bit unsigned
 
|-
 
| QUAD
 
| 64-bit signed
 
|}
 
 
== Floating-point types ==
 
{| class="wikitable"
 
! Type
 
! Description
 
|-
 
| FLOAT
 
| 32-bit floating point
 
|-
 
| DOUBLE
 
| 64-bit floating point
 
|}
 
 
== Text types ==
 
{| class="wikitable"
 
! Type
 
! Description
 
|-
 
| TEXT
 
| Text (8-bit)
 
|-
 
| WCHAR
 
| Unicode text (32-bit)
 
|-
 
| STRPTR
 
| Pointer to string
 
|-
 
| CONST_STRPTR
 
| Pointer to constant string
 
|-
 
| WSTRPTR
 
| Pointer to Unicode string
 
|-
 
| CONST_WSTRPTR
 
| Pointer to constant Unicode string
 
|}
 
 
== Other types ==
 
{| class="wikitable"
 
! Type
 
! Description
 
|-
 
| BOOL
 
| Boolean (16-bit)
 
|-
 
| IPTR
 
| Mixed integer/pointer type
 
|-
 
| APTR
 
| Untyped pointer
 
|-
 
| CONST_APTR
 
| Constant untyped pointer
 
|}
 
 
 
= Memory allocation =
 
= Memory allocation =
 
== Memory types ==
 
== Memory types ==
Line 98: Line 13:
 
|-
 
|-
 
| MEMF_FAST
 
| MEMF_FAST
| Allocate only the fastest memory available to the CPU. This memory can not be accessed by Amiga custom chips and allocation fails on Amigas without the fast memory.
+
| 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.
 
|}
 
|}
  
Line 124: Line 39:
 
| MEMF_REVERSE
 
| MEMF_REVERSE
 
| The memory is allocated from the end of memory list. Only applicable to operating systems using memory list based memory allocator.
 
| 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.
 
|}
 
|}
  
Line 254: Line 172:
 
= Semaphores =
 
= Semaphores =
  
Semaphores are used to protect critical sections.
+
Semaphores are used to protect critical sections. Despite its name they are actually ''monitors'' by definition.
  
 
== Creating semaphore ==
 
== 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.
 +
 
<source lang="c">
 
<source lang="c">
 
struct SignalSemaphore *CreateSemaphore()
 
struct SignalSemaphore *CreateSemaphore()

Latest revision as of 17:18, 13 January 2016

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;
}