root/headers/private/fs_shell/fssh_os.h
/* Kernel specific structures and functions
 *
 * Copyright 2004-2006, Haiku Inc. All Rights Reserved.
 * Distributed under the terms of the MIT License.
 */
#ifndef _FSSH_SEM_H
#define _FSSH_SEM_H

#include "fssh_types.h"


#ifdef __cplusplus
extern "C" {
#endif


/*-------------------------------------------------------------*/
/* System constants */

#define FSSH_B_OS_NAME_LENGTH   32
#define FSSH_B_PAGE_SIZE                4096
#define FSSH_B_INFINITE_TIMEOUT (9223372036854775807LL)


/*-------------------------------------------------------------*/
/* Types */

typedef int32_t fssh_area_id;
typedef int32_t fssh_port_id;
typedef int32_t fssh_sem_id;
typedef int32_t fssh_team_id;
typedef int32_t fssh_thread_id;


/*-------------------------------------------------------------*/
/* Semaphores */

typedef struct fssh_sem_info {
        fssh_sem_id             sem;
        fssh_team_id    team;
        char                    name[FSSH_B_OS_NAME_LENGTH];
        int32_t                 count;
        fssh_thread_id  latest_holder;
} fssh_sem_info;

/* semaphore flags */
enum {
        FSSH_B_CAN_INTERRUPT                    = 0x01, // acquisition of the semaphore can be
                                                                                        // interrupted (system use only)
        FSSH_B_CHECK_PERMISSION                 = 0x04, // ownership will be checked (system use
                                                                                        // only)
        FSSH_B_KILL_CAN_INTERRUPT               = 0x20, // acquisition of the semaphore can be
                                                                                        // interrupted by SIGKILL[THR], even
                                                                                        // if not B_CAN_INTERRUPT (system use
                                                                                        // only)

        /* release_sem_etc() only flags */
        FSSH_B_DO_NOT_RESCHEDULE                = 0x02, // thread is not rescheduled
        FSSH_B_RELEASE_ALL                              = 0x08, // all waiting threads will be woken up,
                                                                                        // count will be zeroed
        FSSH_B_RELEASE_IF_WAITING_ONLY  = 0x10  // release count only if there are any
                                                                                        // threads waiting
};

extern fssh_sem_id              fssh_create_sem(int32_t count, const char *name);
extern fssh_status_t    fssh_delete_sem(fssh_sem_id id);
extern fssh_status_t    fssh_acquire_sem(fssh_sem_id id);
extern fssh_status_t    fssh_acquire_sem_etc(fssh_sem_id id, int32_t count,
                                                        uint32_t flags, fssh_bigtime_t timeout);
extern fssh_status_t    fssh_release_sem(fssh_sem_id id);
extern fssh_status_t    fssh_release_sem_etc(fssh_sem_id id, int32_t count,
                                                        uint32_t flags);
extern fssh_status_t    fssh_get_sem_count(fssh_sem_id id,
                                                        int32_t *threadCount);
extern fssh_status_t    fssh_set_sem_owner(fssh_sem_id id, fssh_team_id team);

/* system private, use the macros instead */
extern fssh_status_t    _fssh_get_sem_info(fssh_sem_id id,
                                                        struct fssh_sem_info *info, fssh_size_t infoSize);
extern fssh_status_t    _fssh_get_next_sem_info(fssh_team_id team,
                                                        int32_t *cookie, struct fssh_sem_info *info,
                                                        fssh_size_t infoSize);

#define fssh_get_sem_info(sem, info) \
                        _fssh_get_sem_info((sem), (info), sizeof(*(info)))

#define fssh_get_next_sem_info(team, cookie, info) \
                        _fssh_get_next_sem_info((team), (cookie), (info), sizeof(*(info)))



enum {
        FSSH_B_TIMEOUT                  = 8,    /* relative timeout */
        FSSH_B_RELATIVE_TIMEOUT = 8,    /* fails after a relative timeout with B_WOULD_BLOCK */
        FSSH_B_ABSOLUTE_TIMEOUT = 16    /* fails after an absolute timeout with B_WOULD BLOCK */
};


/*-------------------------------------------------------------*/
/* Teams */

#define FSSH_B_CURRENT_TEAM     0
#define FSSH_B_SYSTEM_TEAM      1


/*-------------------------------------------------------------*/
/* Threads */

typedef enum {
        FSSH_B_THREAD_RUNNING   = 1,
        FSSH_B_THREAD_READY,
        FSSH_B_THREAD_RECEIVING,
        FSSH_B_THREAD_ASLEEP,
        FSSH_B_THREAD_SUSPENDED,
        FSSH_B_THREAD_WAITING
} fssh_thread_state;

typedef struct {
        fssh_thread_id          thread;
        fssh_team_id            team;
        char                            name[FSSH_B_OS_NAME_LENGTH];
        fssh_thread_state       state;
        int32_t                         priority;
        fssh_sem_id                     sem;
        fssh_bigtime_t          user_time;
        fssh_bigtime_t          kernel_time;
        void                            *stack_base;
        void                            *stack_end;
} fssh_thread_info;

#define FSSH_B_IDLE_PRIORITY                            0
#define FSSH_B_LOWEST_ACTIVE_PRIORITY           1
#define FSSH_B_LOW_PRIORITY                                     5
#define FSSH_B_NORMAL_PRIORITY                          10
#define FSSH_B_DISPLAY_PRIORITY                         15
#define FSSH_B_URGENT_DISPLAY_PRIORITY          20
#define FSSH_B_REAL_TIME_DISPLAY_PRIORITY       100
#define FSSH_B_URGENT_PRIORITY                          110
#define FSSH_B_REAL_TIME_PRIORITY                       120

#define FSSH_B_FIRST_REAL_TIME_PRIORITY         B_REAL_TIME_DISPLAY_PRIORITY
#define FSSH_B_MIN_PRIORITY                                     B_IDLE_PRIORITY
#define FSSH_B_MAX_PRIORITY                                     B_REAL_TIME_PRIORITY

#define FSSH_B_SYSTEM_TIMEBASE                          0

typedef fssh_status_t (*fssh_thread_func)(void *);
#define fssh_thread_entry fssh_thread_func
        /* thread_entry is for backward compatibility only! Use thread_func */

extern fssh_thread_id   fssh_spawn_thread(fssh_thread_func, const char *name,
                                                        int32_t priority, void *data);
extern fssh_status_t    fssh_kill_thread(fssh_thread_id thread);
extern fssh_status_t    fssh_resume_thread(fssh_thread_id thread);
extern fssh_status_t    fssh_suspend_thread(fssh_thread_id thread);

extern fssh_status_t    fssh_rename_thread(fssh_thread_id thread,
                                                        const char *newName);
extern fssh_status_t    fssh_set_thread_priority (fssh_thread_id thread,
                                                        int32_t newPriority);
extern void                             fssh_exit_thread(fssh_status_t status);
extern fssh_status_t    fssh_wait_for_thread (fssh_thread_id thread,
                                                        fssh_status_t *threadReturnValue);
extern fssh_status_t    fssh_on_exit_thread(void (*callback)(void *),
                                                        void *data);

extern fssh_thread_id   fssh_find_thread(const char *name);

extern fssh_status_t    fssh_send_data(fssh_thread_id thread, int32_t code,
                                                        const void *buffer,
                                                fssh_size_t bufferSize);
extern int32_t                  fssh_receive_data(fssh_thread_id *sender, void *buffer,
                                                        fssh_size_t bufferSize);
extern bool                             fssh_has_data(fssh_thread_id thread);

extern fssh_status_t    fssh_snooze(fssh_bigtime_t amount);
extern fssh_status_t    fssh_snooze_etc(fssh_bigtime_t amount, int timeBase,
                                                        uint32_t flags);
extern fssh_status_t    fssh_snooze_until(fssh_bigtime_t time, int timeBase);

/* system private, use macros instead */
extern fssh_status_t    _fssh_get_thread_info(fssh_thread_id id,
                                                        fssh_thread_info *info, fssh_size_t size);
extern fssh_status_t    _fssh_get_next_thread_info(fssh_team_id team,
                                                        int32_t *cookie, fssh_thread_info *info,
                                                        fssh_size_t size);

#define fssh_get_thread_info(id, info) \
                        _fssh_get_thread_info((id), (info), sizeof(*(info)))

#define fssh_get_next_thread_info(team, cookie, info) \
                        _fssh_get_next_thread_info((team), (cookie), (info), sizeof(*(info)))


/*-------------------------------------------------------------*/
/* Time */

extern unsigned long    fssh_real_time_clock(void);
extern void                             fssh_set_real_time_clock(unsigned long secs_since_jan1_1970);
extern fssh_bigtime_t   fssh_real_time_clock_usecs(void);
extern fssh_status_t    fssh_set_timezone(char *timezone);
extern fssh_bigtime_t   fssh_system_time(void);     /* time since booting in microseconds */


#ifdef __cplusplus
}
#endif


#endif  // _FSSH_TYPES_H