/*  -
   Copyright (C) 2006 Weongyo Jeong (weongyo@gmail.com)

This file is part of ROVM.

ROVM is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.

ROVM is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

#ifndef _ROVM_TICKET_H
#define _ROVM_TICKET_H

#include "core.h"
#include "class.h"

/**
   기본적으로 생성할 스택 slot 의 갯수.
 */
#define DEFAULT_STACK_SLOT              256

enum ticket_status
  {
    /* 현재 Ticket 이 휴식중임을 가르킵니다.  */
    TICKET_IS_RELAX,
    /* 현재 Ticket 이 열심히 일하고 있다는 뜻입니다.  */
    TICKET_IS_WORKING,
    /* 현재 Ticket 이 GC Slot 에 들어가 있기 때문에, 더 이상 이 티켓은 유효하지
       않다는 뜻입니다.  */
    TICKET_IS_ON_GCSLOT
  };

#define TICKET_STATUS(NODE)             ((NODE)->status)
#define TICKET_TIME_INIT(NODE)		((NODE)->tinit)
#define TICKET_TIME_UPDATE(NODE)        ((NODE)->tupdate)
#define TICKET_SP(NODE)                 ((NODE)->sp)
#define TICKET_MAX_SP(NODE)             ((NODE)->maxsp)
#define TICKET_MIN_SP(NODE)             ((NODE)->minsp)
#define TICKET_LOCAL(NODE)              ((NODE)->local)
#define TICKET_MAXLOCAL(NODE)           ((NODE)->maxlocal)
#define TICKET_RET(NODE)                (&((NODE)->ret))
#define TICKET_DELAYED_SLOT(NODE)       ((NODE)->delayed_slot)
#define TICKET_DELAYED_SLOT_IDX(NODE, IDX)  ((NODE)->delayed_slot[(IDX)])
#define TICKET_DELAYED_SLOT_MAX(NODE)   ((NODE)->delayed_slot_max)
#define TICKET_DELAYED_SLOT_NELM(NODE)  ((NODE)->delayed_slot_nelm)
#define DEFAULT_DELAYED_SLOT            64
#define TICKET_STACK(NODE)              ((NODE)->stack)
#define TICKET_STACK_IDX(NODE, IDX)     ((NODE)->stack[(IDX)])
#define TICKET_MAX_STACK_SLOT(NODE)     ((NODE)->max_stack_slot)

/**
   사용자로 부터 `REQ' 명령어가 전달되고, 그에 대한 합당한 인증 절차를 거쳐
   유효한 사용자로 판명이 되었을 때, 생성되는 구조체로써, 사용자가 보낸 여러 정보들의
   상태등을 담고 있으며, 이를 이용하여 다음 요청이 왔을 때에도 계속 사용할 수
   있도록 한다.

   이 구조체는 대단히 중요한 구조체로써 각 request 에 대한 현재 모든 상태들을
   가지고 있다.

   (운영체제에서의 프로세스랑 동급으로 생각하시면 됩니다.)
 */
struct ticket
{
  /**
     현재 Ticket 의 상태에 대한 정보를 나타내는 변수입니다.  이 변수는 Ticket
     구조체에 대한 GC 가 이루어질 때 사용되는 정보로써 만약 ticket 이 사용 중일
     때는 해당 Ticket 구조체에 대한 GC 가 이루어지지 않도록 되어 있습니다.  
  */
  enum ticket_status status;

  /**
     Ticket 이 생성된 시각과 가장 최근 사용된 시간을 가지고 있습니다.  이것은
     나중에 일정 시간이 경과한 ticket 의 경우, 자동 소멸을 위해서 사용됩니다.
  */
  rc_time_t tinit;
  rc_time_t tupdate;

  /** Stack Pointer.  x86 에서 stack pointer 개념이랑 같습니다.  */
  rovm_stack_t *sp;
  /** Stack Pointer 가 최대/최소로 증가하였을 경우의 포인터이다.  이것은 Stack 경계점을
      넘어가는 것을 검사하기 위한 루틴이다.  */
  rovm_stack_t *maxsp;
  rovm_stack_t *minsp;

  /** Local Variable Pointer.  이것은 자바 가상 머신에서의 개념과 거의 같으며
      아래 변수 `stack' 배열중 하나의 slot 을 가르키게 된다.  이에 대한 자세한
      개념은 `Stack 과 Local 변수의 이해' 글을 참고하기 바란다.

      @note 현재 `Stack 과 Local 변수의 이해' 글은 존재하지 않는다.  */
  rovm_stack_t *local;
  /** Local 변수의 최대 slot 에 대한 포인터 정보를 가지고 있으며, iload 와 같은
      opcode 가 잘못된 local 변수 범위 외의 영역에 침범하는지를 판단하는데,
      사용된다.  */
  rovm_stack_t *maxlocal;

  /** Ticket 이 관리하는 스택 slot 들.  스택 배열입니다. */
  rovm_stack_t *stack;
  /** 위 변수 `stack' 에 할당된 스택 slot 의 갯수.  */
  int max_stack_slot;

  /** 현재 ticket operation 이 처리되면서 반환하게 되는 return 값이 설정되는
      위치.  */
  rovm_stack_t ret;

  /** GC 메모리가 할당되고 Ticket Slot 에 들어가기 전까지 해당 메모리 포인터가
      머무는 장소이다.  */
  void **delayed_slot;
  int delayed_slot_max;
  int delayed_slot_nelm;
};

extern struct ticket *create_ticket (struct rovm *);
extern char *create_ticketid (request_rec *);
extern int gen_unique_ticketid (char *);
extern int register_ticketid (request_rec *, char *);
extern struct ticket *lookup_ticket (request_rec *, char *);
extern int ticket_pre_config (struct ticket *);
extern int ticket_post_config (struct ticket *);
extern int ticket_beforecall (struct ticket *, RvMethod *, u2, u2 *);
extern void destroy_ticket (struct ticket *);
extern int destroy_tickets (struct rovm *, char *);
extern void ticket_clear_delay_slot (struct ticket *);
extern int ticket_collect (struct rovm *);

extern int safe_tktree_walking (struct rovm *, tktree_t *, tktree_foreach_fn, void *);

#endif
