!  File  MOUSE:MANAGER

! Mouse MANAGER process
! Creates the global pools of message buffers and kernel objects.
! Keeps a register of named kernel objects.

%option "-low-nons-nocheck-nodiag"
%include "mouse.inc"

%begin

%constinteger object pool size = 200, message pool size = 100

%recordformat regfm(%record(regfm)%name next,%integer ref,%string(63)s)
%ownrecord(regfm)%name reg==nil

%integer -
  osz = sizeof(object pool) * object pool size,
  msz = 2048 * (message pool size + 1),
  pos,i
%bytearray b(1:osz+msz)

%routine handle message(%record(message fm)%name m)
%record(mailbox fm)%name reply
%record(manager request fm)%name r
%record(regfm)%name cell
  r == record(addr(m_data))
  %if r_code=0 %or r_code=1 %start
    cell == reg
    %while cell##nil %cycle    {Lookup first
      %if cell_s=r_s %start    {found
        %if r_code=0 %start    {defining
          cell_ref = r_ref
        %else
          r_ref = cell_ref
        %finish
        %exit
      %finish
      cell == cell_next
    %repeat
    %if cell==nil %start       {not found
      %if r_code=0 %start      {if defining
        cell == new(cell)      {add new one
        cell_s = r_s; cell_ref = r_ref; cell_next == reg; reg == cell
      %else                    {just looking
        r_ref = 0              {indicate not found
      %finish
    %finish
    m_size = 8
  %else
    m_size = 0
  %finish
  reply == m_reply; m_reply == nil
  send message(m,reply)
%end

%record(*)%map new semaphore(%integer c)
%record(semaphore fm)%name s
  s == record(pos); pos = pos+sizeof(s)
  s = 0; s_tag = 'SE'; s_counter = c
  s_fwd == s; s_bck == s
  %result == s
%end

%record(message fm)%map new message
%record(message fm)%name m
  m == record(pos); pos = pos+2048
  m_tag = 'ME'; m_sender == nil; m_reply == nil; m_size = 0
  %result == m
%end

  becomeprocess(sizeof(reg)*objectpoolsize + 2000)
  pos = addr(b(1))

  object pool semaphore == new semaphore(object pool size)
  message pool semaphore == new semaphore(message pool size)
  object pool == new semaphore(0); object pool_tag = 'OP'
  message pool == new semaphore(0); message pool_tag = 'MP'
  enqueue(new semaphore(0),object pool) %for i = 1,1,object pool size-4
  pos = (pos+2047)&-2048
  enqueue(new message,message pool) %for i = 1,1,message pool size
  manager mailbox == createmailbox(createsemaphore(0))

  %cycle
    handle message(receive message(manager mailbox))
  %repeat

%end
