/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "ssvm.h"

int ssvm_master_init (ssvm_private_t * ssvm, u32 master_index)
{
  int ssvm_fd;
  u8 * ssvm_filename;
  u8 junk = 0;
  int flags;
  ssvm_shared_header_t * sh;
  u64 ticks = clib_cpu_time_now();
  u64 randomize_baseva;
  void * oldheap;

  if (ssvm->ssvm_size == 0)
    return SSVM_API_ERROR_NO_SIZE;

  ssvm_filename = format (0, "/dev/shm/%s%c", ssvm->name, 0);

  unlink ((char *) ssvm_filename);

  vec_free(ssvm_filename);

  ssvm_fd = shm_open((char *) ssvm->name, O_RDWR | O_CREAT | O_EXCL, 0777);

  if (ssvm_fd < 0)
    {
      clib_unix_warning ("create segment '%s'", ssvm->name);
      return SSVM_API_ERROR_CREATE_FAILURE;
    }

  lseek(ssvm_fd, ssvm->ssvm_size, SEEK_SET);
  if (write(ssvm_fd, &junk, 1) != 1)
    {
      clib_unix_warning ("set ssvm size");
      close(ssvm_fd);
      return SSVM_API_ERROR_SET_SIZE;
    }
  
  flags = MAP_SHARED;
  if (ssvm->requested_va)
    flags |= MAP_FIXED;

  randomize_baseva = (ticks & 15) * MMAP_PAGESIZE;

  if (ssvm->requested_va)
    ssvm->requested_va += randomize_baseva;
  
  sh = ssvm->sh = (void *) mmap((void *)ssvm->requested_va, ssvm->ssvm_size, 
                                PROT_READ | PROT_WRITE, flags, ssvm_fd, 0);

  if ((u64) ssvm->sh == (u64) MAP_FAILED)
    {
      clib_unix_warning ("mmap");
      close(ssvm_fd);
      return SSVM_API_ERROR_MMAP;
    }

  close(ssvm_fd);

  ssvm->my_pid = getpid();
  sh->master_pid = ssvm->my_pid;
  sh->ssvm_size = ssvm->ssvm_size;
  sh->heap = mheap_alloc_with_flags 
    (((u8 *)sh) + MMAP_PAGESIZE, ssvm->ssvm_size - MMAP_PAGESIZE, 
     MHEAP_FLAG_DISABLE_VM | MHEAP_FLAG_THREAD_SAFE);

  sh->ssvm_va = (u64) sh;
  sh->master_index = master_index;

  oldheap = ssvm_push_heap (sh);
  sh->name = format (0, "%s%c", ssvm->name, 0);
  ssvm_pop_heap (oldheap);

  ssvm->i_am_master = 1;

  /* The application has to set set sh->ready... */
  return 0;
}

int ssvm_slave_init (ssvm_private_t * ssvm, int timeout_in_seconds)
{
    struct stat stat;
    int ssvm_fd = -1;
    ssvm_shared_header_t * sh;

    ssvm->i_am_master = 0;

    while (timeout_in_seconds-- > 0)
      {
        if (ssvm_fd < 0)
          ssvm_fd = shm_open((char *)ssvm->name, O_RDWR, 0777);
        if (ssvm_fd < 0)
          {
            sleep (1);
            continue;
          }
        if (fstat(ssvm_fd, &stat) < 0)
          {
            sleep (1);
            continue;
          }
        
        if (stat.st_size > 0)
          goto map_it;
      }
    clib_warning ("slave timeout");
    return SSVM_API_ERROR_SLAVE_TIMEOUT;
        
 map_it:
    sh = (void *) mmap (0, MMAP_PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, 
                        ssvm_fd, 0);
    if ((u64) sh == (u64) MAP_FAILED)
      {
        clib_unix_warning ("slave research mmap");
        close (ssvm_fd);
        return SSVM_API_ERROR_MMAP;
      }
    
    while (timeout_in_seconds-- > 0)
      {
        if (sh->ready)
          goto re_map_it;
      }
    close (ssvm_fd);
    munmap (sh, MMAP_PAGESIZE);
    clib_warning ("slave timeout 2");
    return SSVM_API_ERROR_SLAVE_TIMEOUT;
    
 re_map_it:
    ssvm->requested_va = (u64) sh->ssvm_va;
    ssvm->ssvm_size = sh->ssvm_size;
    munmap (sh, MMAP_PAGESIZE);

    sh = ssvm->sh = (void *) mmap((void *)ssvm->requested_va, ssvm->ssvm_size, 
                                  PROT_READ | PROT_WRITE, 
                                  MAP_SHARED | MAP_FIXED,
                                  ssvm_fd, 0);
    
    if ((u64) sh == (u64) MAP_FAILED)
      {
        clib_unix_warning ("slave final mmap");
        close (ssvm_fd);
        return SSVM_API_ERROR_MMAP;
      }
    sh->slave_pid = getpid();
    return 0;
}
