/*
 * process.h
 *
 * Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _PROCESS_H_
#define _PROCESS_H_

#include <sdk/process.h>
#include <common.h>
#include <object.h>
#include <memory.h>
#include <clock.h>
#include <pipe.h>
#include <thread.h>
#include <vm86.h>
#include <user.h>

#define MAX_PROCESSES 2097152
#define PROCESS_POOL_ADDRESS NULL
#define PROCESS_POOL_SIZE 524288
#define STARTUP_HANDLE_TABLE_SIZE (256 * sizeof(handle_info_t))

#ifndef THREAD_TYPEDEF
#define THREAD_TYPEDEF
typedef struct thread thread_t;
#endif

typedef struct
{
    object_t *obj; /* strong reference */
    access_flags_t access_flags;
} handle_info_t;

struct process
{
    object_t header;
    dword_t pid;
    char *name;
    memory_address_space_t memory_space;
    dword_t exit_code;
    bool_t terminating;
    dword_t terminated;
    clock_time_t start_time;
    clock_time_t end_time;
    list_entry_t threads;
    lock_t thread_list_lock;
    handle_info_t *handle_table;
    dword_t handle_count, handle_table_size;
    lock_t handle_table_lock;
    user_t *original_user; /* weak reference */
    user_t *current_user; /* strong reference */
};

#ifndef PROCESS_TYPEDEF
#define PROCESS_TYPEDEF
typedef struct process process_t;
#endif

extern process_t *kernel_process;

process_t *get_current_process();
void init_user_stack(uintptr_t *stack_pointer, process_params_t *parameters);
void process_cleanup(object_t *proc);
dword_t process_pre_wait(object_t *obj, void *parameter, wait_condition_t *condition);
void destroy_process(process_t *process);
process_t *switch_process(process_t *new_process);
void terminate_process(process_t *proc, dword_t exit_code);
void process_init(void);

#endif
