/branches/dd/uspace/lib/libfs/libfs.c |
---|
42,6 → 42,7 |
#include <as.h> |
#include <assert.h> |
#include <dirent.h> |
#include <mem.h> |
/** Register file system server. |
* |
208,12 → 209,13 |
* The path passed in the PLB must be in the canonical file system path format |
* as returned by the canonify() function. |
* |
* @param ops libfs operations structure with function pointers to |
* file system implementation |
* @param fs_handle File system handle of the file system where to perform |
* the lookup. |
* @param rid Request ID of the VFS_LOOKUP request. |
* @param request VFS_LOOKUP request data itself. |
* @param ops libfs operations structure with function pointers to |
* file system implementation |
* @param fs_handle File system handle of the file system where to perform |
* the lookup. |
* @param rid Request ID of the VFS_LOOKUP request. |
* @param request VFS_LOOKUP request data itself. |
* |
*/ |
void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, |
ipc_call_t *request) |
426,5 → 428,32 |
ops->node_put(tmp); |
} |
/** Open VFS triplet. |
* |
* @param ops libfs operations structure with function pointers to |
* file system implementation |
* @param rid Request ID of the VFS_OPEN_NODE request. |
* @param request VFS_OPEN_NODE request data itself. |
* |
*/ |
void libfs_open_node(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, |
ipc_call_t *request) |
{ |
dev_handle_t dev_handle = IPC_GET_ARG1(*request); |
fs_index_t index = IPC_GET_ARG2(*request); |
fs_node_t *node = ops->node_get(dev_handle, index); |
if (node == NULL) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
ipc_answer_5(rid, EOK, fs_handle, dev_handle, index, |
ops->size_get(node), ops->lnkcnt_get(node)); |
ops->node_put(node); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libfs/libfs.h |
---|
26,20 → 26,21 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libfs |
/** @addtogroup libfs |
* @{ |
*/ |
*/ |
/** |
* @file |
*/ |
#ifndef LIBFS_LIBFS_H_ |
#define LIBFS_LIBFS_H_ |
#define LIBFS_LIBFS_H_ |
#include "../../srv/vfs/vfs.h" |
#include <ipc/vfs.h> |
#include <stdint.h> |
#include <ipc/ipc.h> |
#include <async.h> |
#include <devmap.h> |
typedef struct { |
bool mp_active; |
49,8 → 50,8 |
} mp_data_t; |
typedef struct { |
mp_data_t mp_data; /**< Mount point info. */ |
void *data; /**< Data of the file system implementation. */ |
mp_data_t mp_data; /**< Mount point info. */ |
void *data; /**< Data of the file system implementation. */ |
} fs_node_t; |
typedef struct { |
66,15 → 67,15 |
unsigned (* lnkcnt_get)(fs_node_t *); |
bool (* has_children)(fs_node_t *); |
fs_node_t *(* root_get)(dev_handle_t); |
char (* plb_get_char)(unsigned pos); |
char (* plb_get_char)(unsigned pos); |
bool (* is_directory)(fs_node_t *); |
bool (* is_file)(fs_node_t *); |
} libfs_ops_t; |
typedef struct { |
int fs_handle; /**< File system handle. */ |
ipcarg_t vfs_phonehash; /**< Initial VFS phonehash. */ |
uint8_t *plb_ro; /**< Read-only PLB view. */ |
int fs_handle; /**< File system handle. */ |
ipcarg_t vfs_phonehash; /**< Initial VFS phonehash. */ |
uint8_t *plb_ro; /**< Read-only PLB view. */ |
} fs_reg_t; |
extern int fs_register(int, fs_reg_t *, vfs_info_t *, async_client_conn_t); |
83,9 → 84,10 |
extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); |
extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); |
extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t, |
ipc_call_t *); |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libblock/libblock.c |
---|
47,8 → 47,9 |
#include <as.h> |
#include <assert.h> |
#include <futex.h> |
#include <libadt/list.h> |
#include <libadt/hash_table.h> |
#include <adt/list.h> |
#include <adt/hash_table.h> |
#include <mem.h> |
/** Lock protecting the device connection list */ |
static futex_t dcl_lock = FUTEX_INITIALIZER; |
/branches/dd/uspace/lib/libblock/libblock.h |
---|
41,8 → 41,8 |
#include "../../srv/vfs/vfs.h" |
#include <futex.h> |
#include <rwlock.h> |
#include <libadt/hash_table.h> |
#include <libadt/list.h> |
#include <adt/hash_table.h> |
#include <adt/list.h> |
/* |
* Flags that can be used with block_get(). |
/branches/dd/uspace/lib/libc/include/console.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/console/color.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/console/style.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/kbd/kbd.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/kbd/keycode.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/libadt/fifo.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/libadt/hash_table.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/libadt/list.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/fcntl.h |
---|
35,13 → 35,13 |
#ifndef LIBC_FCNTL_H_ |
#define LIBC_FCNTL_H_ |
#define O_CREAT 1 |
#define O_EXCL 2 |
#define O_TRUNC 4 |
#define O_APPEND 8 |
#define O_RDONLY 16 |
#define O_RDWR 32 |
#define O_WRONLY 64 |
#define O_CREAT 1 |
#define O_EXCL 2 |
#define O_TRUNC 4 |
#define O_APPEND 8 |
#define O_RDONLY 16 |
#define O_RDWR 32 |
#define O_WRONLY 64 |
extern int open(const char *, int, ...); |
/branches/dd/uspace/lib/libc/include/string.h |
---|
39,8 → 39,8 |
#include <sys/types.h> |
#include <bool.h> |
#define U_SPECIAL '?' |
#define U_BOM 0xfeff |
#define U_SPECIAL '?' |
#define U_BOM 0xfeff |
/** No size limit constant */ |
#define STR_NO_LIMIT ((size_t) -1) |
54,20 → 54,20 |
extern size_t str_size(const char *str); |
extern size_t wstr_size(const wchar_t *str); |
extern size_t str_lsize(const char *str, count_t max_len); |
extern size_t wstr_lsize(const wchar_t *str, count_t max_len); |
extern size_t str_lsize(const char *str, size_t max_len); |
extern size_t wstr_lsize(const wchar_t *str, size_t max_len); |
extern count_t str_length(const char *str); |
extern count_t wstr_length(const wchar_t *wstr); |
extern size_t str_length(const char *str); |
extern size_t wstr_length(const wchar_t *wstr); |
extern count_t str_nlength(const char *str, size_t size); |
extern count_t wstr_nlength(const wchar_t *str, size_t size); |
extern size_t str_nlength(const char *str, size_t size); |
extern size_t wstr_nlength(const wchar_t *str, size_t size); |
extern bool ascii_check(wchar_t ch); |
extern bool chr_check(wchar_t ch); |
extern int str_cmp(const char *s1, const char *s2); |
extern int str_lcmp(const char *s1, const char *s2, count_t max_len); |
extern int str_lcmp(const char *s1, const char *s2, size_t max_len); |
extern void str_cpy(char *dest, size_t size, const char *src); |
extern void str_ncpy(char *dest, size_t size, const char *src, size_t n); |
78,8 → 78,8 |
extern const char *str_chr(const char *str, wchar_t ch); |
extern const char *str_rchr(const char *str, wchar_t ch); |
extern bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos); |
extern bool wstr_remove(wchar_t *str, count_t pos); |
extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos); |
extern bool wstr_remove(wchar_t *str, size_t pos); |
extern char *str_dup(const char *); |
/branches/dd/uspace/lib/libc/include/vfs/vfs.h |
---|
36,12 → 36,36 |
#define LIBC_VFS_H_ |
#include <sys/types.h> |
#include <ipc/vfs.h> |
#include <ipc/devmap.h> |
#include <stdio.h> |
/** |
* This type is a libc version of the VFS triplet. |
* It uniquelly identifies a file system node within a file system instance. |
*/ |
typedef struct { |
fs_handle_t fs_handle; |
dev_handle_t dev_handle; |
fs_index_t index; |
} fdi_node_t; |
extern char *absolutize(const char *, size_t *); |
extern int mount(const char *, const char *, const char *, const char *, |
unsigned int flags); |
unsigned int); |
extern void stdio_init(int filc, fdi_node_t *filv[]); |
extern void stdio_done(void); |
extern int open_node(fdi_node_t *, int); |
extern int fd_phone(int); |
extern int fd_node(int, fdi_node_t *); |
extern FILE *fopen_node(fdi_node_t *, const char *); |
extern int fphone(FILE *); |
extern int fnode(FILE *, fdi_node_t *); |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/async.h |
---|
43,13 → 43,17 |
typedef ipc_callid_t aid_t; |
typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call); |
typedef void (*async_pending_t)(void); |
extern atomic_t async_futex; |
static inline void async_manager(void) |
{ |
fibril_switch(FIBRIL_TO_MANAGER); |
} |
ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs); |
extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs); |
static inline ipc_callid_t async_get_call(ipc_call_t *data) |
{ |
return async_get_call_timeout(data, 0); |
63,19 → 67,19 |
*/ |
#define async_send_0(phoneid, method, dataptr) \ |
async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr)) |
async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr)) |
#define async_send_1(phoneid, method, arg1, dataptr) \ |
async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr)) |
async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr)) |
#define async_send_2(phoneid, method, arg1, arg2, dataptr) \ |
async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr)) |
async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr)) |
#define async_send_3(phoneid, method, arg1, arg2, arg3, dataptr) \ |
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr)) |
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr)) |
#define async_send_4(phoneid, method, arg1, arg2, arg3, arg4, dataptr) \ |
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(dataptr)) |
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(dataptr)) |
#define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \ |
async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (dataptr)) |
async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (dataptr)) |
extern aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr); |
86,34 → 90,35 |
extern int async_wait_timeout(aid_t amsgid, ipcarg_t *retval, |
suseconds_t timeout); |
fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid, |
extern fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid, |
ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *)); |
void async_usleep(suseconds_t timeout); |
void async_create_manager(void); |
void async_destroy_manager(void); |
int _async_init(void); |
extern void async_usleep(suseconds_t timeout); |
extern void async_create_manager(void); |
extern void async_destroy_manager(void); |
extern int _async_init(void); |
extern void async_set_client_connection(async_client_conn_t conn); |
extern void async_set_interrupt_received(async_client_conn_t conn); |
extern void async_set_pending(async_pending_t pend); |
/* Wrappers for simple communication */ |
#define async_msg_0(phone, method) \ |
ipc_call_async_0((phone), (method), NULL, NULL, true) |
ipc_call_async_0((phone), (method), NULL, NULL, true) |
#define async_msg_1(phone, method, arg1) \ |
ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \ |
true) |
ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \ |
true) |
#define async_msg_2(phone, method, arg1, arg2) \ |
ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \ |
true) |
ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \ |
true) |
#define async_msg_3(phone, method, arg1, arg2, arg3) \ |
ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \ |
true) |
ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \ |
true) |
#define async_msg_4(phone, method, arg1, arg2, arg3, arg4) \ |
ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \ |
NULL, true) |
ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \ |
NULL, true) |
#define async_msg_5(phone, method, arg1, arg2, arg3, arg4, arg5) \ |
ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), NULL, NULL, true) |
ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), NULL, NULL, true) |
/* |
* User-friendly wrappers for async_req_fast() and async_req_slow(). The macros |
122,90 → 127,90 |
* and slow verion based on m. |
*/ |
#define async_req_0_0(phoneid, method) \ |
async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \ |
NULL) |
async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \ |
NULL) |
#define async_req_0_1(phoneid, method, r1) \ |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \ |
NULL) |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \ |
NULL) |
#define async_req_0_2(phoneid, method, r1, r2) \ |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \ |
NULL) |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \ |
NULL) |
#define async_req_0_3(phoneid, method, r1, r2, r3) \ |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \ |
NULL) |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \ |
NULL) |
#define async_req_0_4(phoneid, method, r1, r2, r3, r4) \ |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \ |
NULL) |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \ |
NULL) |
#define async_req_0_5(phoneid, method, r1, r2, r3, r4, r5) \ |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \ |
(r5)) |
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \ |
(r5)) |
#define async_req_1_0(phoneid, method, arg1) \ |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \ |
NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \ |
NULL, NULL) |
#define async_req_1_1(phoneid, method, arg1, rc1) \ |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \ |
NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \ |
NULL, NULL) |
#define async_req_1_2(phoneid, method, arg1, rc1, rc2) \ |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \ |
NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \ |
NULL, NULL) |
#define async_req_1_3(phoneid, method, arg1, rc1, rc2, rc3) \ |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \ |
NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \ |
NULL, NULL) |
#define async_req_1_4(phoneid, method, arg1, rc1, rc2, rc3, rc4) \ |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \ |
(rc4), NULL) |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \ |
(rc4), NULL) |
#define async_req_1_5(phoneid, method, arg1, rc1, rc2, rc3, rc4, rc5) \ |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \ |
(rc4), (rc5)) |
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \ |
(rc4), (rc5)) |
#define async_req_2_0(phoneid, method, arg1, arg2) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \ |
NULL, NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \ |
NULL, NULL, NULL) |
#define async_req_2_1(phoneid, method, arg1, arg2, rc1) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \ |
NULL, NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \ |
NULL, NULL, NULL) |
#define async_req_2_2(phoneid, method, arg1, arg2, rc1, rc2) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ |
NULL, NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ |
NULL, NULL, NULL) |
#define async_req_2_3(phoneid, method, arg1, arg2, rc1, rc2, rc3) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ |
(rc3), NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ |
(rc3), NULL, NULL) |
#define async_req_2_4(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ |
(rc3), (rc4), NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ |
(rc3), (rc4), NULL) |
#define async_req_2_5(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ |
(rc3), (rc4), (rc5)) |
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \ |
(rc3), (rc4), (rc5)) |
#define async_req_3_0(phoneid, method, arg1, arg2, arg3) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \ |
NULL, NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \ |
NULL, NULL, NULL) |
#define async_req_3_1(phoneid, method, arg1, arg2, arg3, rc1) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ |
NULL, NULL, NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ |
NULL, NULL, NULL, NULL) |
#define async_req_3_2(phoneid, method, arg1, arg2, arg3, rc1, rc2) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ |
(rc2), NULL, NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ |
(rc2), NULL, NULL, NULL) |
#define async_req_3_3(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ |
(rc2), (rc3), NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ |
(rc2), (rc3), NULL, NULL) |
#define async_req_3_4(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ |
(rc2), (rc3), (rc4), NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ |
(rc2), (rc3), (rc4), NULL) |
#define async_req_3_5(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \ |
rc5) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \ |
(rc2), (rc3), (rc4), (rc5)) |
#define async_req_4_0(phoneid, method, arg1, arg2, arg3, arg4) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \ |
NULL, NULL, NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \ |
NULL, NULL, NULL, NULL) |
#define async_req_4_1(phoneid, method, arg1, arg2, arg3, arg4, rc1) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \ |
NULL, NULL, NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \ |
NULL, NULL, NULL, NULL) |
#define async_req_4_2(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \ |
(rc2), NULL, NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \ |
(rc2), NULL, NULL, NULL) |
#define async_req_4_3(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \ |
(rc2), (rc3), NULL, NULL) |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \ |
(rc2), (rc3), NULL, NULL) |
#define async_req_4_4(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \ |
rc4) \ |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
215,14 → 220,14 |
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(rc1), (rc2), (rc3), (rc4), (rc5)) |
#define async_req_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \ |
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), NULL, NULL, NULL, NULL, NULL) |
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), NULL, NULL, NULL, NULL, NULL) |
#define async_req_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1) \ |
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (rc1), NULL, NULL, NULL, NULL) |
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (rc1), NULL, NULL, NULL, NULL) |
#define async_req_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \ |
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (rc1), (rc2), NULL, NULL, NULL) |
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (rc1), (rc2), NULL, NULL, NULL) |
#define async_req_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \ |
rc3) \ |
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
253,8 → 258,6 |
fibril_dec_sercount(); |
} |
extern atomic_t async_futex; |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/stdio.h |
---|
37,78 → 37,94 |
#include <sys/types.h> |
#include <stdarg.h> |
#include <adt/list.h> |
#define EOF (-1) |
#define EOF (-1) |
#include <string.h> |
#include <io/stream.h> |
#define DEBUG(fmt, ...) \ |
{ \ |
char buf[256]; \ |
int n; \ |
n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \ |
int n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \ |
if (n > 0) \ |
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, str_size(buf)); \ |
} |
#ifndef SEEK_SET |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
#endif |
typedef struct { |
/** Linked list pointer. */ |
link_t link; |
/** Underlying file descriptor. */ |
int fd; |
/** Error indicator. */ |
int error; |
/** End-of-file indicator. */ |
int eof; |
/** Klog indicator */ |
int klog; |
/** Phone to the file provider */ |
int phone; |
} FILE; |
extern FILE *stdin, *stdout, *stderr; |
extern FILE *stdin; |
extern FILE *stdout; |
extern FILE *stderr; |
/* Character and string input functions */ |
extern int fgetc(FILE *); |
extern char *fgets(char *, size_t, FILE *); |
extern int getchar(void); |
extern char *gets(char *, size_t); |
/* Character and string output functions */ |
extern int fputc(wchar_t, FILE *); |
extern int fputs(const char *, FILE *); |
extern int putchar(wchar_t); |
extern int puts(const char *); |
extern int putchar(int); |
extern int fflush(FILE *); |
/* Formatted string output functions */ |
extern int fprintf(FILE *, const char*, ...); |
extern int vfprintf(FILE *, const char *, va_list); |
extern int printf(const char *, ...); |
extern int vprintf(const char *, va_list); |
extern int snprintf(char *, size_t , const char *, ...); |
extern int asprintf(char **, const char *, ...); |
extern int sprintf(char *, const char *, ...); |
extern int snprintf(char *, size_t , const char *, ...); |
extern int vprintf(const char *, va_list); |
extern int vsprintf(char *, const char *, va_list); |
extern int vsnprintf(char *, size_t, const char *, va_list); |
extern int rename(const char *, const char *); |
/* File stream functions */ |
extern FILE *fopen(const char *, const char *); |
extern FILE *fdopen(int, const char *); |
extern int fclose(FILE *); |
extern size_t fread(void *, size_t, size_t, FILE *); |
extern size_t fwrite(const void *, size_t, size_t, FILE *); |
extern int fseek(FILE *, long, int); |
extern void rewind(FILE *); |
extern int ftell(FILE *); |
extern int feof(FILE *); |
extern int fflush(FILE *); |
extern int ferror(FILE *); |
extern void clearerr(FILE *); |
extern int fgetc(FILE *); |
extern int fputc(int, FILE *); |
extern int fputs(const char *, FILE *); |
/* Misc file functions */ |
extern int rename(const char *, const char *); |
extern int fprintf(FILE *, const char *, ...); |
extern int vfprintf(FILE *, const char *, va_list); |
#define getc fgetc |
#define putc fputc |
extern int fseek(FILE *, long, int); |
#ifndef SEEK_SET |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
#endif |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/dirent.h |
---|
35,7 → 35,7 |
#ifndef LIBC_DIRENT_H_ |
#define LIBC_DIRENT_H_ |
#define NAME_MAX 256 |
#define NAME_MAX 256 |
struct dirent { |
char d_name[NAME_MAX + 1]; |
46,7 → 46,6 |
struct dirent res; |
} DIR; |
extern DIR *opendir(const char *); |
extern struct dirent *readdir(DIR *); |
extern void rewinddir(DIR *); |
/branches/dd/uspace/lib/libc/include/task.h |
---|
42,6 → 42,7 |
extern task_id_t task_get_id(void); |
extern int task_set_name(const char *name); |
extern task_id_t task_spawn(const char *path, char *const argv[]); |
extern int task_wait(task_id_t id); |
#endif |
/branches/dd/uspace/lib/libc/include/fibril_sync.h |
---|
0,0 → 1,104 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_FIBRIL_SYNC_H_ |
#define LIBC_FIBRIL_SYNC_H_ |
#include <async.h> |
#include <fibril.h> |
#include <adt/list.h> |
#include <libarch/tls.h> |
typedef struct { |
int counter; |
link_t waiters; |
} fibril_mutex_t; |
#define FIBRIL_MUTEX_INITIALIZE(name) \ |
fibril_mutex_t name = { \ |
.counter = 1, \ |
.waiters = { \ |
.prev = &name.waiters, \ |
.next = &name.waiters, \ |
} \ |
} |
typedef struct { |
unsigned writers; |
unsigned readers; |
link_t waiters; |
} fibril_rwlock_t; |
#define FIBRIL_RWLOCK_INITIALIZE(name) \ |
fibril_rwlock_t name = { \ |
.readers = 0, \ |
.writers = 0, \ |
.waiters = { \ |
.prev = &name.waiters, \ |
.next = &name.waiters, \ |
} \ |
} |
typedef struct { |
link_t waiters; |
} fibril_condvar_t; |
#define FIBRIL_CONDVAR_INITIALIZE(name) \ |
fibril_condvar_t name = { \ |
.waiters = { \ |
.next = &name.waiters, \ |
.prev = &name.waiters, \ |
} \ |
} |
extern void fibril_mutex_initialize(fibril_mutex_t *); |
extern void fibril_mutex_lock(fibril_mutex_t *); |
extern bool fibril_mutex_trylock(fibril_mutex_t *); |
extern void fibril_mutex_unlock(fibril_mutex_t *); |
extern void fibril_rwlock_initialize(fibril_rwlock_t *); |
extern void fibril_rwlock_read_lock(fibril_rwlock_t *); |
extern void fibril_rwlock_write_lock(fibril_rwlock_t *); |
extern void fibril_rwlock_read_unlock(fibril_rwlock_t *); |
extern void fibril_rwlock_write_unlock(fibril_rwlock_t *); |
extern void fibril_condvar_initialize(fibril_condvar_t *); |
extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *); |
extern void fibril_condvar_signal(fibril_condvar_t *); |
extern void fibril_condvar_broadcast(fibril_condvar_t *); |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/unistd.h |
---|
39,26 → 39,30 |
#include <libarch/config.h> |
#ifndef NULL |
#define NULL 0 |
#define NULL 0 |
#endif |
#define getpagesize() (PAGE_SIZE) |
#define getpagesize() (PAGE_SIZE) |
#ifndef SEEK_SET |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
#endif |
extern ssize_t write(int, const void *, size_t); |
extern ssize_t read(int, void *, size_t); |
extern off_t lseek(int, off_t, int); |
extern int ftruncate(int, off_t); |
extern int close(int); |
extern int fsync(int); |
extern int unlink(const char *); |
extern char *getcwd(char *buf, size_t); |
extern int rmdir(const char *); |
extern int chdir(const char *); |
extern char *getcwd(char *buf, size_t); |
extern void _exit(int status) __attribute__ ((noreturn)); |
extern void *sbrk(ssize_t incr); |
/branches/dd/uspace/lib/libc/include/fibril.h |
---|
36,17 → 36,18 |
#define LIBC_FIBRIL_H_ |
#include <libarch/fibril.h> |
#include <libadt/list.h> |
#include <adt/list.h> |
#include <libarch/tls.h> |
#ifndef context_set |
#define context_set(c, _pc, stack, size, ptls) \ |
(c)->pc = (sysarg_t) (_pc); \ |
(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ |
(c)->tls = (sysarg_t) (ptls); |
#define context_set(c, _pc, stack, size, ptls) \ |
(c)->pc = (sysarg_t) (_pc); \ |
(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ |
(c)->tls = (sysarg_t) (ptls); |
#endif /* context_set */ |
#define FIBRIL_SERIALIZED 1 |
#define FIBRIL_SERIALIZED 1 |
#define FIBRIL_WRITER 2 |
typedef enum { |
FIBRIL_PREEMPT, |
71,6 → 72,9 |
}; |
typedef struct fibril fibril_t; |
/** Fibril-local variable specifier */ |
#define fibril_local __thread |
extern int context_save(context_t *c); |
extern void context_restore(context_t *c) __attribute__ ((noreturn)); |
/branches/dd/uspace/lib/libc/include/loader/pcb.h |
---|
37,6 → 37,7 |
#define LIBC_PCB_H_ |
#include <sys/types.h> |
#include <vfs/vfs.h> |
typedef void (*entry_point_t)(void); |
45,19 → 46,26 |
* Holds pointers to data passed from the program loader to the program |
* and/or to the dynamic linker. This includes the program entry point, |
* arguments, environment variables etc. |
* |
*/ |
typedef struct { |
/** Program entry point. */ |
entry_point_t entry; |
/** Number of command-line arguments. */ |
int argc; |
/** Command-line arguments. */ |
char **argv; |
/** Number of preset files. */ |
int filc; |
/** Preset files. */ |
fdi_node_t **filv; |
/* |
* ELF-specific data. |
*/ |
/** Pointer to ELF dynamic section of the program. */ |
void *dynamic; |
} pcb_t; |
/branches/dd/uspace/lib/libc/include/loader/loader.h |
---|
37,6 → 37,7 |
#define LIBC_LOADER_H_ |
#include <task.h> |
#include <vfs/vfs.h> |
/** Abstraction of a loader connection */ |
typedef struct { |
48,7 → 49,8 |
extern loader_t *loader_connect(void); |
extern int loader_get_task_id(loader_t *, task_id_t *); |
extern int loader_set_pathname(loader_t *, const char *); |
extern int loader_set_args(loader_t *, char *const []); |
extern int loader_set_args(loader_t *, char *const[]); |
extern int loader_set_files(loader_t *, fdi_node_t *const[]); |
extern int loader_load_program(loader_t *); |
extern int loader_run(loader_t *); |
extern void loader_abort(loader_t *); |
/branches/dd/uspace/lib/libc/include/io/io.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/io/stream.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/io/printf_core.h |
---|
56,5 → 56,3 |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/io/klog.h |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 Jakub Vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_STREAM_H_ |
#define LIBC_STREAM_H_ |
#include <sys/types.h> |
extern size_t klog_write(const void *buf, size_t size); |
extern void klog_update(void); |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/io/color.h |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_IO_COLOR_H_ |
#define LIBC_IO_COLOR_H_ |
enum console_color { |
COLOR_BLACK = 0, |
COLOR_BLUE = 1, |
COLOR_GREEN = 2, |
COLOR_CYAN = 3, |
COLOR_RED = 4, |
COLOR_MAGENTA = 5, |
COLOR_YELLOW = 6, |
COLOR_WHITE = 7, |
CATTR_BRIGHT = 8, |
CATTR_BLINK = 8 |
}; |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/io/style.h |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_IO_STYLE_H_ |
#define LIBC_IO_STYLE_H_ |
enum console_style { |
STYLE_NORMAL = 0, |
STYLE_EMPHASIS = 1 |
}; |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/io/console.h |
---|
0,0 → 1,78 |
/* |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_IO_CONSOLE_H_ |
#define LIBC_IO_CONSOLE_H_ |
#include <ipc/ipc.h> |
#include <bool.h> |
typedef enum { |
KEY_PRESS, |
KEY_RELEASE |
} console_ev_type_t; |
/** Console event structure. */ |
typedef struct { |
/** Press or release event. */ |
console_ev_type_t type; |
/** Keycode of the key that was pressed or released. */ |
unsigned int key; |
/** Bitmask of modifiers held. */ |
unsigned int mods; |
/** The character that was generated or '\0' for none. */ |
wchar_t c; |
} console_event_t; |
extern void console_clear(int phone); |
extern int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols); |
extern void console_goto(int phone, ipcarg_t row, ipcarg_t col); |
extern void console_set_style(int phone, int style); |
extern void console_set_color(int phone, int fg_color, int bg_color, int flags); |
extern void console_set_rgb_color(int phone, int fg_color, int bg_color); |
extern void console_cursor_visibility(int phone, bool show); |
extern void console_kcon_enable(int phone); |
extern bool console_get_event(int phone, console_event_t *event); |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/io/keycode.h |
---|
0,0 → 1,220 |
/* |
* Copyright (c) 2009 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_IO_KEYCODE_H_ |
#define LIBC_IO_KEYCODE_H_ |
/** Keycode definitions. |
* |
* A keycode identifies a key by its position on the keyboard, rather |
* than by its label. For human readability, key positions are noted |
* with the key label on a keyboard with US layout. This label has |
* nothing to do with the character, that the key produces |
* -- this is determined by the keymap. |
* |
* The keyboard model reflects a standard PC keyboard layout. |
* Non-standard keyboards need to be mapped to this model in some |
* logical way. Scancodes are mapped to keycodes with a scanmap. |
* |
* For easier mapping to the model and to emphasize the nature of keycodes, |
* they really are organized here by position, rather than by label. |
*/ |
enum keycode { |
/* Main block row 1 */ |
KC_BACKTICK = 1, |
KC_1, |
KC_2, |
KC_3, |
KC_4, |
KC_5, |
KC_6, |
KC_7, |
KC_8, |
KC_9, |
KC_0, |
KC_MINUS, |
KC_EQUALS, |
KC_BACKSPACE, |
/* Main block row 2 */ |
KC_TAB, |
KC_Q, |
KC_W, |
KC_E, |
KC_R, |
KC_T, |
KC_Y, |
KC_U, |
KC_I, |
KC_O, |
KC_P, |
KC_LBRACKET, |
KC_RBRACKET, |
/* Main block row 3 */ |
KC_CAPS_LOCK, |
KC_A, |
KC_S, |
KC_D, |
KC_F, |
KC_G, |
KC_H, |
KC_J, |
KC_K, |
KC_L, |
KC_SEMICOLON, |
KC_QUOTE, |
KC_BACKSLASH, |
KC_ENTER, |
/* Main block row 4 */ |
KC_LSHIFT, |
KC_Z, |
KC_X, |
KC_C, |
KC_V, |
KC_B, |
KC_N, |
KC_M, |
KC_COMMA, |
KC_PERIOD, |
KC_SLASH, |
KC_RSHIFT, |
/* Main block row 5 */ |
KC_LCTRL, |
KC_LALT, |
KC_SPACE, |
KC_RALT, |
KC_RCTRL, |
/* Function keys block */ |
KC_ESCAPE, |
KC_F1, |
KC_F2, |
KC_F3, |
KC_F4, |
KC_F5, |
KC_F6, |
KC_F7, |
KC_F8, |
KC_F9, |
KC_F10, |
KC_F11, |
KC_F12, |
KC_PRTSCR, |
KC_SCROLL_LOCK, |
KC_PAUSE, |
/* Cursor keys block */ |
KC_INSERT, |
KC_HOME, |
KC_PAGE_UP, |
KC_DELETE, |
KC_END, |
KC_PAGE_DOWN, |
KC_UP, |
KC_LEFT, |
KC_DOWN, |
KC_RIGHT, |
/* Numeric block */ |
KC_NUM_LOCK, |
KC_NSLASH, |
KC_NTIMES, |
KC_NMINUS, |
KC_NPLUS, |
KC_NENTER, |
KC_N7, |
KC_N8, |
KC_N9, |
KC_N4, |
KC_N5, |
KC_N6, |
KC_N1, |
KC_N2, |
KC_N3, |
KC_N0, |
KC_NPERIOD |
} keycode_t; |
enum keymod { |
KM_LSHIFT = 0x001, |
KM_RSHIFT = 0x002, |
KM_LCTRL = 0x004, |
KM_RCTRL = 0x008, |
KM_LALT = 0x010, |
KM_RALT = 0x020, |
KM_CAPS_LOCK = 0x040, |
KM_NUM_LOCK = 0x080, |
KM_SCROLL_LOCK = 0x100, |
KM_SHIFT = KM_LSHIFT | KM_RSHIFT, |
KM_CTRL = KM_LCTRL | KM_RCTRL, |
KM_ALT = KM_LALT | KM_RALT |
} keymod_t; |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/adt/hash_table.h |
---|
0,0 → 1,94 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_HASH_TABLE_H_ |
#define LIBC_HASH_TABLE_H_ |
#include <adt/list.h> |
#include <unistd.h> |
typedef unsigned long hash_count_t; |
typedef unsigned long hash_index_t; |
typedef struct hash_table hash_table_t; |
typedef struct hash_table_operations hash_table_operations_t; |
/** Hash table structure. */ |
struct hash_table { |
link_t *entry; |
hash_count_t entries; |
hash_count_t max_keys; |
hash_table_operations_t *op; |
}; |
/** Set of operations for hash table. */ |
struct hash_table_operations { |
/** Hash function. |
* |
* @param key Array of keys needed to compute hash index. All keys |
* must be passed. |
* |
* @return Index into hash table. |
*/ |
hash_index_t (* hash)(unsigned long key[]); |
/** Hash table item comparison function. |
* |
* @param key Array of keys that will be compared with item. It is |
* not necessary to pass all keys. |
* |
* @return true if the keys match, false otherwise. |
*/ |
int (*compare)(unsigned long key[], hash_count_t keys, link_t *item); |
/** Hash table item removal callback. |
* |
* @param item Item that was removed from the hash table. |
*/ |
void (*remove_callback)(link_t *item); |
}; |
#define hash_table_get_instance(item, type, member) \ |
list_get_instance((item), type, member) |
extern int hash_table_create(hash_table_t *, hash_count_t, hash_count_t, |
hash_table_operations_t *); |
extern void hash_table_insert(hash_table_t *, unsigned long [], link_t *); |
extern link_t *hash_table_find(hash_table_t *, unsigned long []); |
extern void hash_table_remove(hash_table_t *, unsigned long [], hash_count_t); |
extern void hash_table_destroy(hash_table_t *); |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/adt/list.h |
---|
0,0 → 1,201 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_LIST_H_ |
#define LIBC_LIST_H_ |
#include <unistd.h> |
/** Doubly linked list head and link type. */ |
typedef struct link { |
struct link *prev; /**< Pointer to the previous item in the list. */ |
struct link *next; /**< Pointer to the next item in the list. */ |
} link_t; |
/** Declare and initialize statically allocated list. |
* |
* @param name Name of the new statically allocated list. |
*/ |
#define LIST_INITIALIZE(name) link_t name = { \ |
.prev = &name, \ |
.next = &name \ |
} |
/** Initialize doubly-linked circular list link |
* |
* Initialize doubly-linked list link. |
* |
* @param link Pointer to link_t structure to be initialized. |
*/ |
static inline void link_initialize(link_t *link) |
{ |
link->prev = NULL; |
link->next = NULL; |
} |
/** Initialize doubly-linked circular list |
* |
* Initialize doubly-linked circular list. |
* |
* @param head Pointer to link_t structure representing head of the list. |
*/ |
static inline void list_initialize(link_t *head) |
{ |
head->prev = head; |
head->next = head; |
} |
/** Add item to the beginning of doubly-linked circular list |
* |
* Add item to the beginning of doubly-linked circular list. |
* |
* @param link Pointer to link_t structure to be added. |
* @param head Pointer to link_t structure representing head of the list. |
*/ |
static inline void list_prepend(link_t *link, link_t *head) |
{ |
link->next = head->next; |
link->prev = head; |
head->next->prev = link; |
head->next = link; |
} |
/** Add item to the end of doubly-linked circular list |
* |
* Add item to the end of doubly-linked circular list. |
* |
* @param link Pointer to link_t structure to be added. |
* @param head Pointer to link_t structure representing head of the list. |
*/ |
static inline void list_append(link_t *link, link_t *head) |
{ |
link->prev = head->prev; |
link->next = head; |
head->prev->next = link; |
head->prev = link; |
} |
/** Insert item before another item in doubly-linked circular list. */ |
static inline void list_insert_before(link_t *l, link_t *r) |
{ |
list_append(l, r); |
} |
/** Insert item after another item in doubly-linked circular list. */ |
static inline void list_insert_after(link_t *r, link_t *l) |
{ |
list_prepend(l, r); |
} |
/** Remove item from doubly-linked circular list |
* |
* Remove item from doubly-linked circular list. |
* |
* @param link Pointer to link_t structure to be removed from the list it is contained in. |
*/ |
static inline void list_remove(link_t *link) |
{ |
link->next->prev = link->prev; |
link->prev->next = link->next; |
link_initialize(link); |
} |
/** Query emptiness of doubly-linked circular list |
* |
* Query emptiness of doubly-linked circular list. |
* |
* @param head Pointer to link_t structure representing head of the list. |
*/ |
static inline int list_empty(link_t *head) |
{ |
return ((head->next == head) ? 1 : 0); |
} |
/** Split or concatenate headless doubly-linked circular list |
* |
* Split or concatenate headless doubly-linked circular list. |
* |
* Note that the algorithm works both directions: |
* concatenates splitted lists and splits concatenated lists. |
* |
* @param part1 Pointer to link_t structure leading the first (half of the headless) list. |
* @param part2 Pointer to link_t structure leading the second (half of the headless) list. |
*/ |
static inline void headless_list_split_or_concat(link_t *part1, link_t *part2) |
{ |
part1->prev->next = part2; |
part2->prev->next = part1; |
link_t *hlp = part1->prev; |
part1->prev = part2->prev; |
part2->prev = hlp; |
} |
/** Split headless doubly-linked circular list |
* |
* Split headless doubly-linked circular list. |
* |
* @param part1 Pointer to link_t structure leading the first half of the headless list. |
* @param part2 Pointer to link_t structure leading the second half of the headless list. |
*/ |
static inline void headless_list_split(link_t *part1, link_t *part2) |
{ |
headless_list_split_or_concat(part1, part2); |
} |
/** Concatenate two headless doubly-linked circular lists |
* |
* Concatenate two headless doubly-linked circular lists. |
* |
* @param part1 Pointer to link_t structure leading the first headless list. |
* @param part2 Pointer to link_t structure leading the second headless list. |
*/ |
static inline void headless_list_concat(link_t *part1, link_t *part2) |
{ |
headless_list_split_or_concat(part1, part2); |
} |
#define list_get_instance(link, type, member) ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member)))) |
extern int list_member(const link_t *link, const link_t *head); |
extern void list_concat(link_t *head1, link_t *head2); |
extern unsigned int list_count(const link_t *link); |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/adt/fifo.h |
---|
0,0 → 1,127 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
/* |
* This implementation of FIFO stores values in an array |
* (static or dynamic). As such, these FIFOs have upper bound |
* on number of values they can store. Push and pop operations |
* are done via accessing the array through head and tail indices. |
* Because of better operation ordering in fifo_pop(), the access |
* policy for these two indices is to 'increment (mod size of FIFO) |
* and use'. |
*/ |
#ifndef LIBC_FIFO_H_ |
#define LIBC_FIFO_H_ |
#include <malloc.h> |
typedef unsigned long fifo_count_t; |
typedef unsigned long fifo_index_t; |
#define FIFO_CREATE_STATIC(name, t, itms) \ |
struct { \ |
t fifo[(itms)]; \ |
fifo_count_t items; \ |
fifo_index_t head; \ |
fifo_index_t tail; \ |
} name |
/** Create and initialize static FIFO. |
* |
* FIFO is allocated statically. |
* This macro is suitable for creating smaller FIFOs. |
* |
* @param name Name of FIFO. |
* @param t Type of values stored in FIFO. |
* @param itms Number of items that can be stored in FIFO. |
*/ |
#define FIFO_INITIALIZE_STATIC(name, t, itms) \ |
FIFO_CREATE_STATIC(name, t, itms) = { \ |
.items = (itms), \ |
.head = 0, \ |
.tail = 0 \ |
} |
/** Create and prepare dynamic FIFO. |
* |
* FIFO is allocated dynamically. |
* This macro is suitable for creating larger FIFOs. |
* |
* @param name Name of FIFO. |
* @param t Type of values stored in FIFO. |
* @param itms Number of items that can be stored in FIFO. |
*/ |
#define FIFO_INITIALIZE_DYNAMIC(name, t, itms) \ |
struct { \ |
t *fifo; \ |
fifo_count_t items; \ |
fifo_index_t head; \ |
fifo_index_t tail; \ |
} name = { \ |
.fifo = NULL, \ |
.items = (itms), \ |
.head = 0, \ |
.tail = 0 \ |
} |
/** Pop value from head of FIFO. |
* |
* @param name FIFO name. |
* |
* @return Leading value in FIFO. |
*/ |
#define fifo_pop(name) \ |
name.fifo[name.head = (name.head + 1) < name.items ? (name.head + 1) : 0] |
/** Push value to tail of FIFO. |
* |
* @param name FIFO name. |
* @param value Value to be appended to FIFO. |
* |
*/ |
#define fifo_push(name, value) \ |
name.fifo[name.tail = (name.tail + 1) < name.items ? (name.tail + 1) : 0] = (value) |
/** Allocate memory for dynamic FIFO. |
* |
* @param name FIFO name. |
*/ |
#define fifo_create(name) \ |
name.fifo = malloc(sizeof(*name.fifo) * name.items) |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/macros.h |
---|
35,15 → 35,22 |
#ifndef LIBC_MACROS_H_ |
#define LIBC_MACROS_H_ |
#define SIZE2KB(size) ((size) >> 10) |
#define SIZE2MB(size) ((size) >> 20) |
#define SIZE2KB(size) ((size) >> 10) |
#define SIZE2MB(size) ((size) >> 20) |
#define KB2SIZE(kb) ((kb) << 10) |
#define MB2SIZE(mb) ((mb) << 20) |
#define KB2SIZE(kb) ((kb) << 10) |
#define MB2SIZE(mb) ((mb) << 20) |
#define STRING(arg) STRING_ARG(arg) |
#define STRING_ARG(arg) #arg |
#define STRING(arg) STRING_ARG(arg) |
#define STRING_ARG(arg) #arg |
#define LOWER32(arg) ((arg) & 0xffffffff) |
#define UPPER32(arg) (((arg) >> 32) & 0xffffffff) |
#define MERGE_LOUP32(lo, up) \ |
((((uint64_t) (lo)) & 0xffffffff) \ |
| ((((uint64_t) (up)) & 0xffffffff) << 32)) |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/ipc/ipc.h |
---|
30,21 → 30,26 |
* @{ |
*/ |
/** @file |
*/ |
*/ |
#ifndef LIBIPC_IPC_H_ |
#define LIBIPC_IPC_H_ |
#include <task.h> |
#include <kernel/ipc/ipc.h> |
#include <kernel/ddi/irq.h> |
#include <sys/types.h> |
#include <kernel/synch/synch.h> |
#define IPC_FLAG_BLOCKING 0x01 |
typedef sysarg_t ipcarg_t; |
typedef struct { |
ipcarg_t args[IPC_CALL_LEN]; |
ipcarg_t in_phone_hash; |
} ipc_call_t; |
typedef sysarg_t ipc_callid_t; |
typedef void (* ipc_async_callback_t)(void *, int, ipc_call_t *); |
56,49 → 61,51 |
* possible, the fast version is used. |
*/ |
#define ipc_call_sync_0_0(phoneid, method) \ |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0) |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0) |
#define ipc_call_sync_0_1(phoneid, method, res1) \ |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0) |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0) |
#define ipc_call_sync_0_2(phoneid, method, res1, res2) \ |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0) |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0) |
#define ipc_call_sync_0_3(phoneid, method, res1, res2, res3) \ |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \ |
0, 0) |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \ |
0, 0) |
#define ipc_call_sync_0_4(phoneid, method, res1, res2, res3, res4) \ |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \ |
(res4), 0) |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \ |
(res4), 0) |
#define ipc_call_sync_0_5(phoneid, method, res1, res2, res3, res4, res5) \ |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \ |
(res4), (res5)) |
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \ |
(res4), (res5)) |
#define ipc_call_sync_1_0(phoneid, method, arg1) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0) |
#define ipc_call_sync_1_1(phoneid, method, arg1, res1) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0) |
#define ipc_call_sync_1_2(phoneid, method, arg1, res1, res2) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \ |
0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \ |
0, 0) |
#define ipc_call_sync_1_3(phoneid, method, arg1, res1, res2, res3) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \ |
(res3), 0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \ |
(res3), 0, 0) |
#define ipc_call_sync_1_4(phoneid, method, arg1, res1, res2, res3, res4) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \ |
(res3), (res4), 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \ |
(res3), (res4), 0) |
#define ipc_call_sync_1_5(phoneid, method, arg1, res1, res2, res3, res4, \ |
res5) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \ |
(res3), (res4), (res5)) |
#define ipc_call_sync_2_0(phoneid, method, arg1, arg2) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \ |
0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \ |
0, 0) |
#define ipc_call_sync_2_1(phoneid, method, arg1, arg2, res1) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \ |
0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \ |
0, 0) |
#define ipc_call_sync_2_2(phoneid, method, arg1, arg2, res1, res2) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ |
(res2), 0, 0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ |
(res2), 0, 0, 0) |
#define ipc_call_sync_2_3(phoneid, method, arg1, arg2, res1, res2, res3) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ |
(res2), (res3), 0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ |
(res2), (res3), 0, 0) |
#define ipc_call_sync_2_4(phoneid, method, arg1, arg2, res1, res2, res3, \ |
res4) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ |
107,15 → 114,16 |
res4, res5)\ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ |
(res2), (res3), (res4), (res5)) |
#define ipc_call_sync_3_0(phoneid, method, arg1, arg2, arg3) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \ |
0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \ |
0, 0) |
#define ipc_call_sync_3_1(phoneid, method, arg1, arg2, arg3, res1) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \ |
0, 0, 0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \ |
0, 0, 0, 0) |
#define ipc_call_sync_3_2(phoneid, method, arg1, arg2, arg3, res1, res2) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \ |
(res2), 0, 0, 0) |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \ |
(res2), 0, 0, 0) |
#define ipc_call_sync_3_3(phoneid, method, arg1, arg2, arg3, res1, res2, \ |
res3) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \ |
128,15 → 136,16 |
res3, res4, res5) \ |
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \ |
(res1), (res2), (res3), (res4), (res5)) |
#define ipc_call_sync_4_0(phoneid, method, arg1, arg2, arg3, arg4) \ |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \ |
0, 0, 0, 0, 0) |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \ |
0, 0, 0, 0, 0) |
#define ipc_call_sync_4_1(phoneid, method, arg1, arg2, arg3, arg4, res1) \ |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \ |
(res1), 0, 0, 0, 0) |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \ |
(res1), 0, 0, 0, 0) |
#define ipc_call_sync_4_2(phoneid, method, arg1, arg2, arg3, arg4, res1, res2) \ |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \ |
(res1), (res2), 0, 0, 0) |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \ |
(res1), (res2), 0, 0, 0) |
#define ipc_call_sync_4_3(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \ |
res3) \ |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ |
149,12 → 158,13 |
res3, res4, res5) \ |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ |
(arg4), 0, (res1), (res2), (res3), (res4), (res5)) |
#define ipc_call_sync_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \ |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), 0, 0, 0, 0, 0) |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), 0, 0, 0, 0, 0) |
#define ipc_call_sync_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1) \ |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (res1), 0, 0, 0, 0) |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (res1), 0, 0, 0, 0) |
#define ipc_call_sync_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \ |
res2) \ |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ |
181,10 → 191,12 |
extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int); |
extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t); |
static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data) |
{ |
return ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT); |
} |
extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *); |
/* |
194,17 → 206,17 |
* to m. |
*/ |
#define ipc_answer_0(callid, retval) \ |
ipc_answer_fast((callid), (retval), 0, 0, 0, 0) |
ipc_answer_fast((callid), (retval), 0, 0, 0, 0) |
#define ipc_answer_1(callid, retval, arg1) \ |
ipc_answer_fast((callid), (retval), (arg1), 0, 0, 0) |
ipc_answer_fast((callid), (retval), (arg1), 0, 0, 0) |
#define ipc_answer_2(callid, retval, arg1, arg2) \ |
ipc_answer_fast((callid), (retval), (arg1), (arg2), 0, 0) |
ipc_answer_fast((callid), (retval), (arg1), (arg2), 0, 0) |
#define ipc_answer_3(callid, retval, arg1, arg2, arg3) \ |
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), 0) |
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), 0) |
#define ipc_answer_4(callid, retval, arg1, arg2, arg3, arg4) \ |
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), (arg4)) |
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), (arg4)) |
#define ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5) \ |
ipc_answer_slow((callid), (retval), (arg1), (arg2), (arg3), (arg4), (arg5)) |
ipc_answer_slow((callid), (retval), (arg1), (arg2), (arg3), (arg4), (arg5)) |
extern ipcarg_t ipc_answer_fast(ipc_callid_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t); |
246,8 → 258,6 |
extern void ipc_call_async_slow(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, void *, ipc_async_callback_t, int); |
#define IPC_FLAG_BLOCKING 0x01 |
extern int ipc_connect_to_me(int, int, int, int, ipcarg_t *); |
extern int ipc_connect_me_to(int, int, int, int); |
extern int ipc_connect_me_to_blocking(int, int, int, int); |
256,20 → 266,19 |
extern int ipc_unregister_irq(int, int); |
extern int ipc_forward_fast(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, int); |
extern int ipc_forward_slow(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, ipcarg_t, int); |
ipcarg_t, ipcarg_t, ipcarg_t, int); |
/* |
* User-friendly wrappers for ipc_share_in_start(). |
*/ |
#define ipc_share_in_start_0_0(phoneid, dst, size) \ |
ipc_share_in_start((phoneid), (dst), (size), 0, NULL) |
ipc_share_in_start((phoneid), (dst), (size), 0, NULL) |
#define ipc_share_in_start_0_1(phoneid, dst, size, flags) \ |
ipc_share_in_start((phoneid), (dst), (size), 0, (flags)) |
ipc_share_in_start((phoneid), (dst), (size), 0, (flags)) |
#define ipc_share_in_start_1_0(phoneid, dst, size, arg) \ |
ipc_share_in_start((phoneid), (dst), (size), (arg), NULL) |
ipc_share_in_start((phoneid), (dst), (size), (arg), NULL) |
#define ipc_share_in_start_1_1(phoneid, dst, size, arg, flags) \ |
ipc_share_in_start((phoneid), (dst), (size), (arg), (flags)) |
ipc_share_in_start((phoneid), (dst), (size), (arg), (flags)) |
extern int ipc_share_in_start(int, void *, size_t, ipcarg_t, int *); |
extern int ipc_share_in_receive(ipc_callid_t *, size_t *); |
284,8 → 293,6 |
extern int ipc_data_write_receive(ipc_callid_t *, size_t *); |
extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t); |
#include <task.h> |
extern int ipc_connect_kbox(task_id_t); |
#endif |
/branches/dd/uspace/lib/libc/include/ipc/devmap.h |
---|
35,7 → 35,7 |
#include <atomic.h> |
#include <ipc/ipc.h> |
#include <libadt/list.h> |
#include <adt/list.h> |
#define DEVMAP_NAME_MAXLEN 255 |
/branches/dd/uspace/lib/libc/include/ipc/vfs.h |
---|
0,0 → 1,147 |
/* |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcipc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_IPC_VFS_H_ |
#define LIBC_IPC_VFS_H_ |
#include <sys/types.h> |
#include <ipc/ipc.h> |
#define FS_NAME_MAXLEN 20 |
#define MAX_PATH_LEN (64 * 1024) |
#define PLB_SIZE (2 * MAX_PATH_LEN) |
/* Basic types. */ |
typedef int16_t fs_handle_t; |
typedef uint32_t fs_index_t; |
/** |
* A structure like this is passed to VFS by each individual FS upon its |
* registration. It assosiates a human-readable identifier with each |
* registered FS. |
*/ |
typedef struct { |
/** Unique identifier of the fs. */ |
char name[FS_NAME_MAXLEN + 1]; |
} vfs_info_t; |
typedef enum { |
VFS_OPEN_NODE = IPC_FIRST_USER_METHOD, |
VFS_READ, |
VFS_WRITE, |
VFS_TRUNCATE, |
VFS_MOUNT, |
VFS_UNMOUNT, |
VFS_DEVICE, |
VFS_SYNC, |
VFS_CLOSE, |
VFS_LAST_CMN /* keep this the last member of this enum */ |
} vfs_request_cmn_t; |
typedef enum { |
VFS_LOOKUP = VFS_LAST_CMN, |
VFS_MOUNTED, |
VFS_DESTROY, |
VFS_LAST_CLNT /* keep this the last member of this enum */ |
} vfs_request_clnt_t; |
typedef enum { |
VFS_REGISTER = VFS_LAST_CMN, |
VFS_OPEN, |
VFS_SEEK, |
VFS_MKDIR, |
VFS_UNLINK, |
VFS_RENAME, |
VFS_NODE, |
VFS_LAST_SRV /* keep this the last member of this enum */ |
} vfs_request_srv_t; |
/* |
* Lookup flags. |
*/ |
/** |
* No lookup flags used. |
*/ |
#define L_NONE 0 |
/** |
* Lookup will succeed only if the object is a regular file. If L_CREATE is |
* specified, an empty file will be created. This flag is mutually exclusive |
* with L_DIRECTORY. |
*/ |
#define L_FILE 1 |
/** |
* Lookup wil succeed only if the object is a directory. If L_CREATE is |
* specified, an empty directory will be created. This flag is mutually |
* exclusive with L_FILE. |
*/ |
#define L_DIRECTORY 2 |
/** |
* When used with L_CREATE, L_EXCLUSIVE will cause the lookup to fail if the |
* object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used. |
*/ |
#define L_EXCLUSIVE 4 |
/** |
* L_CREATE is used for creating both regular files and directories. |
*/ |
#define L_CREATE 8 |
/** |
* L_LINK is used for linking to an already existing nodes. |
*/ |
#define L_LINK 16 |
/** |
* L_UNLINK is used to remove leaves from the file system namespace. This flag |
* cannot be passed directly by the client, but will be set by VFS during |
* VFS_UNLINK. |
*/ |
#define L_UNLINK 32 |
/** |
* L_OPEN is used to indicate that the lookup operation is a part of VFS_OPEN |
* call from the client. This means that the server might allocate some |
* resources for the opened file. This flag cannot be passed directly by the |
* client. |
*/ |
#define L_OPEN 64 |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/ipc/ns.h |
---|
35,6 → 35,13 |
#ifndef LIBIPC_NS_H_ |
#define LIBIPC_NS_H_ |
#include <ipc/ipc.h> |
typedef enum { |
NS_PING = IPC_FIRST_USER_METHOD, |
NS_TASK_WAIT |
} ns_request_t; |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/ipc/console.h |
---|
27,7 → 27,7 |
*/ |
/** @addtogroup libcipc |
* @{ |
* @{ |
*/ |
/** @file |
*/ |
36,15 → 36,13 |
#define LIBC_IPC_CONSOLE_H_ |
#include <ipc/ipc.h> |
#include <ipc/vfs.h> |
typedef enum { |
CONSOLE_GETKEY = IPC_FIRST_USER_METHOD, |
CONSOLE_PUTCHAR, |
CONSOLE_WRITE, |
CONSOLE_GET_SIZE = VFS_LAST_SRV, |
CONSOLE_GET_EVENT, |
CONSOLE_GOTO, |
CONSOLE_CLEAR, |
CONSOLE_GOTO, |
CONSOLE_GETSIZE, |
CONSOLE_FLUSH, |
CONSOLE_SET_STYLE, |
CONSOLE_SET_COLOR, |
CONSOLE_SET_RGB_COLOR, |
53,6 → 51,6 |
} console_request_t; |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/ipc/loader.h |
---|
42,6 → 42,7 |
LOADER_GET_TASKID, |
LOADER_SET_PATHNAME, |
LOADER_SET_ARGS, |
LOADER_SET_FILES, |
LOADER_LOAD, |
LOADER_RUN |
} loader_request_t; |
/branches/dd/uspace/lib/libc/include/errno.h |
---|
41,17 → 41,18 |
#include <kernel/errno.h> |
#define ENAMETOOLONG (-256) |
#define EISDIR (-257) |
#define ENOTDIR (-258) |
#define ENOSPC (-259) |
#define EEXIST (-260) |
#define ENOTEMPTY (-261) |
#define EBADF (-262) |
#define ERANGE (-263) |
#define EXDEV (-264) |
#define EIO (-265) |
#define EMLINK (-266) |
#define EMFILE (-17) |
#define ENAMETOOLONG (-256) |
#define EISDIR (-257) |
#define ENOTDIR (-258) |
#define ENOSPC (-259) |
#define EEXIST (-260) |
#define ENOTEMPTY (-261) |
#define EBADF (-262) |
#define ERANGE (-263) |
#define EXDEV (-264) |
#define EIO (-265) |
#define EMLINK (-266) |
#endif |
/branches/dd/uspace/lib/libc/Makefile.toolchain |
---|
26,10 → 26,10 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
CFLAGS = -fno-builtin -Wall -Werror-implicit-function-declaration \ |
CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \ |
-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32 -finput-charset=UTF-8 \ |
-Wmissing-prototypes -O3 -nostdlib -nostdinc -imacros \ |
$(LIBC_PREFIX)/../../../config.h -I$(LIBC_PREFIX)/include -pipe -g |
-fno-builtin -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \ |
-Werror-implicit-function-declaration -nostdlib -nostdinc -pipe -g |
LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS = |
/branches/dd/uspace/lib/libc/generic/kbd.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/libadt/hash_table.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/libadt/list.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/console.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/ddi.c |
---|
127,7 → 127,7 |
} |
#endif |
phys = ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE); |
phys = (void *) ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE); |
offset = pio_addr - phys; |
pages = ALIGN_UP(offset + size, PAGE_SIZE) >> PAGE_WIDTH; |
virt = as_get_mappable_page(pages << PAGE_WIDTH); |
/branches/dd/uspace/lib/libc/generic/task.c |
---|
31,7 → 31,7 |
* @{ |
*/ |
/** @file |
*/ |
*/ |
#include <task.h> |
#include <libc.h> |
39,21 → 39,25 |
#include <errno.h> |
#include <loader/loader.h> |
#include <string.h> |
#include <ipc/ns.h> |
#include <macros.h> |
#include <async.h> |
task_id_t task_get_id(void) |
{ |
task_id_t task_id; |
(void) __SYSCALL1(SYS_TASK_GET_ID, (sysarg_t) &task_id); |
return task_id; |
} |
/** Set the task name. |
* |
* @param name The new name, typically the command used to execute the |
* program. |
* @return Zero on success or negative error code. |
* @param name The new name, typically the command used to execute the |
* program. |
* |
* @return Zero on success or negative error code. |
* |
*/ |
int task_set_name(const char *name) |
{ |
65,58 → 69,89 |
* This is really just a convenience wrapper over the more complicated |
* loader API. |
* |
* @param path pathname of the binary to execute |
* @param argv command-line arguments |
* @return ID of the newly created task or zero on error. |
* @param path pathname of the binary to execute |
* @param argv command-line arguments |
* |
* @return ID of the newly created task or zero on error. |
* |
*/ |
task_id_t task_spawn(const char *path, char *const argv[]) |
task_id_t task_spawn(const char *path, char *const args[]) |
{ |
loader_t *ldr; |
task_id_t task_id; |
int rc; |
/* Connect to a program loader. */ |
ldr = loader_connect(); |
loader_t *ldr = loader_connect(); |
if (ldr == NULL) |
return 0; |
/* Get task ID. */ |
rc = loader_get_task_id(ldr, &task_id); |
task_id_t task_id; |
int rc = loader_get_task_id(ldr, &task_id); |
if (rc != EOK) |
goto error; |
/* Send program pathname. */ |
rc = loader_set_pathname(ldr, path); |
if (rc != EOK) |
goto error; |
/* Send arguments. */ |
rc = loader_set_args(ldr, argv); |
rc = loader_set_args(ldr, args); |
if (rc != EOK) |
goto error; |
/* Send default files */ |
fdi_node_t *files[4]; |
fdi_node_t stdin_node; |
fdi_node_t stdout_node; |
fdi_node_t stderr_node; |
if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK)) |
files[0] = &stdin_node; |
else |
files[0] = NULL; |
if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK)) |
files[1] = &stdout_node; |
else |
files[1] = NULL; |
if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK)) |
files[2] = &stderr_node; |
else |
files[2] = NULL; |
files[3] = NULL; |
rc = loader_set_files(ldr, files); |
if (rc != EOK) |
goto error; |
/* Load the program. */ |
rc = loader_load_program(ldr); |
if (rc != EOK) |
goto error; |
/* Run it. */ |
rc = loader_run(ldr); |
if (rc != EOK) |
goto error; |
/* Success */ |
free(ldr); |
return task_id; |
error: |
/* Error exit */ |
error: |
loader_abort(ldr); |
free(ldr); |
return 0; |
} |
int task_wait(task_id_t id) |
{ |
return (int) async_req_2_0(PHONE_NS, NS_TASK_WAIT, LOWER32(id), UPPER32(id)); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/fibril_sync.c |
---|
0,0 → 1,219 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#include <fibril_sync.h> |
#include <fibril.h> |
#include <async.h> |
#include <adt/list.h> |
#include <futex.h> |
#include <assert.h> |
void fibril_mutex_initialize(fibril_mutex_t *fm) |
{ |
fm->counter = 1; |
list_initialize(&fm->waiters); |
} |
void fibril_mutex_lock(fibril_mutex_t *fm) |
{ |
futex_down(&async_futex); |
if (fm->counter-- <= 0) { |
fibril_t *f = (fibril_t *) fibril_get_id(); |
list_append(&f->link, &fm->waiters); |
fibril_switch(FIBRIL_TO_MANAGER); |
} else { |
futex_up(&async_futex); |
} |
} |
bool fibril_mutex_trylock(fibril_mutex_t *fm) |
{ |
bool locked = false; |
futex_down(&async_futex); |
if (fm->counter > 0) { |
fm->counter--; |
locked = true; |
} |
futex_up(&async_futex); |
return locked; |
} |
static void _fibril_mutex_unlock_unsafe(fibril_mutex_t *fm) |
{ |
assert(fm->counter <= 0); |
if (fm->counter++ < 0) { |
link_t *tmp; |
fibril_t *f; |
assert(!list_empty(&fm->waiters)); |
tmp = fm->waiters.next; |
f = list_get_instance(tmp, fibril_t, link); |
list_remove(&f->link); |
fibril_add_ready((fid_t) f); |
} |
} |
void fibril_mutex_unlock(fibril_mutex_t *fm) |
{ |
futex_down(&async_futex); |
_fibril_mutex_unlock_unsafe(fm); |
futex_up(&async_futex); |
} |
void fibril_rwlock_initialize(fibril_rwlock_t *frw) |
{ |
frw->writers = 0; |
frw->readers = 0; |
list_initialize(&frw->waiters); |
} |
void fibril_rwlock_read_lock(fibril_rwlock_t *frw) |
{ |
futex_down(&async_futex); |
if (frw->writers) { |
fibril_t *f = (fibril_t *) fibril_get_id(); |
f->flags &= ~FIBRIL_WRITER; |
list_append(&f->link, &frw->waiters); |
fibril_switch(FIBRIL_TO_MANAGER); |
} else { |
frw->readers++; |
futex_up(&async_futex); |
} |
} |
void fibril_rwlock_write_lock(fibril_rwlock_t *frw) |
{ |
futex_down(&async_futex); |
if (frw->writers || frw->readers) { |
fibril_t *f = (fibril_t *) fibril_get_id(); |
f->flags |= FIBRIL_WRITER; |
list_append(&f->link, &frw->waiters); |
fibril_switch(FIBRIL_TO_MANAGER); |
} else { |
frw->writers++; |
futex_up(&async_futex); |
} |
} |
static void _fibril_rwlock_common_unlock(fibril_rwlock_t *frw) |
{ |
futex_down(&async_futex); |
assert(frw->readers || (frw->writers == 1)); |
if (frw->readers) { |
if (--frw->readers) |
goto out; |
} else { |
frw->writers--; |
} |
assert(!frw->readers && !frw->writers); |
while (!list_empty(&frw->waiters)) { |
link_t *tmp = frw->waiters.next; |
fibril_t *f = list_get_instance(tmp, fibril_t, link); |
if (f->flags & FIBRIL_WRITER) { |
if (frw->readers) |
break; |
list_remove(&f->link); |
fibril_add_ready((fid_t) f); |
frw->writers++; |
break; |
} else { |
list_remove(&f->link); |
fibril_add_ready((fid_t) f); |
frw->readers++; |
} |
} |
out: |
futex_up(&async_futex); |
} |
void fibril_rwlock_read_unlock(fibril_rwlock_t *frw) |
{ |
_fibril_rwlock_common_unlock(frw); |
} |
void fibril_rwlock_write_unlock(fibril_rwlock_t *frw) |
{ |
_fibril_rwlock_common_unlock(frw); |
} |
void fibril_condvar_initialize(fibril_condvar_t *fcv) |
{ |
list_initialize(&fcv->waiters); |
} |
void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm) |
{ |
fibril_t *f = (fibril_t *) fibril_get_id(); |
futex_down(&async_futex); |
list_append(&f->link, &fcv->waiters); |
_fibril_mutex_unlock_unsafe(fm); |
fibril_switch(FIBRIL_TO_MANAGER); |
fibril_mutex_lock(fm); |
} |
static void _fibril_condvar_wakeup_common(fibril_condvar_t *fcv, bool once) |
{ |
link_t *tmp; |
fibril_t *f; |
futex_down(&async_futex); |
while (!list_empty(&fcv->waiters)) { |
tmp = fcv->waiters.next; |
f = list_get_instance(tmp, fibril_t, link); |
list_remove(&f->link); |
fibril_add_ready((fid_t) f); |
if (once) |
break; |
} |
futex_up(&async_futex); |
} |
void fibril_condvar_signal(fibril_condvar_t *fcv) |
{ |
_fibril_condvar_wakeup_common(fcv, true); |
} |
void fibril_condvar_broadcast(fibril_condvar_t *fcv) |
{ |
_fibril_condvar_wakeup_common(fcv, false); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/as.c |
---|
30,7 → 30,7 |
* @{ |
*/ |
/** @file |
*/ |
*/ |
#include <as.h> |
#include <libc.h> |
102,7 → 102,7 |
static size_t heapsize = 0; |
static size_t maxheapsize = (size_t) (-1); |
static void * last_allocated = 0; |
static void *last_allocated = 0; |
/* Start of heap linker symbol */ |
extern char _heap; |
119,15 → 119,15 |
void *res; |
/* Check for invalid values */ |
if (incr < 0 && -incr > heapsize) |
if ((incr < 0) && (((size_t) -incr) > heapsize)) |
return NULL; |
/* Check for too large value */ |
if (incr > 0 && incr+heapsize < heapsize) |
if ((incr > 0) && (incr + heapsize < heapsize)) |
return NULL; |
/* Check for too small values */ |
if (incr < 0 && incr+heapsize > heapsize) |
if ((incr < 0) && (incr + heapsize > heapsize)) |
return NULL; |
/* Check for user limit */ |
175,7 → 175,7 |
asz = 1 << (fnzb64(sz - 1) + 1); |
/* Set heapsize to some meaningful value */ |
if (maxheapsize == -1) |
if (maxheapsize == (size_t) -1) |
set_maxheapsize(MAX_HEAP_SIZE); |
/* |
/branches/dd/uspace/lib/libc/generic/string.c |
---|
138,8 → 138,8 |
* @param size Size of the output buffer (in bytes). |
* |
* @return EOK if the character was encoded successfully, EOVERFLOW if there |
* was not enough space in the output buffer or EINVAL if the character |
* code was invalid. |
* was not enough space in the output buffer or EINVAL if the character |
* code was invalid. |
*/ |
int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size) |
{ |
243,9 → 243,9 |
* @return Number of bytes used by the characters. |
* |
*/ |
size_t str_lsize(const char *str, count_t max_len) |
size_t str_lsize(const char *str, size_t max_len) |
{ |
count_t len = 0; |
size_t len = 0; |
size_t offset = 0; |
while (len < max_len) { |
271,7 → 271,7 |
* @return Number of bytes used by the wide characters. |
* |
*/ |
size_t wstr_lsize(const wchar_t *str, count_t max_len) |
size_t wstr_lsize(const wchar_t *str, size_t max_len) |
{ |
return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t)); |
} |
283,9 → 283,9 |
* @return Number of characters in string. |
* |
*/ |
count_t str_length(const char *str) |
size_t str_length(const char *str) |
{ |
count_t len = 0; |
size_t len = 0; |
size_t offset = 0; |
while (str_decode(str, &offset, STR_NO_LIMIT) != 0) |
301,9 → 301,9 |
* @return Number of characters in @a str. |
* |
*/ |
count_t wstr_length(const wchar_t *wstr) |
size_t wstr_length(const wchar_t *wstr) |
{ |
count_t len = 0; |
size_t len = 0; |
while (*wstr++ != 0) |
len++; |
319,9 → 319,9 |
* @return Number of characters in string. |
* |
*/ |
count_t str_nlength(const char *str, size_t size) |
size_t str_nlength(const char *str, size_t size) |
{ |
count_t len = 0; |
size_t len = 0; |
size_t offset = 0; |
while (str_decode(str, &offset, size) != 0) |
338,11 → 338,11 |
* @return Number of characters in string. |
* |
*/ |
count_t wstr_nlength(const wchar_t *str, size_t size) |
size_t wstr_nlength(const wchar_t *str, size_t size) |
{ |
count_t len = 0; |
count_t limit = ALIGN_DOWN(size, sizeof(wchar_t)); |
count_t offset = 0; |
size_t len = 0; |
size_t limit = ALIGN_DOWN(size, sizeof(wchar_t)); |
size_t offset = 0; |
while ((offset < limit) && (*str++ != 0)) { |
len++; |
430,7 → 430,7 |
* 1 if second smaller. |
* |
*/ |
int str_lcmp(const char *s1, const char *s2, count_t max_len) |
int str_lcmp(const char *s1, const char *s2, size_t max_len) |
{ |
wchar_t c1 = 0; |
wchar_t c2 = 0; |
438,7 → 438,7 |
size_t off1 = 0; |
size_t off2 = 0; |
count_t len = 0; |
size_t len = 0; |
while (true) { |
if (len >= max_len) |
568,7 → 568,7 |
return; |
wchar_t ch; |
count_t src_idx = 0; |
size_t src_idx = 0; |
size_t dst_off = 0; |
while ((ch = src[src_idx++]) != 0) { |
616,7 → 616,7 |
wchar_t acc; |
size_t off = 0; |
size_t last = 0; |
char *res = NULL; |
const char *res = NULL; |
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
if (acc == ch) |
641,14 → 641,14 |
* is out of bounds. |
* |
*/ |
bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos) |
bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos) |
{ |
count_t len = wstr_length(str); |
size_t len = wstr_length(str); |
if ((pos > len) || (pos + 1 > max_pos)) |
return false; |
count_t i; |
size_t i; |
for (i = len; i + 1 > pos; i--) |
str[i + 1] = str[i]; |
669,14 → 669,14 |
* is out of bounds. |
* |
*/ |
bool wstr_remove(wchar_t *str, count_t pos) |
bool wstr_remove(wchar_t *str, size_t pos) |
{ |
count_t len = wstr_length(str); |
size_t len = wstr_length(str); |
if (pos >= len) |
return false; |
count_t i; |
size_t i; |
for (i = pos + 1; i <= len; i++) |
str[i - 1] = str[i]; |
/branches/dd/uspace/lib/libc/generic/loader.c |
---|
30,7 → 30,7 |
* @{ |
*/ |
/** @file |
*/ |
*/ |
#include <ipc/ipc.h> |
#include <ipc/loader.h> |
47,9 → 47,12 |
/** Connect to a new program loader. |
* |
* Spawns a new program loader task and returns the connection structure. |
* @param name Symbolic name to set on the newly created task. |
* @return Pointer to the loader connection structure (should be |
* de-allocated using free() after use). |
* |
* @param name Symbolic name to set on the newly created task. |
* |
* @return Pointer to the loader connection structure (should be |
* deallocated using free() after use). |
* |
*/ |
int loader_spawn(const char *name) |
{ |
59,19 → 62,16 |
loader_t *loader_connect(void) |
{ |
loader_t *ldr; |
int phone_id; |
phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0); |
int phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0); |
if (phone_id < 0) |
return NULL; |
ldr = malloc(sizeof(loader_t)); |
loader_t *ldr = malloc(sizeof(loader_t)); |
if (ldr == NULL) |
return NULL; |
ldr->phone_id = phone_id; |
return ldr; |
return ldr; |
} |
/** Get ID of the new task. |
78,27 → 78,26 |
* |
* Retrieves the ID of the new task from the loader. |
* |
* @param ldr Loader connection structure. |
* @param task_id Points to a variable where the ID should be stored. |
* @return Zero on success or negative error code. |
* @param ldr Loader connection structure. |
* @param task_id Points to a variable where the ID should be stored. |
* |
* @return Zero on success or negative error code. |
* |
*/ |
int loader_get_task_id(loader_t *ldr, task_id_t *task_id) |
{ |
/* Get task ID. */ |
ipc_call_t answer; |
aid_t req; |
int rc; |
ipcarg_t retval; |
/* Get task ID. */ |
req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer); |
rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); |
aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer); |
int rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
return rc; |
} |
ipcarg_t retval; |
async_wait_for(req, &retval); |
return (int)retval; |
return (int) retval; |
} |
/** Set pathname of the program to load. |
107,39 → 106,35 |
* to the current working directory (it will be absolutized before |
* sending to the loader). |
* |
* @param ldr Loader connection structure. |
* @param path Pathname of the program file. |
* @return Zero on success or negative error code. |
* @param ldr Loader connection structure. |
* @param path Pathname of the program file. |
* |
* @return Zero on success or negative error code. |
* |
*/ |
int loader_set_pathname(loader_t *ldr, const char *path) |
{ |
ipc_call_t answer; |
aid_t req; |
int rc; |
ipcarg_t retval; |
char *pa; |
size_t pa_len; |
pa = absolutize(path, &pa_len); |
char *pa = absolutize(path, &pa_len); |
if (!pa) |
return 0; |
/* Send program pathname */ |
req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer); |
rc = ipc_data_write_start(ldr->phone_id, (void *)pa, pa_len); |
ipc_call_t answer; |
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer); |
int rc = ipc_data_write_start(ldr->phone_id, (void *) pa, pa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
return rc; |
} |
free(pa); |
ipcarg_t retval; |
async_wait_for(req, &retval); |
return (int)retval; |
return (int) retval; |
} |
/** Set command-line arguments for the program. |
* |
* Sets the vector of command-line arguments to be passed to the loaded |
146,61 → 141,110 |
* program. By convention, the very first argument is typically the same as |
* the command used to execute the program. |
* |
* @param ldr Loader connection structure. |
* @param argv NULL-terminated array of pointers to arguments. |
* @return Zero on success or negative error code. |
* @param ldr Loader connection structure. |
* @param argv NULL-terminated array of pointers to arguments. |
* |
* @return Zero on success or negative error code. |
* |
*/ |
int loader_set_args(loader_t *ldr, char *const argv[]) |
{ |
aid_t req; |
ipc_call_t answer; |
ipcarg_t rc; |
char *const *ap; |
char *dp; |
char *arg_buf; |
size_t buffer_size; |
/* |
/* |
* Serialize the arguments into a single array. First |
* compute size of the buffer needed. |
*/ |
ap = argv; |
buffer_size = 0; |
char *const *ap = argv; |
size_t buffer_size = 0; |
while (*ap != NULL) { |
buffer_size += str_size(*ap) + 1; |
++ap; |
ap++; |
} |
arg_buf = malloc(buffer_size); |
if (arg_buf == NULL) return ENOMEM; |
char *arg_buf = malloc(buffer_size); |
if (arg_buf == NULL) |
return ENOMEM; |
/* Now fill the buffer with null-terminated argument strings */ |
ap = argv; |
dp = arg_buf; |
char *dp = arg_buf; |
while (*ap != NULL) { |
str_cpy(dp, buffer_size - (dp - arg_buf), *ap); |
dp += str_size(*ap) + 1; |
++ap; |
ap++; |
} |
/* Send serialized arguments to the loader */ |
req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer); |
rc = ipc_data_write_start(ldr->phone_id, (void *)arg_buf, buffer_size); |
ipc_call_t answer; |
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer); |
ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
return rc; |
} |
async_wait_for(req, &rc); |
if (rc != EOK) return rc; |
if (rc != EOK) |
return rc; |
/* Free temporary buffer */ |
free(arg_buf); |
return EOK; |
} |
/** Set preset files for the program. |
* |
* Sets the vector of preset files to be passed to the loaded |
* program. By convention, the first three files represent stdin, |
* stdout and stderr respectively. |
* |
* @param ldr Loader connection structure. |
* @param files NULL-terminated array of pointers to files. |
* |
* @return Zero on success or negative error code. |
* |
*/ |
int loader_set_files(loader_t *ldr, fdi_node_t *const files[]) |
{ |
/* |
* Serialize the arguments into a single array. First |
* compute size of the buffer needed. |
*/ |
fdi_node_t *const *ap = files; |
size_t count = 0; |
while (*ap != NULL) { |
count++; |
ap++; |
} |
fdi_node_t *files_buf; |
files_buf = (fdi_node_t *) malloc(count * sizeof(fdi_node_t)); |
if (files_buf == NULL) |
return ENOMEM; |
/* Fill the buffer */ |
size_t i; |
for (i = 0; i < count; i++) |
files_buf[i] = *files[i]; |
/* Send serialized files to the loader */ |
ipc_call_t answer; |
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer); |
ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) files_buf, |
count * sizeof(fdi_node_t)); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
return rc; |
} |
async_wait_for(req, &rc); |
if (rc != EOK) |
return rc; |
/* Free temporary buffer */ |
free(files_buf); |
return EOK; |
} |
209,18 → 253,14 |
* If this function succeeds, the program has been successfully loaded |
* and is ready to be executed. |
* |
* @param ldr Loader connection structure. |
* @return Zero on success or negative error code. |
* @param ldr Loader connection structure. |
* |
* @return Zero on success or negative error code. |
* |
*/ |
int loader_load_program(loader_t *ldr) |
{ |
int rc; |
rc = async_req_0_0(ldr->phone_id, LOADER_LOAD); |
if (rc != EOK) |
return rc; |
return EOK; |
return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD); |
} |
/** Instruct loader to execute the program. |
232,17 → 272,17 |
* After using this function, no further operations must be performed |
* on the loader structure. It should be de-allocated using free(). |
* |
* @param ldr Loader connection structure. |
* @return Zero on success or negative error code. |
* @param ldr Loader connection structure. |
* |
* @return Zero on success or negative error code. |
* |
*/ |
int loader_run(loader_t *ldr) |
{ |
int rc; |
rc = async_req_0_0(ldr->phone_id, LOADER_RUN); |
int rc = async_req_0_0(ldr->phone_id, LOADER_RUN); |
if (rc != EOK) |
return rc; |
ipc_hangup(ldr->phone_id); |
ldr->phone_id = 0; |
return EOK; |
254,8 → 294,10 |
* After using this function, no further operations must be performed |
* on the loader structure. It should be de-allocated using free(). |
* |
* @param ldr Loader connection structure. |
* @return Zero on success or negative error code. |
* @param ldr Loader connection structure. |
* |
* @return Zero on success or negative error code. |
* |
*/ |
void loader_abort(loader_t *ldr) |
{ |
/branches/dd/uspace/lib/libc/generic/fibril.c |
---|
33,7 → 33,7 |
/** @file |
*/ |
#include <libadt/list.h> |
#include <adt/list.h> |
#include <fibril.h> |
#include <thread.h> |
#include <tls.h> |
49,7 → 49,8 |
#define FIBRIL_INITIAL_STACK_PAGES_NO 1 |
#endif |
/** This futex serializes access to ready_list, serialized_list and manage_list. |
/** |
* This futex serializes access to ready_list, serialized_list and manager_list. |
*/ |
static atomic_t fibril_futex = FUTEX_INITIALIZER; |
59,12 → 60,12 |
static void fibril_main(void); |
/** Number of fibrils that are in async_serialized mode */ |
static int serialized_fibrils; /* Protected by async_futex */ |
/** Thread-local count of serialization. If >0, we must not preempt */ |
static __thread int serialization_count; |
/** Counter for fibrils residing in async_manager */ |
static int fibrils_in_manager; |
/** Number of threads that are executing a manager fibril. */ |
static int threads_in_manager; |
/** Number of threads that are executing a manager fibril and are serialized. */ |
static int serialized_threads; /* Protected by async_futex */ |
/** Fibril-local count of serialization. If > 0, we must not preempt */ |
static fibril_local int serialization_count; |
/** Setup fibril information into TCB structure */ |
fibril_t *fibril_setup(void) |
143,11 → 144,11 |
if (list_empty(&ready_list) && list_empty(&serialized_list)) |
goto ret_0; |
/* |
* Do not preempt if there is not sufficient count of fibril |
* managers. |
* Do not preempt if there is not enough threads to run the |
* ready fibrils which are not serialized. |
*/ |
if (list_empty(&serialized_list) && |
fibrils_in_manager <= serialized_fibrils) { |
threads_in_manager <= serialized_threads) { |
goto ret_0; |
} |
} |
194,7 → 195,7 |
list_append(&srcf->link, &ready_list); |
else if (stype == FIBRIL_FROM_MANAGER) { |
list_append(&srcf->link, &manager_list); |
fibrils_in_manager--; |
threads_in_manager--; |
} else { |
/* |
* If stype == FIBRIL_TO_MANAGER, don't put ourselves to |
208,10 → 209,10 |
if (stype == FIBRIL_TO_MANAGER || stype == FIBRIL_FROM_DEAD) { |
dstf = list_get_instance(manager_list.next, fibril_t, link); |
if (serialization_count && stype == FIBRIL_TO_MANAGER) { |
serialized_fibrils++; |
serialized_threads++; |
srcf->flags |= FIBRIL_SERIALIZED; |
} |
fibrils_in_manager++; |
threads_in_manager++; |
if (stype == FIBRIL_FROM_DEAD) |
dstf->clean_after_me = srcf; |
219,7 → 220,7 |
if (!list_empty(&serialized_list)) { |
dstf = list_get_instance(serialized_list.next, fibril_t, |
link); |
serialized_fibrils--; |
serialized_threads--; |
} else { |
dstf = list_get_instance(ready_list.next, fibril_t, |
link); |
269,7 → 270,7 |
/** Add a fibril to the ready list. |
* |
* @param fid Pinter to the fibril structure of the fibril to be |
* @param fid Pointer to the fibril structure of the fibril to be |
* added. |
*/ |
void fibril_add_ready(fid_t fid) |
287,7 → 288,8 |
/** Add a fibril to the manager list. |
* |
* @param fid Pinter to the fibril structure of the fibril to be added. |
* @param fid Pointer to the fibril structure of the fibril to be |
* added. |
*/ |
void fibril_add_manager(fid_t fid) |
{ |
314,7 → 316,8 |
/** Return fibril id of the currently running fibril. |
* |
* @return Fibril ID of the currently running pseudo thread. |
* @return fibril ID of the currently running fibril. |
* |
*/ |
fid_t fibril_get_id(void) |
{ |
321,13 → 324,14 |
return (fid_t) __tcb_get()->fibril_data; |
} |
/** Disable preemption |
/** Disable preemption |
* |
* If the fibril wants to send several message in a row and does not want to be |
* preempted, it should start async_serialize_start() in the beginning of |
* communication and async_serialize_end() in the end. If it is a true |
* multithreaded application, it should protect the communication channel by a |
* futex as well. Interrupt messages can still be preempted. |
* futex as well. |
* |
*/ |
void fibril_inc_sercount(void) |
{ |
/branches/dd/uspace/lib/libc/generic/libc.c |
---|
27,28 → 27,29 |
*/ |
/** @addtogroup lc Libc |
* @brief HelenOS C library |
* @brief HelenOS C library |
* @{ |
* @} |
*/ |
/** @addtogroup libc generic |
* @ingroup lc |
* @{ |
*/ |
/** @file |
*/ |
*/ |
#include <libc.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <malloc.h> |
#include <tls.h> |
#include <thread.h> |
#include <fibril.h> |
#include <io/stream.h> |
#include <ipc/ipc.h> |
#include <async.h> |
#include <as.h> |
#include <console.h> |
#include <loader/pcb.h> |
extern char _heap; |
63,28 → 64,30 |
void __main(void *pcb_ptr) |
{ |
fibril_t *f; |
int argc; |
char **argv; |
(void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ); |
_async_init(); |
f = fibril_setup(); |
__tcb_set(f->tcb); |
fibril_t *fibril = fibril_setup(); |
__tcb_set(fibril->tcb); |
/* Save the PCB pointer */ |
__pcb = (pcb_t *)pcb_ptr; |
__pcb = (pcb_t *) pcb_ptr; |
int argc; |
char **argv; |
if (__pcb == NULL) { |
argc = 0; |
argv = NULL; |
stdio_init(0, NULL); |
} else { |
argc = __pcb->argc; |
argv = __pcb->argv; |
stdio_init(__pcb->filc, __pcb->filv); |
} |
main(argc, argv); |
console_flush(); |
stdio_done(); |
} |
void __exit(void) |
/branches/dd/uspace/lib/libc/generic/ipc.c |
---|
43,7 → 43,7 |
#include <libc.h> |
#include <malloc.h> |
#include <errno.h> |
#include <libadt/list.h> |
#include <adt/list.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <futex.h> |
232,7 → 232,7 |
return; |
} |
if (callid == IPC_CALLRET_FATAL) { |
if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) { |
futex_up(&ipc_futex); |
/* Call asynchronous handler with error code */ |
if (call->callback) |
241,7 → 241,7 |
return; |
} |
if (callid == IPC_CALLRET_TEMPORARY) { |
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) { |
futex_up(&ipc_futex); |
call->u.msg.phoneid = phoneid; |
309,7 → 309,7 |
callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1, |
arg2, arg3, arg4); |
if (callid == IPC_CALLRET_TEMPORARY) { |
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) { |
if (!call) { |
call = ipc_prepare_async(private, callback); |
if (!call) |
442,7 → 442,7 |
call = list_get_instance(queued_calls.next, async_call_t, list); |
callid = _ipc_call_async(call->u.msg.phoneid, |
&call->u.msg.data); |
if (callid == IPC_CALLRET_TEMPORARY) { |
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) { |
break; |
} |
list_remove(&call->list); |
451,7 → 451,7 |
if (call->fid) |
fibril_add_ready(call->fid); |
if (callid == IPC_CALLRET_FATAL) { |
if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) { |
if (call->callback) |
call->callback(call->private, ENOENT, NULL); |
free(call); |
/branches/dd/uspace/lib/libc/generic/devmap.c |
---|
99,6 → 99,8 |
if (phone < 0) |
return phone; |
async_serialize_start(); |
ipc_call_t answer; |
aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); |
106,6 → 108,7 |
if (retval != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
return -1; |
} |
115,6 → 118,8 |
ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash); |
async_wait_for(req, &retval); |
async_serialize_end(); |
return retval; |
} |
131,6 → 136,8 |
if (phone < 0) |
return phone; |
async_serialize_start(); |
ipc_call_t answer; |
aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0, |
&answer); |
139,11 → 146,14 |
if (retval != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
return retval; |
} |
async_wait_for(req, &retval); |
async_serialize_end(); |
if (retval != EOK) { |
if (handle != NULL) |
*handle = -1; |
163,6 → 173,8 |
if (phone < 0) |
return phone; |
async_serialize_start(); |
ipc_call_t answer; |
aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0, |
&answer); |
171,11 → 183,14 |
if (retval != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
return retval; |
} |
async_wait_for(req, &retval); |
async_serialize_end(); |
if (retval != EOK) { |
if (handle != NULL) |
*handle = -1; |
211,7 → 226,7 |
return 0; |
ipcarg_t count; |
int retval = ipc_call_sync_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count); |
int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count); |
if (retval != EOK) |
return 0; |
225,6 → 240,8 |
if (phone < 0) |
return 0; |
async_serialize_start(); |
ipc_call_t answer; |
aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer); |
232,11 → 249,14 |
if (retval != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
return 0; |
} |
async_wait_for(req, &retval); |
async_serialize_end(); |
if (retval != EOK) |
return 0; |
/branches/dd/uspace/lib/libc/generic/async.c |
---|
95,8 → 95,8 |
#include <async.h> |
#include <fibril.h> |
#include <stdio.h> |
#include <libadt/hash_table.h> |
#include <libadt/list.h> |
#include <adt/hash_table.h> |
#include <adt/list.h> |
#include <ipc/ipc.h> |
#include <assert.h> |
#include <errno.h> |
174,10 → 174,11 |
} connection_t; |
/** Identifier of the incoming connection handled by the current fibril. */ |
__thread connection_t *FIBRIL_connection; |
fibril_local connection_t *FIBRIL_connection; |
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call); |
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call); |
static void default_pending(void); |
/** |
* Pointer to a fibril function that will be used to handle connections. |
190,11 → 191,15 |
*/ |
static async_client_conn_t interrupt_received = default_interrupt_received; |
/** |
* Pointer to a fibril function that will be used to handle pending |
* operations. |
*/ |
static async_pending_t pending = default_pending; |
static hash_table_t conn_hash_table; |
static LIST_INITIALIZE(timeout_list); |
#define CONN_HASH_TABLE_CHAINS 32 |
/** Compute hash into the connection hash table based on the source phone hash. |
376,6 → 381,42 |
return true; |
} |
/** Pending fibril. |
* |
* After each call the pending operations are executed in a separate |
* fibril. The function pending() is c. |
* |
* @param arg Unused. |
* |
* @return Always zero. |
* |
*/ |
static int pending_fibril(void *arg) |
{ |
pending(); |
return 0; |
} |
/** Process pending actions. |
* |
* A new fibril is created which would process the pending operations. |
* |
* @return False if an error occured. |
* True if the execution was passed to the pending fibril. |
* |
*/ |
static bool process_pending(void) |
{ |
futex_down(&async_futex); |
fid_t fid = fibril_create(pending_fibril, NULL); |
fibril_add_ready(fid); |
futex_up(&async_futex); |
return true; |
} |
/** Return new incoming message for the current (fibril-local) connection. |
* |
* @param call Storage where the incoming call data will be stored. |
472,6 → 513,15 |
{ |
} |
/** Default fibril function that gets called to handle pending operations. |
* |
* This function is defined as a weak symbol - to be redefined in user code. |
* |
*/ |
static void default_pending(void) |
{ |
} |
/** Wrapper for client connection fibril. |
* |
* When a new connection arrives, a fibril with this implementing function is |
500,9 → 550,10 |
/* Answer all remaining messages with EHANGUP */ |
while (!list_empty(&FIBRIL_connection->msg_queue)) { |
msg_t *msg |
= list_get_instance(FIBRIL_connection->msg_queue.next, msg_t, link); |
msg_t *msg; |
msg = list_get_instance(FIBRIL_connection->msg_queue.next, |
msg_t, link); |
list_remove(&msg->link); |
ipc_answer_0(msg->callid, EHANGUP); |
free(msg); |
563,7 → 614,7 |
} |
/* Add connection to the connection hash table */ |
ipcarg_t key = conn->in_phone_hash; |
unsigned long key = conn->in_phone_hash; |
futex_down(&async_futex); |
hash_table_insert(&conn_hash_table, &key, &conn->link); |
588,7 → 639,7 |
/* Unrouted call - do some default behaviour */ |
if ((callid & IPC_CALLID_NOTIFICATION)) { |
process_notification(callid, call); |
return; |
goto out; |
} |
switch (IPC_GET_METHOD(*call)) { |
597,15 → 648,19 |
/* Open new connection with fibril etc. */ |
async_new_connection(IPC_GET_ARG5(*call), callid, call, |
client_connection); |
return; |
goto out; |
} |
/* Try to route the call through the connection hash table */ |
if (route_call(callid, call)) |
return; |
goto out; |
/* Unknown call from unknown phone - hang it up */ |
ipc_answer_0(callid, EHANGUP); |
return; |
out: |
process_pending(); |
} |
/** Fire all timeouts that expired. */ |
663,8 → 718,8 |
suseconds_t timeout; |
if (!list_empty(&timeout_list)) { |
awaiter_t *waiter |
= list_get_instance(timeout_list.next, awaiter_t, link); |
awaiter_t *waiter = list_get_instance(timeout_list.next, |
awaiter_t, link); |
struct timeval tv; |
gettimeofday(&tv, NULL); |
681,8 → 736,8 |
futex_up(&async_futex); |
ipc_call_t call; |
ipc_callid_t callid |
= ipc_wait_cycle(&call, timeout, SYNCH_FLAGS_NONE); |
ipc_callid_t callid = ipc_wait_cycle(&call, timeout, |
SYNCH_FLAGS_NONE); |
if (!callid) { |
handle_expired_timeouts(); |
759,13 → 814,13 |
*/ |
static void reply_received(void *arg, int retval, ipc_call_t *data) |
{ |
futex_down(&async_futex); |
amsg_t *msg = (amsg_t *) arg; |
msg->retval = retval; |
futex_down(&async_futex); |
/* Copy data after futex_down, just in case the call was detached */ |
if (msg->dataptr) |
if ((msg->dataptr) && (data)) |
*msg->dataptr = *data; |
write_barrier(); |
994,6 → 1049,16 |
interrupt_received = intr; |
} |
/** Setter for pending function pointer. |
* |
* @param pend Function that will implement a new pending |
* operations fibril. |
*/ |
void async_set_pending(async_pending_t pend) |
{ |
pending = pend; |
} |
/** Pseudo-synchronous message sending - fast version. |
* |
* Send message asynchronously and return only after the reply arrives. |
/branches/dd/uspace/lib/libc/generic/vfs/vfs.c |
---|
49,12 → 49,13 |
#include <errno.h> |
#include <string.h> |
#include <devmap.h> |
#include "../../../srv/vfs/vfs.h" |
#include <ipc/vfs.h> |
#include <ipc/devmap.h> |
int vfs_phone = -1; |
futex_t vfs_phone_futex = FUTEX_INITIALIZER; |
static int vfs_phone = -1; |
static futex_t vfs_phone_futex = FUTEX_INITIALIZER; |
static futex_t cwd_futex = FUTEX_INITIALIZER; |
futex_t cwd_futex = FUTEX_INITIALIZER; |
DIR *cwd_dir = NULL; |
char *cwd_path = NULL; |
size_t cwd_size = 0; |
210,9 → 211,10 |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
if (rc != EOK) |
return (int) rc; |
return (int) IPC_GET_ARG1(answer); |
} |
221,6 → 223,27 |
return _open(path, L_FILE, oflag); |
} |
int open_node(fdi_node_t *node, int oflag) |
{ |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
ipc_call_t answer; |
aid_t req = async_send_4(vfs_phone, VFS_OPEN_NODE, node->fs_handle, |
node->dev_handle, node->index, oflag, &answer); |
ipcarg_t rc; |
async_wait_for(req, &rc); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
if (rc != EOK) |
return (int) rc; |
return (int) IPC_GET_ARG1(answer); |
} |
int close(int fildes) |
{ |
ipcarg_t rc; |
291,6 → 314,62 |
return -1; |
} |
int fd_phone(int fildes) |
{ |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
ipcarg_t device; |
ipcarg_t rc = async_req_1_1(vfs_phone, VFS_DEVICE, fildes, &device); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
if (rc != EOK) |
return -1; |
return devmap_device_connect((dev_handle_t) device, 0); |
} |
int fd_node(int fildes, fdi_node_t *node) |
{ |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
ipcarg_t fs_handle; |
ipcarg_t dev_handle; |
ipcarg_t index; |
ipcarg_t rc = async_req_1_3(vfs_phone, VFS_NODE, fildes, &fs_handle, |
&dev_handle, &index); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
if (rc == EOK) { |
node->fs_handle = (fs_handle_t) fs_handle; |
node->dev_handle = (dev_handle_t) dev_handle; |
node->index = (fs_index_t) index; |
} |
return rc; |
} |
int fsync(int fildes) |
{ |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
ipcarg_t rc = async_req_1_0(vfs_phone, VFS_SYNC, fildes); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return (int) rc; |
} |
off_t lseek(int fildes, off_t offset, int whence) |
{ |
ipcarg_t rc; |
386,7 → 465,7 |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return rc; |
return rc; |
} |
static int _unlink(const char *path, int lflag) |
416,7 → 495,7 |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return rc; |
return rc; |
} |
int unlink(const char *path) |
/branches/dd/uspace/lib/libc/generic/mem.c |
---|
95,7 → 95,7 |
static void *unaligned_memcpy(void *dst, const void *src, size_t n) |
{ |
int i, j; |
size_t i, j; |
struct along *adst = dst; |
const struct along *asrc = src; |
/branches/dd/uspace/lib/libc/generic/io/sprintf.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/io/vsprintf.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/io/fprintf.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/io/stream.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/io/stdio.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/io/printf.c |
---|
34,23 → 34,43 |
#include <io/printf_core.h> |
#include <stdio.h> |
#include <stdio.h> |
/** Print formatted text. |
* @param fmt format string |
* |
* @param stream Output stream |
* @param fmt Format string |
* |
* \see For more details about format string see printf_core. |
* |
*/ |
int fprintf(FILE *stream, const char *fmt, ...) |
{ |
va_list args; |
va_start(args, fmt); |
int ret = vfprintf(stream, fmt, args); |
va_end(args); |
return ret; |
} |
/** Print formatted text to stdout. |
* |
* @param fmt Format string |
* |
* \see For more details about format string see printf_core. |
* |
*/ |
int printf(const char *fmt, ...) |
{ |
int ret; |
va_list args; |
va_start(args, fmt); |
ret = vprintf(fmt, args); |
int ret = vprintf(fmt, args); |
va_end(args); |
return ret; |
} |
/branches/dd/uspace/lib/libc/generic/io/console.c |
---|
0,0 → 1,102 |
/* |
* Copyright (c) 2006 Josef Cejka |
* Copyright (c) 2006 Jakub Vana |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#include <libc.h> |
#include <async.h> |
#include <io/console.h> |
#include <ipc/console.h> |
void console_clear(int phone) |
{ |
async_msg_0(phone, CONSOLE_CLEAR); |
} |
int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols) |
{ |
return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols); |
} |
void console_set_style(int phone, int style) |
{ |
async_msg_1(phone, CONSOLE_SET_STYLE, style); |
} |
void console_set_color(int phone, int fg_color, int bg_color, int flags) |
{ |
async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags); |
} |
void console_set_rgb_color(int phone, int fg_color, int bg_color) |
{ |
async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color); |
} |
void console_cursor_visibility(int phone, bool show) |
{ |
async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false); |
} |
void console_kcon_enable(int phone) |
{ |
async_msg_0(phone, CONSOLE_KCON_ENABLE); |
} |
void console_goto(int phone, ipcarg_t row, ipcarg_t col) |
{ |
async_msg_2(phone, CONSOLE_GOTO, row, col); |
} |
bool console_get_event(int phone, console_event_t *event) |
{ |
ipcarg_t type; |
ipcarg_t key; |
ipcarg_t mods; |
ipcarg_t c; |
int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c); |
if (rc < 0) |
return false; |
event->type = type; |
event->key = key; |
event->mods = mods; |
event->c = c; |
return true; |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/io/snprintf.c |
---|
37,21 → 37,23 |
#include <io/printf_core.h> |
/** Print formatted to the given buffer with limited size. |
* @param str buffer |
* @param size buffer size |
* @param fmt format string |
* |
* @param str Buffer |
* @param size Buffer size |
* @param fmt Format string |
* |
* \see For more details about format string see printf_core. |
* |
*/ |
int snprintf(char *str, size_t size, const char *fmt, ...) |
{ |
int ret; |
va_list args; |
va_start(args, fmt); |
va_start(args, fmt); |
ret = vsnprintf(str, size, fmt, args); |
int ret = vsnprintf(str, size, fmt, args); |
va_end(args); |
return ret; |
} |
/branches/dd/uspace/lib/libc/generic/io/asprintf.c |
---|
36,42 → 36,52 |
#include <stdarg.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <io/printf_core.h> |
static int asprintf_prewrite(const char *str, size_t count, void *unused) |
static int asprintf_str_write(const char *str, size_t count, void *unused) |
{ |
return count; |
return str_nlength(str, count); |
} |
static int asprintf_wstr_write(const wchar_t *str, size_t count, void *unused) |
{ |
return wstr_nlength(str, count); |
} |
/** Allocate and print to string. |
* |
* @param strp Address of the pointer where to store the address of |
* the newly allocated string. |
* @fmt Format strin. |
* @param strp Address of the pointer where to store the address of |
* the newly allocated string. |
* @fmt Format string. |
* |
* @return Number of characters printed or a negative error code. |
* @return Number of characters printed or a negative error code. |
* |
*/ |
int asprintf(char **strp, const char *fmt, ...) |
{ |
struct printf_spec ps = { |
asprintf_prewrite, |
NULL |
asprintf_str_write, |
asprintf_wstr_write, |
NULL |
}; |
int ret; |
va_list args; |
va_start(args, fmt); |
ret = printf_core(fmt, &ps, args); |
int ret = printf_core(fmt, &ps, args); |
va_end(args); |
if (ret > 0) { |
*strp = malloc(ret + 20); |
if (!*strp) |
*strp = malloc(STR_BOUNDS(ret) + 1); |
if (*strp == NULL) |
return -1; |
va_start(args, fmt); |
vsprintf(*strp, fmt, args); |
va_end(args); |
vsnprintf(*strp, STR_BOUNDS(ret) + 1, fmt, args); |
va_end(args); |
} |
return ret; |
} |
/branches/dd/uspace/lib/libc/generic/io/io.c |
---|
30,98 → 30,421 |
* @{ |
*/ |
/** @file |
*/ |
*/ |
#include <libc.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <stdio.h> |
#include <io/io.h> |
#include <fcntl.h> |
#include <string.h> |
#include <errno.h> |
#include <console.h> |
#include <bool.h> |
#include <malloc.h> |
#include <io/klog.h> |
#include <vfs/vfs.h> |
#include <ipc/devmap.h> |
#include <adt/list.h> |
const static char nl = '\n'; |
static FILE stdin_null = { |
.fd = -1, |
.error = true, |
.eof = true, |
.klog = false, |
.phone = -1 |
}; |
int puts(const char *str) |
static FILE stdout_klog = { |
.fd = -1, |
.error = false, |
.eof = false, |
.klog = true, |
.phone = -1 |
}; |
static FILE stderr_klog = { |
.fd = -1, |
.error = false, |
.eof = false, |
.klog = true, |
.phone = -1 |
}; |
FILE *stdin = NULL; |
FILE *stdout = NULL; |
FILE *stderr = NULL; |
static LIST_INITIALIZE(files); |
void stdio_init(int filc, fdi_node_t *filv[]) |
{ |
size_t count; |
if (filc > 0) { |
stdin = fopen_node(filv[0], "r"); |
} else { |
stdin = &stdin_null; |
list_append(&stdin->link, &files); |
} |
if (str == NULL) |
return putnchars("(NULL)", 6); |
if (filc > 1) { |
stdout = fopen_node(filv[1], "w"); |
} else { |
stdout = &stdout_klog; |
list_append(&stdout->link, &files); |
} |
for (count = 0; str[count] != 0; count++); |
if (filc > 2) { |
stderr = fopen_node(filv[2], "w"); |
} else { |
stderr = &stderr_klog; |
list_append(&stderr->link, &files); |
} |
} |
void stdio_done(void) |
{ |
link_t *link = files.next; |
if (console_write((void *) str, count) == count) { |
if (console_write(&nl, 1) == 1) |
return 0; |
while (link != &files) { |
FILE *file = list_get_instance(link, FILE, link); |
fclose(file); |
link = files.next; |
} |
} |
static bool parse_mode(const char *mode, int *flags) |
{ |
/* Parse mode except first character. */ |
const char *mp = mode; |
if (*mp++ == 0) { |
errno = EINVAL; |
return false; |
} |
return EOF; |
if ((*mp == 'b') || (*mp == 't')) |
mp++; |
bool plus; |
if (*mp == '+') { |
mp++; |
plus = true; |
} else |
plus = false; |
if (*mp != 0) { |
errno = EINVAL; |
return false; |
} |
/* Parse first character of mode and determine flags for open(). */ |
switch (mode[0]) { |
case 'r': |
*flags = plus ? O_RDWR : O_RDONLY; |
break; |
case 'w': |
*flags = (O_TRUNC | O_CREAT) | (plus ? O_RDWR : O_WRONLY); |
break; |
case 'a': |
/* TODO: a+ must read from beginning, append to the end. */ |
if (plus) { |
errno = ENOTSUP; |
return false; |
} |
*flags = (O_APPEND | O_CREAT) | (plus ? O_RDWR : O_WRONLY); |
default: |
errno = EINVAL; |
return false; |
} |
return true; |
} |
/** Put count chars from buffer to stdout without adding newline |
* @param buf Buffer with size at least count bytes - NULL pointer NOT allowed! |
* @param count |
* @return 0 on succes, EOF on fail |
/** Open a stream. |
* |
* @param path Path of the file to open. |
* @param mode Mode string, (r|w|a)[b|t][+]. |
* |
*/ |
int putnchars(const char *buf, size_t count) |
FILE *fopen(const char *path, const char *mode) |
{ |
if (console_write((void *) buf, count) == count) |
return 0; |
int flags; |
if (!parse_mode(mode, &flags)) |
return NULL; |
return EOF; |
/* Open file. */ |
FILE *stream = malloc(sizeof(FILE)); |
if (stream == NULL) { |
errno = ENOMEM; |
return NULL; |
} |
stream->fd = open(path, flags, 0666); |
if (stream->fd < 0) { |
/* errno was set by open() */ |
free(stream); |
return NULL; |
} |
stream->error = false; |
stream->eof = false; |
stream->klog = false; |
stream->phone = -1; |
list_append(&stream->link, &files); |
return stream; |
} |
/** Same as puts, but does not print newline at end |
FILE *fdopen(int fd, const char *mode) |
{ |
/* Open file. */ |
FILE *stream = malloc(sizeof(FILE)); |
if (stream == NULL) { |
errno = ENOMEM; |
return NULL; |
} |
stream->fd = fd; |
stream->error = false; |
stream->eof = false; |
stream->klog = false; |
stream->phone = -1; |
list_append(&stream->link, &files); |
return stream; |
} |
FILE *fopen_node(fdi_node_t *node, const char *mode) |
{ |
int flags; |
if (!parse_mode(mode, &flags)) |
return NULL; |
/* Open file. */ |
FILE *stream = malloc(sizeof(FILE)); |
if (stream == NULL) { |
errno = ENOMEM; |
return NULL; |
} |
stream->fd = open_node(node, flags); |
if (stream->fd < 0) { |
/* errno was set by open_node() */ |
free(stream); |
return NULL; |
} |
stream->error = false; |
stream->eof = false; |
stream->klog = false; |
stream->phone = -1; |
list_append(&stream->link, &files); |
return stream; |
} |
int fclose(FILE *stream) |
{ |
int rc = 0; |
fflush(stream); |
if (stream->phone >= 0) |
ipc_hangup(stream->phone); |
if (stream->fd >= 0) |
rc = close(stream->fd); |
list_remove(&stream->link); |
if ((stream != &stdin_null) |
&& (stream != &stdout_klog) |
&& (stream != &stderr_klog)) |
free(stream); |
stream = NULL; |
if (rc != 0) { |
/* errno was set by close() */ |
return EOF; |
} |
return 0; |
} |
/** Read from a stream. |
* |
* @param buf Destination buffer. |
* @param size Size of each record. |
* @param nmemb Number of records to read. |
* @param stream Pointer to the stream. |
* |
*/ |
int putstr(const char *str) |
size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream) |
{ |
size_t count; |
size_t left = size * nmemb; |
size_t done = 0; |
if (str == NULL) |
return putnchars("(NULL)", 6); |
while ((left > 0) && (!stream->error) && (!stream->eof)) { |
ssize_t rd = read(stream->fd, buf + done, left); |
if (rd < 0) |
stream->error = true; |
else if (rd == 0) |
stream->eof = true; |
else { |
left -= rd; |
done += rd; |
} |
} |
return (done / size); |
} |
for (count = 0; str[count] != 0; count++); |
if (console_write((void *) str, count) == count) |
return 0; |
/** Write to a stream. |
* |
* @param buf Source buffer. |
* @param size Size of each record. |
* @param nmemb Number of records to write. |
* @param stream Pointer to the stream. |
* |
*/ |
size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) |
{ |
size_t left = size * nmemb; |
size_t done = 0; |
return EOF; |
while ((left > 0) && (!stream->error)) { |
ssize_t wr; |
if (stream->klog) |
wr = klog_write(buf + done, left); |
else |
wr = write(stream->fd, buf + done, left); |
if (wr <= 0) |
stream->error = true; |
else { |
left -= wr; |
done += wr; |
} |
} |
return (done / size); |
} |
int putchar(int c) |
int fputc(wchar_t c, FILE *stream) |
{ |
char buf[STR_BOUNDS(1)]; |
size_t offs; |
size_t sz = 0; |
if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) { |
size_t wr = fwrite(buf, sz, 1, stream); |
if (wr < sz) |
return EOF; |
return (int) c; |
} |
return EOF; |
} |
offs = 0; |
if (chr_encode(c, buf, &offs, STR_BOUNDS(1)) != EOK) |
return EOF; |
int putchar(wchar_t c) |
{ |
return fputc(c, stdout); |
} |
if (console_write((void *) buf, offs) == offs) |
return c; |
int fputs(const char *str, FILE *stream) |
{ |
return fwrite(str, str_size(str), 1, stream); |
} |
return EOF; |
int puts(const char *str) |
{ |
return fputs(str, stdout); |
} |
int fgetc(FILE *stream) |
{ |
char c; |
/* This could be made faster by only flushing when needed. */ |
if (stdout) |
fflush(stdout); |
if (stderr) |
fflush(stderr); |
if (fread(&c, sizeof(char), 1, stream) < sizeof(char)) |
return EOF; |
return (int) c; |
} |
int getchar(void) |
{ |
unsigned char c; |
return fgetc(stdin); |
} |
int fseek(FILE *stream, long offset, int origin) |
{ |
off_t rc = lseek(stream->fd, offset, origin); |
if (rc == (off_t) (-1)) { |
/* errno has been set by lseek. */ |
return -1; |
} |
console_flush(); |
if (read_stdin((void *) &c, 1) == 1) |
return c; |
stream->eof = false; |
return EOF; |
return 0; |
} |
int fflush(FILE *f) |
void rewind(FILE *stream) |
{ |
/* Dummy implementation */ |
(void) f; |
console_flush(); |
return 0; |
(void) fseek(stream, 0, SEEK_SET); |
} |
int fflush(FILE *stream) |
{ |
if (stream->klog) { |
klog_update(); |
return EOK; |
} |
if (stream->fd >= 0) |
return fsync(stream->fd); |
return ENOENT; |
} |
int feof(FILE *stream) |
{ |
return stream->eof; |
} |
int ferror(FILE *stream) |
{ |
return stream->error; |
} |
int fphone(FILE *stream) |
{ |
if (stream->fd >= 0) { |
if (stream->phone < 0) |
stream->phone = fd_phone(stream->fd); |
return stream->phone; |
} |
return -1; |
} |
int fnode(FILE *stream, fdi_node_t *node) |
{ |
if (stream->fd >= 0) |
return fd_node(stream->fd, node); |
return ENOENT; |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/io/vprintf.c |
---|
38,37 → 38,25 |
#include <io/printf_core.h> |
#include <futex.h> |
#include <async.h> |
#include <console.h> |
#include <string.h> |
static atomic_t printf_futex = FUTEX_INITIALIZER; |
static int vprintf_str_write(const char *str, size_t size, void *data) |
static int vprintf_str_write(const char *str, size_t size, void *stream) |
{ |
size_t offset = 0; |
size_t prev; |
count_t chars = 0; |
while (offset < size) { |
prev = offset; |
str_decode(str, &offset, size); |
console_write(str + prev, offset - prev); |
chars++; |
} |
return chars; |
size_t wr = fwrite(str, 1, size, (FILE *) stream); |
return str_nlength(str, wr); |
} |
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data) |
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *stream) |
{ |
size_t offset = 0; |
size_t boff; |
count_t chars = 0; |
char buf[4]; |
size_t chars = 0; |
while (offset < size) { |
boff = 0; |
chr_encode(str[chars], buf, &boff, 4); |
console_write(buf, boff); |
if (fputc(str[chars], (FILE *) stream) <= 0) |
break; |
chars++; |
offset += sizeof(wchar_t); |
} |
76,33 → 64,55 |
return chars; |
} |
/** Print formatted text. |
* @param fmt format string |
* @param ap format parameters |
* |
* @param stream Output stream |
* @param fmt Format string |
* @param ap Format parameters |
* |
* \see For more details about format string see printf_core. |
* |
*/ |
int vprintf(const char *fmt, va_list ap) |
int vfprintf(FILE *stream, const char *fmt, va_list ap) |
{ |
struct printf_spec ps = { |
vprintf_str_write, |
vprintf_wstr_write, |
NULL |
stream |
}; |
/* |
* Prevent other threads to execute printf_core() |
*/ |
futex_down(&printf_futex); |
/* |
* Prevent other pseudo threads of the same thread |
* Prevent other fibrils of the same thread |
* to execute printf_core() |
*/ |
async_serialize_start(); |
int ret = printf_core(fmt, &ps, ap); |
async_serialize_end(); |
futex_up(&printf_futex); |
return ret; |
} |
/** Print formatted text to stdout. |
* |
* @param file Output stream |
* @param fmt Format string |
* @param ap Format parameters |
* |
* \see For more details about format string see printf_core. |
* |
*/ |
int vprintf(const char *fmt, va_list ap) |
{ |
return vfprintf(stdout, fmt, ap); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/io/vsnprintf.c |
---|
82,7 → 82,7 |
* with the trailing zero => print only a part |
* of string |
*/ |
index_t index = 0; |
size_t index = 0; |
while (index < size) { |
wchar_t uc = str_decode(str, &index, size); |
130,7 → 130,7 |
*/ |
static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data) |
{ |
index_t index = 0; |
size_t index = 0; |
while (index < (size / sizeof(wchar_t))) { |
size_t left = data->size - data->len; |
/branches/dd/uspace/lib/libc/generic/io/printf_core.c |
---|
173,7 → 173,7 |
*/ |
static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps) |
{ |
count_t counter = 0; |
size_t counter = 0; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
while (--width > 0) { |
/* |
211,7 → 211,7 |
*/ |
static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps) |
{ |
count_t counter = 0; |
size_t counter = 0; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
while (--width > 0) { |
/* |
254,12 → 254,12 |
return printf_putstr(nullstr, ps); |
/* Print leading spaces. */ |
count_t strw = str_length(str); |
size_t strw = str_length(str); |
if (precision == 0) |
precision = strw; |
/* Left padding */ |
count_t counter = 0; |
size_t counter = 0; |
width -= precision; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
while (width-- > 0) { |
310,7 → 310,7 |
precision = strw; |
/* Left padding */ |
count_t counter = 0; |
size_t counter = 0; |
width -= precision; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
while (width-- > 0) { |
432,7 → 432,7 |
} |
width -= precision + size - number_size; |
count_t counter = 0; |
size_t counter = 0; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
while (width-- > 0) { |
595,7 → 595,7 |
size_t nxt = 0; /* Index of the next character from fmt */ |
size_t j = 0; /* Index to the first not printed nonformating character */ |
count_t counter = 0; /* Number of characters printed */ |
size_t counter = 0; /* Number of characters printed */ |
int retval; /* Return values from nested functions */ |
while (true) { |
/branches/dd/uspace/lib/libc/generic/io/klog.c |
---|
0,0 → 1,53 |
/* |
* Copyright (c) 2006 Josef Cejka |
* Copyright (c) 2006 Jakub Vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#include <libc.h> |
#include <string.h> |
#include <sys/types.h> |
#include <unistd.h> |
#include <io/klog.h> |
size_t klog_write(const void *buf, size_t size) |
{ |
return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size); |
} |
void klog_update(void) |
{ |
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/adt/hash_table.c |
---|
0,0 → 1,196 |
/* |
* Copyright (c) 2008 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
/* |
* This is an implementation of generic chained hash table. |
*/ |
#include <adt/hash_table.h> |
#include <adt/list.h> |
#include <unistd.h> |
#include <malloc.h> |
#include <assert.h> |
#include <stdio.h> |
#include <string.h> |
/** Create chained hash table. |
* |
* @param h Hash table structure. Will be initialized by this call. |
* @param m Number of hash table buckets. |
* @param max_keys Maximal number of keys needed to identify an item. |
* @param op Hash table operations structure. |
* @return True on success |
*/ |
int hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys, |
hash_table_operations_t *op) |
{ |
hash_count_t i; |
assert(h); |
assert(op && op->hash && op->compare); |
assert(max_keys > 0); |
h->entry = malloc(m * sizeof(link_t)); |
if (!h->entry) { |
printf("cannot allocate memory for hash table\n"); |
return false; |
} |
memset((void *) h->entry, 0, m * sizeof(link_t)); |
for (i = 0; i < m; i++) |
list_initialize(&h->entry[i]); |
h->entries = m; |
h->max_keys = max_keys; |
h->op = op; |
return true; |
} |
/** Destroy a hash table instance. |
* |
* @param h Hash table to be destroyed. |
*/ |
void hash_table_destroy(hash_table_t *h) |
{ |
assert(h); |
assert(h->entry); |
free(h->entry); |
} |
/** Insert item into a hash table. |
* |
* @param h Hash table. |
* @param key Array of all keys necessary to compute hash index. |
* @param item Item to be inserted into the hash table. |
*/ |
void hash_table_insert(hash_table_t *h, unsigned long key[], link_t *item) |
{ |
hash_index_t chain; |
assert(item); |
assert(h && h->op && h->op->hash && h->op->compare); |
chain = h->op->hash(key); |
assert(chain < h->entries); |
list_append(item, &h->entry[chain]); |
} |
/** Search hash table for an item matching keys. |
* |
* @param h Hash table. |
* @param key Array of all keys needed to compute hash index. |
* |
* @return Matching item on success, NULL if there is no such item. |
*/ |
link_t *hash_table_find(hash_table_t *h, unsigned long key[]) |
{ |
link_t *cur; |
hash_index_t chain; |
assert(h && h->op && h->op->hash && h->op->compare); |
chain = h->op->hash(key); |
assert(chain < h->entries); |
for (cur = h->entry[chain].next; cur != &h->entry[chain]; |
cur = cur->next) { |
if (h->op->compare(key, h->max_keys, cur)) { |
/* |
* The entry is there. |
*/ |
return cur; |
} |
} |
return NULL; |
} |
/** Remove all matching items from hash table. |
* |
* For each removed item, h->remove_callback() is called. |
* |
* @param h Hash table. |
* @param key Array of keys that will be compared against items of |
* the hash table. |
* @param keys Number of keys in the 'key' array. |
*/ |
void hash_table_remove(hash_table_t *h, unsigned long key[], hash_count_t keys) |
{ |
hash_index_t chain; |
link_t *cur; |
assert(h && h->op && h->op->hash && h->op->compare && |
h->op->remove_callback); |
assert(keys <= h->max_keys); |
if (keys == h->max_keys) { |
/* |
* All keys are known, hash_table_find() can be used to find the |
* entry. |
*/ |
cur = hash_table_find(h, key); |
if (cur) { |
list_remove(cur); |
h->op->remove_callback(cur); |
} |
return; |
} |
/* |
* Fewer keys were passed. |
* Any partially matching entries are to be removed. |
*/ |
for (chain = 0; chain < h->entries; chain++) { |
for (cur = h->entry[chain].next; cur != &h->entry[chain]; |
cur = cur->next) { |
if (h->op->compare(key, keys, cur)) { |
link_t *hlp; |
hlp = cur; |
cur = cur->prev; |
list_remove(hlp); |
h->op->remove_callback(hlp); |
continue; |
} |
} |
} |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/adt/list.c |
---|
0,0 → 1,112 |
/* |
* Copyright (c) 2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#include <adt/list.h> |
/** Check for membership |
* |
* Check whether link is contained in the list head. |
* The membership is defined as pointer equivalence. |
* |
* @param link Item to look for. |
* @param head List to look in. |
* |
* @return true if link is contained in head, false otherwise. |
* |
*/ |
int list_member(const link_t *link, const link_t *head) |
{ |
int found = 0; |
link_t *hlp = head->next; |
while (hlp != head) { |
if (hlp == link) { |
found = 1; |
break; |
} |
hlp = hlp->next; |
} |
return found; |
} |
/** Concatenate two lists |
* |
* Concatenate lists head1 and head2, producing a single |
* list head1 containing items from both (in head1, head2 |
* order) and empty list head2. |
* |
* @param head1 First list and concatenated output |
* @param head2 Second list and empty output. |
* |
*/ |
void list_concat(link_t *head1, link_t *head2) |
{ |
if (list_empty(head2)) |
return; |
head2->next->prev = head1->prev; |
head2->prev->next = head1; |
head1->prev->next = head2->next; |
head1->prev = head2->prev; |
list_initialize(head2); |
} |
/** Count list items |
* |
* Return the number of items in the list. |
* |
* @param link List to count. |
* |
* @return Number of items in the list. |
* |
*/ |
unsigned int list_count(const link_t *link) |
{ |
unsigned int count = 0; |
link_t *hlp = link->next; |
while (hlp != link) { |
count++; |
hlp = hlp->next; |
} |
return count; |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/Makefile |
---|
46,12 → 46,12 |
generic/ddi.c \ |
generic/as.c \ |
generic/cap.c \ |
generic/console.c \ |
generic/devmap.c \ |
generic/event.c \ |
generic/mem.c \ |
generic/string.c \ |
generic/fibril.c \ |
generic/fibril_sync.c \ |
generic/pcb.c \ |
generic/smc.c \ |
generic/thread.c \ |
61,15 → 61,12 |
generic/io/asprintf.c \ |
generic/io/io.c \ |
generic/io/printf.c \ |
generic/io/fprintf.c \ |
generic/io/stdio.c \ |
generic/io/stream.c \ |
generic/io/sprintf.c \ |
generic/io/klog.c \ |
generic/io/snprintf.c \ |
generic/io/vprintf.c \ |
generic/io/vsprintf.c \ |
generic/io/vsnprintf.c \ |
generic/io/printf_core.c \ |
generic/io/console.c \ |
malloc/malloc.c \ |
generic/sysinfo.c \ |
generic/ipc.c \ |
76,12 → 73,11 |
generic/async.c \ |
generic/loader.c \ |
generic/getopt.c \ |
generic/libadt/list.o \ |
generic/libadt/hash_table.o \ |
generic/adt/list.o \ |
generic/adt/hash_table.o \ |
generic/time.c \ |
generic/err.c \ |
generic/stdlib.c \ |
generic/kbd.c \ |
generic/mman.c \ |
generic/udebug.c \ |
generic/vfs/vfs.c \ |
/branches/dd/uspace/lib/libc/arch/sparc64/include/types.h |
---|
49,8 → 49,6 |
typedef int64_t ssize_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
/branches/dd/uspace/lib/libc/arch/ia64/include/types.h |
---|
49,8 → 49,6 |
typedef int64_t ssize_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
/branches/dd/uspace/lib/libc/arch/arm32/include/tls.h |
---|
40,7 → 40,7 |
#define CONFIG_TLS_VARIANT_1 |
/** Offsets for accessing __thread variables are shifted 8 bytes higher. */ |
/** Offsets for accessing thread-local variables are shifted 8 bytes higher. */ |
#define ARM_TP_OFFSET (-8) |
/** TCB (Thread Control Block) struct. |
/branches/dd/uspace/lib/libc/arch/arm32/include/types.h |
---|
50,8 → 50,6 |
typedef int32_t ssize_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
/branches/dd/uspace/lib/libc/arch/arm32/include/fibril.h |
---|
38,7 → 38,7 |
#include <sys/types.h> |
#include <align.h> |
#include "thread.h" |
#include <thread.h> |
/** Size of a stack item */ |
#define STACK_ITEM_SIZE 4 |
/branches/dd/uspace/lib/libc/arch/ppc32/include/types.h |
---|
49,8 → 49,6 |
typedef int32_t ssize_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
/branches/dd/uspace/lib/libc/arch/amd64/include/types.h |
---|
49,8 → 49,6 |
typedef int64_t ssize_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
/branches/dd/uspace/lib/libc/arch/mips32/include/types.h |
---|
50,8 → 50,6 |
typedef int32_t ssize_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
/branches/dd/uspace/lib/libc/arch/ia32/include/types.h |
---|
49,8 → 49,6 |
typedef int32_t ssize_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |