/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */ /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */ /* Copyright (C) 2014 Stony Brook University This file is part of Graphene Library OS. Graphene Library OS is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Graphene Library OS 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* * shim_sysv.h * * This file includes functions and types for implementing System V IPC * functionality. */ #ifndef __SHIM_SYSV_H__ #define __SHIM_SYSV_H__ #include #include enum sysv_type { SYSV_NONE, SYSV_MSGQ, SYSV_SEM, SYSV_SHM }; #define SYSV_TYPE_STR(type) \ ((type) == SYSV_MSGQ ? "MSGQ" : \ ((type) == SYSV_SEM ? "SEM" : \ ((type) == SYSV_SHM ? "SHM" : \ ""))) #define VALID_SYSV_TYPE(type) \ ((type) == SYSV_MSGQ || (type) == SYSV_SEM || (type) == SYSV_SHM) struct sysv_score { IDTYPE vmid; unsigned long score; }; struct sysv_client { struct shim_ipc_port * port; IDTYPE vmid; unsigned seq; }; struct shim_handle; struct sysv_balance_policy { unsigned int score_decay; unsigned int score_max; unsigned int balance_threshold; int (*migrate) (struct shim_handle * hdl, struct sysv_client * client); }; int __balance_sysv_score (struct sysv_balance_policy * policy, struct shim_handle * hdl, struct sysv_score * scores, int nscores, struct sysv_client * src, long score); #define MSG_NOERROR 010000 #include struct __kernel_msgbuf { long mtype; /* type of message */ char mtext[]; /* message text */ }; #define MSG_QOBJ_SIZE 64 struct msg_qobj { void * next; char data[MSG_QOBJ_SIZE - sizeof(void *)]; } __attribute__((packed)); struct msg_item { void * next; unsigned short size; char data[]; } __attribute__((packed)); #define MSG_ITEM_DATA_SIZE(size) \ ((size) < MSG_QOBJ_SIZE - sizeof(struct msg_item) ? (size) : \ MSG_QOBJ_SIZE - sizeof(struct msg_item)) struct msg_ext_item { void * next; char data[]; } __attribute__((packed)); #define MSG_EXT_ITEM_DATA_SIZE(size) \ ((size) < MSG_QOBJ_SIZE - sizeof(struct msg_ext_item) ? (size) : \ MSG_QOBJ_SIZE - sizeof(struct msg_ext_item)) struct msg_req { struct msg_req * next; unsigned short size; int flags; struct sysv_client dest; } __attribute__((packed)); #define INIT_MSG_TYPE_SIZE 32 struct msg_type { long type; /* type of the messages */ struct msg_item * msgs, * msg_tail; struct msg_req * reqs, * req_tail; }; #define DEFAULT_MSG_QUEUE_SIZE 2048 #define MSG_SND_SCORE 1 #define MSG_RCV_SCORE 20 #define MSG_SCORE_DECAY 10 #define MSG_SCORE_MAX 200 #define MSG_BALANCE_THRESHOLD 100 struct msg_handle_backup { int perm; /* access permissions */ int nmsgs; /* number of msgs */ int currentsize; /* current size in bytes */ }; struct msg_backup { long type; int size; char data[]; }; struct shim_msg_handle; int add_msg_handle (unsigned long key, IDTYPE id, bool owned); int del_msg_handle (struct shim_msg_handle * msgq); struct shim_msg_handle * get_msg_handle_by_key (unsigned long key); struct shim_msg_handle * get_msg_handle_by_id (IDTYPE id); void put_msg_handle (struct shim_msg_handle * msgq); int recover_msg_ownership (struct shim_msg_handle * msgq); int add_sysv_msg (struct shim_msg_handle * msgq, long type, int size, const void * data, struct sysv_client * src); int get_sysv_msg (struct shim_msg_handle * msgq, long type, int size, void * data, int flags, struct sysv_client * src); int store_all_msg_persist (void); #define HOST_SEM_NUM 65535 DEFINE_LIST(sem_ops); struct sem_ops { LIST_TYPE(sem_ops) progress; struct sem_stat { bool completed; bool failed; int nops; int current; unsigned long timeout; } stat; struct sysv_client client; struct sembuf ops[]; }; DEFINE_LISTP(sem_ops); struct sem_obj { unsigned short num; unsigned short val; unsigned short zcnt; unsigned short ncnt; IDTYPE pid; PAL_NUM host_sem_id; PAL_HANDLE host_sem; LISTP_TYPE(sem_ops) ops; LISTP_TYPE(sem_ops) next_ops; }; #define SEM_POSITIVE_SCORE(num) ((num) < 5 ? 5 - (num) : 1) #define SEM_ZERO_SCORE 20 #define SEM_NEGATIVE_SCORE(num) (20 * (num)) #define SEM_SCORE_DECAY 10 #define SEM_SCORE_MAX 200 #define SEM_BALANCE_THRESHOLD 100 struct sem_backup { unsigned short val; unsigned short zcnt; unsigned short ncnt; IDTYPE pid; }; struct sem_client_backup { IDTYPE vmid; unsigned long seq; int current; int nops; }; int add_sem_handle (unsigned long key, IDTYPE id, int nsems, bool owned); struct shim_sem_handle * get_sem_handle_by_key (unsigned long key); struct shim_sem_handle * get_sem_handle_by_id (IDTYPE semid); void put_sem_handle (struct shim_sem_handle * sem); int del_sem_handle (struct shim_sem_handle * sem); int recover_sem_ownership (struct shim_sem_handle * sem, struct sem_backup * backups, int nbackups, struct sem_client_backup * clients, int nclients); int submit_sysv_sem (struct shim_sem_handle * sem, struct sembuf * sops, int nsops, unsigned long timeout, struct sysv_client * client); #ifdef USE_SHARED_SEMAPHORE int send_sem_host_ids (struct shim_sem_handle * sem, struct shim_ipc_port * port, IDTYPE dest, unsigned long seq); #endif #endif /* __SHIM_SYSV_H__ */