From ca828476fdb64ad4615bc6f580c2a451e78fcc1c Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Wed, 17 Dec 2008 13:11:52 +0100 Subject: Move viengoos header files to libviengoos. / 2008-12-17 Neal H. Walfield * libviengoos: New directory. * Makefile.am (SUBDIRS): Add libviengoos. * configure.ac: Include libviengoos/headers.m4. Generate libviengoos/Makefile. hurd/ 2008-12-17 Neal H. Walfield * activity.h: Move to ../libviengoos/viengoos. Update references. * addr-trans.h: Likewise. * addr.h: Likewise. * cap.h: Likewise. * folio.h: Likewise. * futex.h: Likewise. * ipc.h: Likewise. * message.h: Likewise. * messenger.h: Likewise. * rpc.h: Likewise. * thread.h: Move viengoos specific bits... * ../libviengoos/viengoos/thread.h: ... to this new file. * thread.h (struct hurd_utcb): New structure. * exceptions.h (hurd_utcb): Use a struct hurd_utcb *, not a struct vg_utcb *. Update users. (hurd_activation_state_alloc): Likewise. (hurd_activation_state_free): Likewise. (hurd_activation_handler_activated): Likewise. (hurd_activation_handler_normal): Likewise. * t-addr-trans.c: Move to ../libviengoos. * t-addr.c: Likewise. * t-rpc.c: Likewise. * Makefile.am (TESTS, check_PROGRAMS, t_addr_CPPFLAGS) (t_addr_SOURCES, t_addr_trans_CPPFLAGS, t_addr_trans_SOURCES) (t_rpc_CPPFLAGS, t_rpc_SOURCES): Move from this file... * ../libviengoos/Makefile.am. * Makefile.am (includehurd_HEADERS): Don't mention activity.h, addr-trans.h, addr.h, cap.h, folio.h, futex.h, ipc.h, message.h or messenger.h. * headers.m4: Don't create a link to hurd/addr.h, hurd/addr-trans.h, hurd/cap.h, hurd/folio.h, hurd/rpc.h, hurd/activity.h, hurd/futex.h, hurd/message.h, hurd/messenger.h or hurd/ipc.h. libviengoos/ 2008-12-17 Neal H. Walfield * Makefile.am: New file. * headers.m4: Likewise. * t-addr-trans.c: Move from ../hurd. * t-addr.c: Likewise. * t-rpc.c: Likewise. * viengoos.h: Likewise. * viengoos/activity.h: Likewise. * viengoos/addr-trans.h: Likewise. * viengoos/addr.h: Likewise. * viengoos/cap.h: Likewise. * viengoos/folio.h: Likewise. * viengoos/futex.h: Likewise. * viengoos/ipc.h: Likewise. * viengoos/message.h: Likewise. * viengoos/messenger.h: Likewise. * viengoos/rpc.h: Likewise. * viengoos/misc.h: Moved from ../viengoos/rm.h. * viengoos/thread.h: New file split from ../hurd/thread.h. libpthread/ 2008-12-17 Neal H. Walfield * Makefile.am: New file. * headers.m4: Likewise. * t-addr-trans.c: Move from ../hurd. * t-addr.c: Likewise. * t-rpc.c: Likewise. * viengoos.h: Likewise. * viengoos/activity.h: Likewise. * viengoos/addr-trans.h: Likewise. * viengoos/addr.h: Likewise. * viengoos/cap.h: Likewise. * viengoos/folio.h: Likewise. * viengoos/futex.h: Likewise. * viengoos/ipc.h: Likewise. * viengoos/message.h: Likewise. * viengoos/messenger.h: Likewise. * viengoos/rpc.h: Likewise. * viengoos/misc.h: Moved from ../viengoos/rm.h. * viengoos/thread.h: New file split from ../hurd/thread.h. viengoos/ 2008-12-17 Neal H. Walfield * rm.h: Move from here... * ../libviengoos/viengoos/misc.h: ... to here. Update users. * headers.m4: Don't link rm.h to hurd/rm.h. * Makefile.am (viengoos_SOURCES): Remove rm.h. --- ChangeLog | 7 + Makefile.am | 2 +- benchmarks/GCbench.c | 4 +- benchmarks/Makefile.am | 4 +- benchmarks/activity-distribution.c | 2 +- .../boehm-gc/patches/05-viengoos-scheduler.patch | 6 +- benchmarks/cache.c | 4 +- benchmarks/shared-memory-distribution.c | 2 +- configure.ac | 2 + hieronymus/hieronymus.c | 8 +- hurd/ChangeLog | 36 + hurd/Makefile.am | 18 +- hurd/activity.h | 256 ----- hurd/addr-trans.h | 190 ---- hurd/addr.h | 179 ---- hurd/cap.h | 730 -------------- hurd/exceptions.h | 16 +- hurd/folio.h | 442 -------- hurd/futex.h | 219 ---- hurd/headers.m4 | 10 - hurd/ipc.h | 296 ------ hurd/message.h | 229 ----- hurd/messenger.h | 87 -- hurd/mutex.h | 2 +- hurd/rpc.h | 1054 -------------------- hurd/startup.h | 2 +- hurd/t-addr-trans.c | 84 -- hurd/t-addr.c | 74 -- hurd/t-rpc.c | 185 ---- hurd/thread.h | 320 +----- hurd/types.h | 2 +- libc-parts/_exit.c | 2 +- libc-parts/backtrace.c | 1 + libc-parts/process-spawn.c | 6 +- libc-parts/process-spawn.h | 4 +- libc-parts/profile.c | 4 +- libc-parts/s_printf.c | 2 +- libhurd-mm/anonymous.c | 2 +- libhurd-mm/anonymous.h | 2 +- libhurd-mm/as-build-custom.c | 6 +- libhurd-mm/as-build.c | 6 +- libhurd-mm/as-compute-gbits.h | 2 +- libhurd-mm/as-dump.c | 4 +- libhurd-mm/as-lookup.c | 4 +- libhurd-mm/as.c | 6 +- libhurd-mm/as.h | 4 +- libhurd-mm/capalloc.c | 2 +- libhurd-mm/capalloc.h | 2 +- libhurd-mm/exceptions.c | 93 +- libhurd-mm/ia32-exception-entry.S | 2 +- libhurd-mm/madvise.c | 2 +- libhurd-mm/map.h | 2 +- libhurd-mm/message-buffer.h | 2 +- libhurd-mm/mm-init.c | 3 +- libhurd-mm/mm.h | 2 +- libhurd-mm/mmap.c | 2 +- libhurd-mm/mprotect.c | 2 +- libhurd-mm/storage.c | 6 +- libhurd-mm/storage.h | 4 +- libpthread/ChangeLog | 7 + libpthread/signal/sigwaiter.c | 2 +- libpthread/sysdeps/viengoos/bits/pthread-np.h | 6 +- libpthread/sysdeps/viengoos/ia32/pt-setup.c | 2 +- .../viengoos/ia32/signal-dispatch-lowlevel.c | 2 +- libpthread/sysdeps/viengoos/pt-block.c | 2 +- libpthread/sysdeps/viengoos/pt-hurd-utcb-np.c | 2 +- libpthread/sysdeps/viengoos/pt-setactivity-np.c | 4 +- libpthread/sysdeps/viengoos/pt-sysdep.h | 2 +- libpthread/sysdeps/viengoos/pt-thread-alloc.c | 2 +- libpthread/sysdeps/viengoos/pt-thread-dealloc.c | 2 +- libpthread/sysdeps/viengoos/pt-thread-halt.c | 2 +- libpthread/sysdeps/viengoos/pt-thread-start.c | 2 +- libpthread/sysdeps/viengoos/pt-wakeup.c | 2 +- libviengoos/ChangeLog | 21 + libviengoos/Makefile.am | 40 + libviengoos/headers.m4 | 28 + libviengoos/t-addr-trans.c | 84 ++ libviengoos/t-addr.c | 74 ++ libviengoos/t-rpc.c | 185 ++++ libviengoos/viengoos.h | 1 + libviengoos/viengoos/activity.h | 254 +++++ libviengoos/viengoos/addr-trans.h | 190 ++++ libviengoos/viengoos/addr.h | 179 ++++ libviengoos/viengoos/cap.h | 730 ++++++++++++++ libviengoos/viengoos/folio.h | 441 ++++++++ libviengoos/viengoos/futex.h | 219 ++++ libviengoos/viengoos/ipc.h | 297 ++++++ libviengoos/viengoos/message.h | 229 +++++ libviengoos/viengoos/messenger.h | 87 ++ libviengoos/viengoos/misc.h | 128 +++ libviengoos/viengoos/rpc.h | 1054 ++++++++++++++++++++ libviengoos/viengoos/thread.h | 281 ++++++ newlib/addon/newlib/libc/sys/hurd/pipefile.c | 2 +- ruth/ruth.c | 12 +- viengoos/ChangeLog | 7 + viengoos/Makefile.am | 1 - viengoos/activity.c | 2 +- viengoos/activity.h | 2 +- viengoos/cap.c | 2 +- viengoos/cap.h | 2 +- viengoos/headers.m4 | 4 +- viengoos/messenger.c | 2 +- viengoos/messenger.h | 6 +- viengoos/object.c | 6 +- viengoos/object.h | 4 +- viengoos/rm.h | 128 --- viengoos/server.c | 10 +- viengoos/thread.c | 4 +- viengoos/thread.h | 4 +- viengoos/viengoos.c | 2 +- 110 files changed, 4795 insertions(+), 4617 deletions(-) delete mode 100644 hurd/activity.h delete mode 100644 hurd/addr-trans.h delete mode 100644 hurd/addr.h delete mode 100644 hurd/cap.h delete mode 100644 hurd/folio.h delete mode 100644 hurd/futex.h delete mode 100644 hurd/ipc.h delete mode 100644 hurd/message.h delete mode 100644 hurd/messenger.h delete mode 100644 hurd/rpc.h delete mode 100644 hurd/t-addr-trans.c delete mode 100644 hurd/t-addr.c delete mode 100644 hurd/t-rpc.c create mode 100644 libviengoos/ChangeLog create mode 100644 libviengoos/Makefile.am create mode 100644 libviengoos/headers.m4 create mode 100644 libviengoos/t-addr-trans.c create mode 100644 libviengoos/t-addr.c create mode 100644 libviengoos/t-rpc.c create mode 100644 libviengoos/viengoos.h create mode 100644 libviengoos/viengoos/activity.h create mode 100644 libviengoos/viengoos/addr-trans.h create mode 100644 libviengoos/viengoos/addr.h create mode 100644 libviengoos/viengoos/cap.h create mode 100644 libviengoos/viengoos/folio.h create mode 100644 libviengoos/viengoos/futex.h create mode 100644 libviengoos/viengoos/ipc.h create mode 100644 libviengoos/viengoos/message.h create mode 100644 libviengoos/viengoos/messenger.h create mode 100644 libviengoos/viengoos/misc.h create mode 100644 libviengoos/viengoos/rpc.h create mode 100644 libviengoos/viengoos/thread.h delete mode 100644 viengoos/rm.h diff --git a/ChangeLog b/ChangeLog index 684fe3b..d835308 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-12-17 Neal H. Walfield + + * libviengoos: New directory. + * Makefile.am (SUBDIRS): Add libviengoos. + * configure.ac: Include libviengoos/headers.m4. Generate + libviengoos/Makefile. + 2008-12-12 Neal H. Walfield * README: Move build requirements prior to build instructions. diff --git a/Makefile.am b/Makefile.am index d42e746..297e44b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,7 +31,7 @@ else endif if TRAVERSE_HIERARCHY -SUBDIRS = libl4 platform \ +SUBDIRS = libl4 libviengoos platform \ $(LIBC_SUBDIRS) $(NEWLIB_SUBDIRS) \ hurd libhurd-ihash libhurd-btree libbitarray \ libhurd-slab \ diff --git a/benchmarks/GCbench.c b/benchmarks/GCbench.c index 1b786be..eb3652e 100644 --- a/benchmarks/GCbench.c +++ b/benchmarks/GCbench.c @@ -88,8 +88,8 @@ static int iter; #ifdef __gnu_hurd_viengoos__ #include -#include -#include +#include +#include #include #include #include diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am index 67f7542..f1d8224 100644 --- a/benchmarks/Makefile.am +++ b/benchmarks/Makefile.am @@ -20,9 +20,9 @@ bootdir = $(prefix)/boot if ! ENABLE_TESTS -SUBDIRS = sqlite boehm-gc +SUBDIRS = sqlite # boehm-gc -boot_PROGRAMS = shared-memory-distribution activity-distribution cache gcbench +boot_PROGRAMS = shared-memory-distribution activity-distribution cache # gcbench endif shared_memory_distribution_CPPFLAGS = $(USER_CPPFLAGS) diff --git a/benchmarks/activity-distribution.c b/benchmarks/activity-distribution.c index 46724b6..52cc6a3 100644 --- a/benchmarks/activity-distribution.c +++ b/benchmarks/activity-distribution.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/benchmarks/boehm-gc/patches/05-viengoos-scheduler.patch b/benchmarks/boehm-gc/patches/05-viengoos-scheduler.patch index 10b5cc2..e986cdf 100644 --- a/benchmarks/boehm-gc/patches/05-viengoos-scheduler.patch +++ b/benchmarks/boehm-gc/patches/05-viengoos-scheduler.patch @@ -237,7 +237,7 @@ diff -uprN -x '*.applied' -x config.guess -x '*~' -x autom4te.cache -x config.su */ +#ifdef __gnu_hurd_viengoos__ -+#include ++#include +#include +#endif +#include @@ -678,8 +678,8 @@ diff -uprN -x '*.applied' -x config.guess -x '*~' -x autom4te.cache -x config.su } +#ifdef __gnu_hurd_viengoos__ -+#include -+#include ++#include ++#include +#include + +extern addr_t gc_activity __attribute__ ((weak)); diff --git a/benchmarks/cache.c b/benchmarks/cache.c index 11d0fc5..84942d8 100644 --- a/benchmarks/cache.c +++ b/benchmarks/cache.c @@ -181,8 +181,8 @@ static struct hurd_ihash cache; #ifdef __gnu_hurd_viengoos__ #include -#include -#include +#include +#include #include #include #include diff --git a/benchmarks/shared-memory-distribution.c b/benchmarks/shared-memory-distribution.c index 482f0c1..20e38d1 100644 --- a/benchmarks/shared-memory-distribution.c +++ b/benchmarks/shared-memory-distribution.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include diff --git a/configure.ac b/configure.ac index dfb43d6..52604d7 100644 --- a/configure.ac +++ b/configure.ac @@ -185,6 +185,7 @@ m4_include([viengoos/config.m4]) # Create links for header and library files. m4_include([libl4/headers.m4]) +m4_include([libviengoos/headers.m4]) m4_include([platform/headers.m4]) m4_include([hurd/headers.m4]) m4_include([libhurd-ihash/headers.m4]) @@ -313,6 +314,7 @@ AC_CONFIG_FILES([Makefile libl4/v2/Makefile libl4/v2/ia32/Makefile libl4/x2/Makefile libl4/tests/Makefile libl4/Makefile + libviengoos/Makefile platform/alpha/Makefile platform/amd64/Makefile platform/ia32/Makefile platform/ia64/Makefile platform/powerpc/Makefile platform/powerpc64/Makefile diff --git a/hieronymus/hieronymus.c b/hieronymus/hieronymus.c index 0d99c94..7a0d3da 100644 --- a/hieronymus/hieronymus.c +++ b/hieronymus/hieronymus.c @@ -18,13 +18,13 @@ along with this program. If not, see . */ -#include -#include +#include +#include +#include #include #include -#include #include -#include +#include #include #include diff --git a/hurd/ChangeLog b/hurd/ChangeLog index 34e3ba7..8b17eed 100644 --- a/hurd/ChangeLog +++ b/hurd/ChangeLog @@ -1,3 +1,39 @@ +2008-12-17 Neal H. Walfield + + * activity.h: Move to ../libviengoos/viengoos. Update references. + * addr-trans.h: Likewise. + * addr.h: Likewise. + * cap.h: Likewise. + * folio.h: Likewise. + * futex.h: Likewise. + * ipc.h: Likewise. + * message.h: Likewise. + * messenger.h: Likewise. + * rpc.h: Likewise. + * thread.h: Move viengoos specific bits... + * ../libviengoos/viengoos/thread.h: ... to this new file. + * thread.h (struct hurd_utcb): New structure. + * exceptions.h (hurd_utcb): Use a struct hurd_utcb *, not a + struct vg_utcb *. Update users. + (hurd_activation_state_alloc): Likewise. + (hurd_activation_state_free): Likewise. + (hurd_activation_handler_activated): Likewise. + (hurd_activation_handler_normal): Likewise. + * t-addr-trans.c: Move to ../libviengoos. + * t-addr.c: Likewise. + * t-rpc.c: Likewise. + * Makefile.am (TESTS, check_PROGRAMS, t_addr_CPPFLAGS) + (t_addr_SOURCES, t_addr_trans_CPPFLAGS, t_addr_trans_SOURCES) + (t_rpc_CPPFLAGS, t_rpc_SOURCES): Move from this file... + * ../libviengoos/Makefile.am. + * Makefile.am (includehurd_HEADERS): Don't mention activity.h, + addr-trans.h, addr.h, cap.h, folio.h, futex.h, ipc.h, message.h or + messenger.h. + * headers.m4: Don't create a link to hurd/addr.h, + hurd/addr-trans.h, hurd/cap.h, hurd/folio.h, hurd/rpc.h, + hurd/activity.h, hurd/futex.h, hurd/message.h, hurd/messenger.h or + hurd/ipc.h. + 2008-12-16 Neal H. Walfield * thread.h (struct vg_utcb): Remove field saved_thread_state. diff --git a/hurd/Makefile.am b/hurd/Makefile.am index f385acd..4eae77a 100644 --- a/hurd/Makefile.am +++ b/hurd/Makefile.am @@ -18,18 +18,6 @@ # along with this program. If not, see . includehurddir = $(includedir)/hurd -includehurd_HEADERS = rpc.h startup.h stddef.h types.h addr.h \ - addr-trans.h cap.h folio.h exceptions.h thread.h activity.h \ - lock.h mutex.h rmutex.h futex.h error.h trace.h - -TESTS = t-addr t-addr-trans t-rpc -check_PROGRAMS = $(TESTS) - -t_addr_CPPFLAGS = $(CHECK_CPPFLAGS) -t_addr_SOURCES = t-addr.c - -t_addr_trans_CPPFLAGS = $(CHECK_CPPFLAGS) -t_addr_trans_SOURCES = t-addr-trans.c - -t_rpc_CPPFLAGS = $(CHECK_CPPFLAGS) -t_rpc_SOURCES = t-rpc.c +includehurd_HEADERS = startup.h stddef.h types.h \ + exceptions.h thread.h \ + lock.h mutex.h rmutex.h error.h trace.h diff --git a/hurd/activity.h b/hurd/activity.h deleted file mode 100644 index dc77fc0..0000000 --- a/hurd/activity.h +++ /dev/null @@ -1,256 +0,0 @@ -/* activity.h - Activity definitions. - Copyright (C) 2007, 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - GNU Hurd is free software: you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with GNU Hurd. If not, see - . */ - -#ifndef _HURD_ACTIVITY_H -#define _HURD_ACTIVITY_H 1 - -#include -#include -#include - -enum - { - RM_activity_policy = 700, - RM_activity_info, - }; - -struct activity_memory_policy -{ - uint16_t priority; - uint16_t weight; -}; - -#define ACTIVITY_MEMORY_POLICY(__amp_priority, __amp_weight) \ - (struct activity_memory_policy) { __amp_priority, __amp_weight } -#define ACTIVITY_MEMORY_POLICY_VOID ACTIVITY_MEMORY_POLICY(0, 0) - -struct activity_policy -{ - /* This policy is typically set by the parent to reflect how - available memory should be distributed among its immediate - children. It may only be set via an activity control - capability. */ - struct activity_memory_policy sibling_rel; - - /* This policy is typically set by the activity user and controls - how the memory allocated *directly* to this activity is managed - relative to the memory allocated to this activity's children. - That is, if the activity has been choosen as a victim, this - provides a policy to determine whether the memory allocated - directly to the activity or that to a child activity should be - evicted. */ - struct activity_memory_policy child_rel; - - /* Number of folios. Zero means no limit. (This does not mean that - there is no limit, just that this activity does not impose a - limit. The parent activity, for instance, may impose a limit.) - May only be set via an activity control capability. */ - uint32_t folios; -}; - -/* Activity statistics. These are approximate and in some cases - represent averages. */ -#define ACTIVITY_STATS_PERIODS 2 -struct activity_stats -{ - /* The period during which this statistic was generated. */ - uint32_t period; - - /* The maximum number of frames this activity could currently - allocate assuming other allocations do not otherwise change. - This implies stealing from others. */ - uint32_t available; - uint32_t available_local; - - /* Log2 the maximum amount of memory (in pages) that the user of - this activity ought to allocate in the next few seconds. If - negative, the amount of memory the activity ought to consider - freeing. */ - int8_t damping_factor; - - /* If pressure is non-zero, then this activity is causing PRESSURE. - - PRESSURE is calculated as follows: if - - 1) this activity is within its entitlement - 2) its working set is significantly smaller than its allocation - (as determined by the size of inactive relative to active), and - 3) other activities are being held back (i.e., paging) due to this - activity, - - then this represents the amount of memory it would be nice to see - this activity free. This activity will not be penalized by the - system if it does not yield memory. However, if the activity has - memory which is yielding a low return, it would be friendly of it - to return it. */ - uint8_t pressure; - uint8_t pressure_local; - - /* The number of clean and dirty frames that are accounted to this - activity. (Does not include frames scheduled for eviction.) The - total number of frames accounted to this activity is thus CLEAN + - DIRTY. */ - uint32_t clean; - uint32_t dirty; - /* Number of frames pending eviction. */ - uint32_t pending_eviction; - - - /* Based on recency information, the number of active frames - accounted to this activity and its children. The number of - inactive frames is approximately CLEAN + DIRTY - ACTIVE. */ - uint32_t active; - /* Likewise, but excluding its children. */ - uint32_t active_local; - - /* Number of frames that were active in the last period that become - inactive in this period. */ - uint32_t became_active; - /* Number of frames that were inactive in the last period that - become active in this period. */ - uint32_t became_inactive; - - - /* Number of frames that were not accounted to this activity in the - last period and are now accounted to it. */ - uint32_t claimed; - /* Number of frames that were accounted to this activity in the last - period and are no longer accounted to it. */ - uint32_t disowned; - - /* The number of frames that this activity referenced but which are - accounted to some other activity. */ - uint32_t freeloading; - /* The sum of the references by other processes to the frames that - are accounted to this activity. (A single frame may account - for multiple references.) */ - uint32_t freeloaded; - - - /* Number of frames that were accounted to this activity and - scheduled for eviction. */ - uint32_t evicted; - /* Number of frames that were accounted to this activity (not its - children), had the discarded bit set, and were discarded. */ - uint32_t discarded; - /* Number of frames paged-in on behalf of this activity. This does - not include pages marked empty that do not require disk - activity. */ - uint32_t pagedin; - /* Number of frames that were referenced before being completely - freed. (If evicted is significant and saved approximates - evicted, then the process is trashing.) */ - uint32_t saved; -}; - -#define ACTIVITY_POLICY(__ap_sibling_rel, __ap_child_rel, __ap_storage) \ - (struct activity_policy) { __ap_sibling_rel, __ap_child_rel, __ap_storage } -#define ACTIVITY_POLICY_VOID \ - ACTIVITY_POLICY(ACTIVITY_MEMORY_POLICY_VOID, \ - ACTIVITY_MEMORY_POLICY_VOID, \ - 0) - -#define RPC_STUB_PREFIX rm -#define RPC_ID_PREFIX RM - -#include - -enum -{ - ACTIVITY_POLICY_CHILD_REL_PRIORITY_SET = 1 << 0, - ACTIVITY_POLICY_CHILD_REL_WEIGHT_SET = 1 << 1, - ACTIVITY_POLICY_SIBLING_REL_PRIORITY_SET = 1 << 2, - ACTIVITY_POLICY_SIBLING_REL_WEIGHT_SET = 1 << 3, - ACTIVITY_POLICY_STORAGE_SET = 1 << 4, - - ACTIVITY_POLICY_CHILD_REL_SET = (ACTIVITY_POLICY_CHILD_REL_PRIORITY_SET - | ACTIVITY_POLICY_CHILD_REL_WEIGHT_SET), - - ACTIVITY_POLICY_SIBLING_REL_SET = (ACTIVITY_POLICY_SIBLING_REL_PRIORITY_SET - | ACTIVITY_POLICY_SIBLING_REL_WEIGHT_SET), -}; - -/* Get ACTIVITY's policy and set according to FLAGS and IN. */ -RPC (activity_policy, 2, 1, 0, - /* cap_t principal, cap_t activity */ - uintptr_t, flags, struct activity_policy, in, - /* Out: */ - struct activity_policy, out); - -enum - { - /* Return statistics. */ - activity_info_stats = 1 << 0, - /* Asynchronous change in availability. */ - activity_info_pressure = 1 << 1, - }; - -struct activity_info -{ - /* The returned event. */ - uintptr_t event; - union - { - /* If EVENT is activity_info_stats. */ - struct - { - /* The number of samples. */ - int count; - /* Samples are ordered by recency with the youngest towards the - start of the buffer. */ - struct activity_stats stats[ACTIVITY_STATS_PERIODS]; - } stats; - - /* If EVENT is activity_info_free. */ - struct - { - /* The number of pages the caller should try to free (negative) - or may allocate (positive). */ - int amount; - } pressure; - }; -}; - -/* Return some information about the activity ACTIVITY. FLAGS is a - bit-wise or of events the caller is interested. Only one event - will be returned. - - If FLAGS contains activity_info_stats, may return the next - statistic that comes at or after UNTIL_PERIOD. (This can be used - to register a callback that is sent when the statistics are next - available. For example, call with UNTIL_PERIOD equal to 0 to get - the current statistics and then examine the period field. Use this - as the base for the next call.) - - If FLAGS contains activity_info_free, may return an upcall - indicating that the activity must free some memory or will be such - subject to paging. In this case, the activity should try to free - at least the indicated number of pages as quickly as possible. */ -RPC (activity_info, 2, 1, 0, - /* cap_t principal, cap_t activity, */ - uintptr_t, flags, uintptr_t, until_period, - /* Out: */ - struct activity_info, info) - -#undef RPC_STUB_PREFIX -#undef RPC_ID_PREFIX -#undef RPC_TARGET - -#endif diff --git a/hurd/addr-trans.h b/hurd/addr-trans.h deleted file mode 100644 index e7695e9..0000000 --- a/hurd/addr-trans.h +++ /dev/null @@ -1,190 +0,0 @@ -/* addr-trans.h - Address translation functions. - Copyright (C) 2007, 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - GNU Hurd is free software: you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with GNU Hurd. If not, see - . */ - -#ifndef _HURD_ADDR_TRANS_H -#define _HURD_ADDR_TRANS_H - -#include -#include -#include - -/* Capabilities have two primary functions: they designate objects and - they participate in address translation. This structure controls - how the page table walker translates bits when passing through this - capability. */ - -#define CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS 22 -#define CAP_ADDR_TRANS_SUBPAGES_BITS 4 -#define CAP_ADDR_TRANS_GDEPTH_BITS 6 - -struct cap_addr_trans -{ - union - { - struct - { - /* The value of the guard and the subpage to use. - - A capability page is partitioned into 2^SUBPAGES_LOG2 subpages. - This value determines the number of subpage index bits and - maximum number of guard bits. The number of subpage index bits - is SUBPAGES_LOG2 and the number of guard bits is the remainder - (the guard lies in the upper bits; the subpage in the lower). - - If SUBPAGES_LOG2 is 0, there is a single subpage (covering the - entire page). This implies that there are no subpage bits (the - only valid offset is 0) and 21 possible guard bits. If - SUBPAGES_LOG2 is 0, there are 256 subpages, 8 subpage bits and a - maximum of 21-8=15 guard bits. */ - uint32_t guard_subpage: CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS; - /* The log2 of the subpages. The size of a subpage is thus 2^(8 - - SUBPAGES_LOG2). Values of SUBPAGES_LOG2 other than 0 are only - allowed for cap pages. */ - uint32_t subpages_log2: CAP_ADDR_TRANS_SUBPAGES_BITS; - /* Number of significant guard bits. The value of the GUARD is zero - extended if GDEPTH is greater than the number of available guard - bits. */ - uint32_t gdepth: CAP_ADDR_TRANS_GDEPTH_BITS; - }; - uint32_t raw; - }; -}; - -#define CAP_ADDR_TRANS_INIT { { .raw = 0 } } -#define CAP_ADDR_TRANS_VOID (struct cap_addr_trans) { { .raw = 0 } } - -/* The log2 number of subpages. */ -#define CAP_ADDR_TRANS_SUBPAGES_LOG2(cap_addr_trans_) \ - ((cap_addr_trans_).subpages_log2) - -/* The number of subpages. */ -#define CAP_ADDR_TRANS_SUBPAGES(cap_addr_trans_) \ - (1 << CAP_ADDR_TRANS_SUBPAGES_LOG2((cap_addr_trans_))) - -/* The designated subpage. */ -#define CAP_ADDR_TRANS_SUBPAGE(cap_addr_trans_) \ - ((cap_addr_trans_).guard_subpage \ - & (CAP_ADDR_TRANS_SUBPAGES ((cap_addr_trans_)) - 1)) - -/* The log2 of the size of the named subpage (in capability - units). */ -#define CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2(cap_addr_trans_) \ - (8 - (cap_addr_trans_).subpages_log2) - -/* The number of caps addressed by this capability. */ -#define CAP_ADDR_TRANS_SUBPAGE_SIZE(cap_addr_trans_) \ - (1 << CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 ((cap_addr_trans_))) - -/* The offset in capability units (with respect to the start of the - capability page) of the first capability in the designated - sub-page. */ -#define CAP_ADDR_TRANS_SUBPAGE_OFFSET(cap_addr_trans_) \ - (CAP_ADDR_TRANS_SUBPAGE ((cap_addr_trans_)) \ - * CAP_ADDR_TRANS_SUBPAGE_SIZE ((cap_addr_trans_))) - -/* The number of guard bits. */ -#define CAP_ADDR_TRANS_GUARD_BITS(cap_addr_trans_) ((cap_addr_trans_).gdepth) - -/* The value of the guard. */ -#define CAP_ADDR_TRANS_GUARD(cap_addr_trans_) \ - ((uint64_t) ((cap_addr_trans_).guard_subpage \ - >> (cap_addr_trans_).subpages_log2)) - -#define CATSGST_(test_, format, args...) \ - if (! (test_)) \ - { \ - r_ = false; \ - debug (1, format, ##args); \ - } - -/* Set CAP_ADDR_TRANS_P_'s guard and the subpage. Returns true on success - (parameters valid), false otherwise. */ -#define CAP_ADDR_TRANS_SET_GUARD_SUBPAGE(cap_addr_trans_p_, guard_, gdepth_, \ - subpage_, subpages_) \ - ({ bool r_ = true; \ - /* There must be at least 1 subpage. */ \ - CATSGST_ (((subpages_) > 0), \ - "subpages_ (%d) must be at least 1\n", (subpages_)); \ - CATSGST_ (((subpages_) & ((subpages_) - 1)) == 0, \ - "SUBPAGES_ (%d) must be a power of 2\n", (subpages_)); \ - int subpages_log2_ = vg_msb ((subpages_)) - 1; \ - CATSGST_ (subpages_log2_ <= 8, \ - "maximum subpages is 256 (%d)\n", (subpages_)); \ - CATSGST_ (0 <= (subpage_) && (subpage_) < (subpages_), \ - "subpage (%d) must be between 0 and SUBPAGES_ (%d) - 1\n", \ - (subpage_), (subpages_)); \ - \ - /* The number of required guard bits. */ \ - int gbits_ = vg_msb64 ((guard_)); \ - CATSGST_ (gbits_ <= (gdepth_), \ - "Significant guard bits (%d) must be less than depth (%d)\n", \ - gbits_, (gdepth_)); \ - CATSGST_ (gbits_ + subpages_log2_ <= CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS, \ - "Significant guard bits (%d) plus subpage bits (%d) > %d\n", \ - gbits_, subpages_log2_, CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS); \ - \ - if (r_) \ - { \ - (cap_addr_trans_p_)->subpages_log2 = subpages_log2_; \ - (cap_addr_trans_p_)->gdepth = (gdepth_); \ - (cap_addr_trans_p_)->guard_subpage \ - = ((guard_) << subpages_log2_) | (subpage_); \ - } \ - r_; \ - }) - -/* Set *CAP_ADDR_TRANS_P_'s guard. Returns true on success (parameters - valid), false otherwise. */ -#define CAP_ADDR_TRANS_SET_GUARD(cap_addr_trans_p_, guard_, gdepth_) \ - ({ int subpage_ = CAP_ADDR_TRANS_SUBPAGE (*(cap_addr_trans_p_)); \ - int subpages_ = CAP_ADDR_TRANS_SUBPAGES (*(cap_addr_trans_p_)); \ - CAP_ADDR_TRANS_SET_GUARD_SUBPAGE ((cap_addr_trans_p_), \ - (guard_), (gdepth_), \ - (subpage_), (subpages_)); \ - }) - -/* Set *CAP_ADDR_TRANS_P_'s subpage. Returns true on success (parameters - valid), false otherwise. */ -#define CAP_ADDR_TRANS_SET_SUBPAGE(cap_addr_trans_p_, subpage_, subpages_) \ - ({ int gdepth_ = CAP_ADDR_TRANS_GUARD_BITS (*(cap_addr_trans_p_)); \ - int guard_ = CAP_ADDR_TRANS_GUARD (*(cap_addr_trans_p_)); \ - CAP_ADDR_TRANS_SET_GUARD_SUBPAGE ((cap_addr_trans_p_), \ - (guard_), (gdepth_), \ - (subpage_), (subpages_)); \ - }) - -/* Returns whether the capability address CAP_ADDR_TRANS is well-formed. */ -#define CAP_ADDR_TRANS_VALID(cap_addr_trans) \ - ({ bool r_ = true; \ - CATSGST_ (CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans) <= WORDSIZE, \ - "Invalid guard depth (%d)", \ - CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans)); \ - CATSGST_ (CAP_ADDR_TRANS_SUBPAGES_LOG2 (cap_addr_trans) <= 8, \ - "Invalid number of subpages (%d)", \ - CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans)); \ - CATSGST_ (vg_msb (CAP_ADDR_TRANS_GUARD (cap_addr_trans)) \ - <= CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans), \ - "Significant guard bits (%d) exceeds guard depth (%d)", \ - vg_msb (CAP_ADDR_TRANS_GUARD (cap_addr_trans)), \ - CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans)); \ - r_; \ - }) - -#endif diff --git a/hurd/addr.h b/hurd/addr.h deleted file mode 100644 index 40092b2..0000000 --- a/hurd/addr.h +++ /dev/null @@ -1,179 +0,0 @@ -/* addr.h - Address definitions. - Copyright (C) 2007, 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _HURD_ADDR_H -#define _HURD_ADDR_H 1 - -#include -#include -#include - -#include - -/* Addresses are 64-bits wide and translate up to 63 bits. They are - composed of a depth and a prefix that is depth bits wide. - - The 64-bit field is packed as follows: the upper bits are encoded - in binary and represent the prefix, these are followed by a single - bit that is on, which is followed by a number encoded in unary. - The value of the unary number is 63 - depth. This allows easy - calculation of the depth and extraction of the prefix. Thus, - given: - - xxxxx100 - - The unary value is 2 yielding a depth of 63 - 2 = 61. These bits - are encoded in the upper DEPTH bits of the field. - - Leaves thus have a 1 in the least significant bit and nodes a - 0. */ -struct addr -{ - uint64_t raw; -}; -#define ADDR_BITS 63 -/* Client-side capability handle. */ -typedef struct addr addr_t; - -#define ADDR_FMT "%llx/%d" -#define ADDR_PRINTF(addr_) addr_prefix ((addr_)), addr_depth ((addr_)) - -/* Create an address given a prefix and a depth. */ -#define ADDR(prefix_, depth_) \ - ({ \ - uint64_t p_ = (prefix_); \ - uint64_t d_ = (depth_); \ - assert (0 <= d_ && d_ <= ADDR_BITS); \ - assert ((p_ & ((1 << (ADDR_BITS - d_)) - 1)) == 0); \ - assert (p_ < (1ULL << ADDR_BITS)); \ - (struct addr) { (p_ << 1ULL) | (1ULL << (ADDR_BITS - d_)) }; \ - }) - -/* Create an address given a prefix and a depth. Appropriate for use - as an initializer. */ -#define ADDR_INIT(prefix_, depth_) \ - { .raw = ((((prefix_) << 1) | 1) << (ADDR_BITS - (depth_))) } - -#define ADDR_VOID ((struct addr) { 0ULL }) -#define ADDR_EQ(a, b) (a.raw == b.raw) -#define ADDR_IS_VOID(a) (ADDR_EQ (a, ADDR_VOID)) - -/* Return ADDR_'s depth. */ -static inline int -addr_depth (addr_t addr) -{ - return ADDR_BITS - (vg_lsb64 (addr.raw) - 1); -} - -/* Return ADDR's prefix. */ -static inline uint64_t -addr_prefix (addr_t addr) -{ - /* (Clear the boundary bit and shift right 1.) */ - return (addr.raw & ~(1ULL << (ADDR_BITS - addr_depth (addr)))) >> 1; -} - -/* Extend the address ADDR by concatenating the lowest DEPTH bits of - PREFIX. */ -#if 0 -static inline addr_t -addr_extend (addr_t addr, uint64_t prefix, int depth) -{ - assertx (depth >= 0, "depth: %d", depth); - assertx (addr_depth (addr) + depth <= ADDR_BITS, - "addr: " ADDR_FMT "; depth: %d", ADDR_PRINTF (addr), depth); - assertx (prefix < (1ULL << depth), - "prefix: %llx; depth: %lld", prefix, 1ULL << depth); - return ADDR (addr_prefix (addr) - | (prefix << (ADDR_BITS - addr_depth (addr) - depth)), - addr_depth (addr) + depth); -} -#else -#define addr_extend(addr_, prefix_, depth_) \ - ({ \ - addr_t a__ = (addr_); \ - uint64_t p__ = (prefix_); \ - int d__ = (depth_); \ - assertx (d__ >= 0, "depth: %d", d__); \ - assertx (addr_depth ((a__)) + (d__) <= ADDR_BITS, \ - "addr: " ADDR_FMT "; depth: %d", ADDR_PRINTF (a__), d__); \ - assertx (p__ < (1ULL << d__), \ - "prefix: %llx; depth: %lld", p__, 1ULL << d__); \ - ADDR (addr_prefix ((a__)) \ - | ((p__) << (ADDR_BITS - addr_depth ((a__)) - (d__))), \ - addr_depth ((a__)) + (d__)); \ - }) -#endif - -/* Decrease the depth of ADDR by DEPTH. */ -static inline addr_t -addr_chop (addr_t addr, int depth) -{ - int d = addr_depth (addr) - depth; - assert (d >= 0); - - return ADDR (addr_prefix (addr) & ~((1ULL << (ADDR_BITS - d)) - 1), d); -} - -/* Return the last WIDTH bits of address's ADDR prefix. */ -static inline uint64_t -addr_extract (addr_t addr, int width) -{ - assert (width <= addr_depth (addr)); - - return (addr_prefix (addr) >> (ADDR_BITS - addr_depth (addr))) - & ((1ULL << width) - 1); -} - -/* Convert an address to a pointer. The address must name an object - mapped in the machine data instruction accessible part of the - address space. */ -#define ADDR_TO_PTR(addr_) \ - ({ \ - assert (addr_prefix ((addr_)) < ((uintptr_t) -1)); \ - assert (addr_depth ((addr_)) == ADDR_BITS); \ - (void *) (uintptr_t) addr_prefix ((addr_)); \ - }) - -/* Convert a pointer to an address. */ -#define PTR_TO_ADDR(ptr_) \ - (ADDR ((uintptr_t) (ptr_), ADDR_BITS)) - -/* Return the address of the page that would contain pointer PTR_. */ -#define PTR_TO_PAGE(ptr_) \ - addr_chop (ADDR ((uintptr_t) (ptr_), ADDR_BITS), PAGESIZE_LOG2) - -static inline addr_t -addr_add (addr_t addr, uint64_t count) -{ - int w = ADDR_BITS - addr_depth (addr); - - return ADDR (addr_prefix (addr) + (count << w), - addr_depth (addr)); -} - -static inline addr_t -addr_sub (addr_t addr, uint64_t count) -{ - return addr_add (addr, - count); -} - -#endif diff --git a/hurd/cap.h b/hurd/cap.h deleted file mode 100644 index 0dd3e82..0000000 --- a/hurd/cap.h +++ /dev/null @@ -1,730 +0,0 @@ -/* cap.h - Capability definitions. - Copyright (C) 2007, 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - GNU Hurd is free software: you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with GNU Hurd. If not, see - . */ - -#ifndef _HURD_CAP_H -#define _HURD_CAP_H 1 - -#include -#include -#include -#include -#include -#include -#include -#include - -/* Capabilities. - - Capabilities have three functions: a capability can designate an - object, it can participate in address translation, and it can be - used to control how the designated object should be managed. */ - -/* The types of objects designated by capabilities. */ -enum cap_type - { -#define CAP_TYPE_MIN cap_void - cap_void, - cap_page, - cap_rpage, - cap_cappage, - cap_rcappage, - cap_folio, - cap_activity, - cap_activity_control, - cap_thread, - cap_messenger, - cap_rmessenger, - cap_type_count, -#define CAP_TYPE_MAX (cap_type_count - 1) - }; - -static inline const char * -cap_type_string (enum cap_type type) -{ - switch (type) - { - case cap_void: - return "void"; - case cap_page: - return "page"; - case cap_rpage: - return "rpage"; - case cap_cappage: - return "cappage"; - case cap_rcappage: - return "rcappage"; - case cap_folio: - return "folio"; - case cap_activity: - return "activity"; - case cap_activity_control: - return "activity_control"; - case cap_thread: - return "thread"; - case cap_messenger: - return "messenger"; - case cap_rmessenger: - return "rmessenger"; - default: - return "unknown cap type"; - }; -} - -/* Return whether two types are compatible in the sense that two caps - with the given types can designate the same object. */ -static inline bool -cap_types_compatible (enum cap_type a, enum cap_type b) -{ - if (a == b) - return true; - - if (a == cap_page && b == cap_rpage) - return true; - if (a == cap_rpage && b == cap_page) - return true; - - if (a == cap_cappage && b == cap_rcappage) - return true; - if (a == cap_rcappage && b == cap_cappage) - return true; - - if (a == cap_activity && b == cap_activity_control) - return true; - if (a == cap_activity_control && b == cap_activity) - return true; - - if (a == cap_messenger && b == cap_rmessenger) - return true; - if (a == cap_rmessenger && b == cap_messenger) - return true; - - return false; -} - -/* Returns weather TYPE corresponds to a weak type. */ -static inline bool -cap_type_weak_p (enum cap_type type) -{ - switch (type) - { - case cap_rpage: - case cap_rcappage: - case cap_activity: - case cap_rmessenger: - return true; - - default: - return false; - } -} - -/* Returns the weakened type corresponding to TYPE. If type is - already a weak type, returns TYPE. */ -static inline enum cap_type -cap_type_weaken (enum cap_type type) -{ - switch (type) - { - case cap_page: - case cap_rpage: - return cap_rpage; - - case cap_cappage: - case cap_rcappage: - return cap_rcappage; - - case cap_activity_control: - case cap_activity: - return cap_activity; - - case cap_messenger: - case cap_rmessenger: - return cap_rmessenger; - - default: - return cap_void; - } -} - -/* Returns the strong type corresponding to TYPE. If type is already - a strong type, returns TYPE. */ -static inline enum cap_type -cap_type_strengthen (enum cap_type type) -{ - switch (type) - { - case cap_page: - case cap_rpage: - return cap_page; - - case cap_cappage: - case cap_rcappage: - return cap_cappage; - - case cap_activity_control: - case cap_activity: - return cap_activity_control; - - case cap_messenger: - case cap_rmessenger: - return cap_messenger; - - default: - return type; - } -} - -/* Object policy. */ - -/* The object priority is a signed 7-bit number (-64 -> 63). A lower - numeric value corresponds to a lower priority. */ -#define OBJECT_PRIORITY_BITS 7 -#define OBJECT_PRIORITY_LEVELS (1 << OBJECT_PRIORITY_BITS) -#define OBJECT_PRIORITY_MIN (-(1 << (OBJECT_PRIORITY_BITS - 1))) -#define OBJECT_PRIORITY_DEFAULT (0) -#define OBJECT_PRIORITY_MAX ((1 << (OBJECT_PRIORITY_BITS - 1)) - 1) - -struct object_policy -{ - union - { - struct - { - /* Whether a page is discardable (if so and the page is not - zero, trying to read the page from disk generates a first - fault fault). */ - int8_t discardable : 1; - - /* An object's priority. If can be used to override LRU - eviction. When a memory object is to be evicted, we select - the object with the lowest priority (higher value = lower - priority). */ - int8_t priority : OBJECT_PRIORITY_BITS; - }; - uint8_t raw; - }; -}; - -#define OBJECT_POLICY_INIT { { raw: 0 } } -#define OBJECT_POLICY(__op_discardable, __op_priority) \ - (struct object_policy) { { { (__op_discardable), (__op_priority) } } } -/* The default object policy: not discardable, managed by LRU. */ -#define OBJECT_POLICY_VOID \ - OBJECT_POLICY (false, OBJECT_PRIORITY_DEFAULT) -/* Synonym for OBJECT_POLICY_VOID. */ -#define OBJECT_POLICY_DEFAULT OBJECT_POLICY_VOID - -/* Capability properties. */ - -struct cap_properties -{ - struct object_policy policy; - struct cap_addr_trans addr_trans; -}; - -#define CAP_PROPERTIES_INIT \ - { OBJECT_POLICY_INIT, CAP_ADDR_TRANS_INIT } -#define CAP_PROPERTIES(__op_object_policy, __op_addr_trans) \ - (struct cap_properties) { __op_object_policy, __op_addr_trans } -#define CAP_PROPERTIES_VOID \ - CAP_PROPERTIES (OBJECT_POLICY_INIT, CAP_ADDR_TRANS_INIT) -#define CAP_PROPERTIES_DEFAULT CAP_PROPERTIES_VOID - -/* Capability representation. */ - -#ifdef RM_INTERN -/* An OID corresponds to a page on a volume. Only the least 54 bits - are significant. */ -typedef uint64_t oid_t; -#define OID_FMT "0x%llx" -#define OID_PRINTF(__op_oid) ((oid_t) (__op_oid)) -#endif - -#define CAP_VERSION_BITS 20 -#define CAP_TYPE_BITS 6 - -struct cap -{ -#ifdef RM_INTERN - /* For a description of how versioning works, refer to the comment - titled "Object versioning" in object.h. */ - uint32_t version : CAP_VERSION_BITS; - /* Whether the capability is weak. */ - uint32_t weak_p : 1; - - /* Whether the designated object may be discarded. */ - uint32_t discardable : 1; - /* The designated object's priority. */ - int32_t priority : OBJECT_PRIORITY_BITS; - - struct cap_addr_trans addr_trans; - - uint64_t type : CAP_TYPE_BITS; - - /* If the capability designates an object, the object id. */ - uint64_t oid : 64 - CAP_TYPE_BITS; -#else - /* The shadow object (only for cappages and folios). */ - struct object *shadow; - - uint32_t discardable : 1; - int32_t priority : OBJECT_PRIORITY_BITS; - - uint32_t type : CAP_TYPE_BITS; - - uint32_t pad0 : 32 - 1 - OBJECT_PRIORITY_BITS - CAP_TYPE_BITS; - - /* This capability's address description. */ - struct cap_addr_trans addr_trans; -#endif -}; - -#define CAP_VOID ((struct cap) { .type = cap_void }) - -/* Return CAP's policy. */ -#define CAP_POLICY_GET(__cpg_cap) \ - OBJECT_POLICY ((__cpg_cap).discardable, (__cpg_cap).priority) -/* Set CAP's policy to POLICY. */ -#define CAP_POLICY_SET(__cps_cap, __cps_policy) \ - do \ - { \ - (__cps_cap)->discardable = (__cps_policy).discardable; \ - (__cps_cap)->priority = (__cps_policy).priority; \ - } \ - while (0) - -/* Return CAP's properties. */ -#define CAP_PROPERTIES_GET(__cpg_cap) \ - CAP_PROPERTIES (CAP_POLICY_GET (__cpg_cap), \ - (__cpg_cap).addr_trans) -/* Set *CAP's properties to PROPERTIES. */ -#define CAP_PROPERTIES_SET(__cps_cap, __cps_properties) \ - do \ - { \ - CAP_POLICY_SET (__cps_cap, (__cps_properties).policy); \ - (__cps_cap)->addr_trans = (__cps_properties).addr_trans; \ - } \ - while (0) - -/* Convenience macros for printing capabilities. */ - -#ifdef RM_INTERN -#define CAP_FMT "{ " OID_FMT ".%d:%s %llx/%d; %d/%d }" -#define CAP_PRINTF(cap) \ - OID_PRINTF ((cap)->oid), (cap)->version, cap_type_string ((cap)->type), \ - CAP_GUARD ((cap)), CAP_GUARD_BITS ((cap)), \ - CAP_SUBPAGE ((cap)), CAP_SUBPAGES ((cap)) -#else -#define CAP_FMT "{ %s %llx/%d; %d/%d }" -#define CAP_PRINTF(cap) \ - cap_type_string ((cap)->type), \ - CAP_GUARD ((cap)), CAP_GUARD_BITS ((cap)), \ - CAP_SUBPAGE ((cap)), CAP_SUBPAGES ((cap)) -#endif - -/* Accessors corresponding to the CAP_ADDR_TRANS macros. */ -#define CAP_SUBPAGES_LOG2(cap_) \ - CAP_ADDR_TRANS_SUBPAGES_LOG2((cap_)->addr_trans) -#define CAP_SUBPAGES(cap_) CAP_ADDR_TRANS_SUBPAGES ((cap_)->addr_trans) -#define CAP_SUBPAGE(cap_) CAP_ADDR_TRANS_SUBPAGE((cap_)->addr_trans) -#define CAP_SUBPAGE_SIZE_LOG2(cap_) \ - CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 ((cap_)->addr_trans) -#define CAP_SUBPAGE_SIZE(cap_) \ - CAP_ADDR_TRANS_SUBPAGE_SIZE ((cap_)->addr_trans) -#define CAP_SUBPAGE_OFFSET(cap_) \ - CAP_ADDR_TRANS_SUBPAGE_OFFSET((cap_)->addr_trans) -#define CAP_GUARD_BITS(cap_) CAP_ADDR_TRANS_GUARD_BITS((cap_)->addr_trans) -#define CAP_GUARD(cap_) CAP_ADDR_TRANS_GUARD((cap_)->addr_trans) - -/* NB: Only updates the shadow guard; NOT the capability. If the - latter behavior is desired, use cap_copy_x instead. */ -#define CAP_SET_GUARD_SUBPAGE(cap_, guard_, gdepth_, subpage_, subpages_) \ - ({ bool r_ = true; \ - if ((subpages_) != 1 \ - && ! ((cap_)->type == cap_cappage || (cap_)->type == cap_rcappage)) \ - { \ - debug (1, "Subpages are only allow for cappages."); \ - r_ = false; \ - } \ - if (r_) \ - r_ = CAP_ADDR_TRANS_SET_GUARD_SUBPAGE (&(cap_)->addr_trans, \ - (guard_), (gdepth_), \ - (subpage_), (subpages_)); \ - r_; \ - }) - -#define CAP_SET_GUARD(cap_, guard_, gdepth_) \ - CAP_SET_GUARD_SUBPAGE ((cap_), (guard_), (gdepth_), \ - CAP_SUBPAGE ((cap_)), CAP_SUBPAGES ((cap_))) -#define CAP_SET_SUBPAGE(cap_, subpage_, subpages_) \ - CAP_SET_GUARD_SUBPAGE ((cap_), CAP_GUARD (cap_), CAP_GUARD_BITS (cap_), \ - (subpage_), (subpages_)) - -/* Capability-related methods. */ - -#define RPC_STUB_PREFIX rm -#define RPC_ID_PREFIX RM - -#include - -enum - { - RM_cap_copy = 300, - RM_cap_rubout, - RM_cap_read, - - RM_object_discarded_clear = 400, - RM_object_discard, - RM_object_status, - RM_object_reply_on_destruction, - RM_object_name, - }; - -enum -{ - /* Use subpage in CAP_ADDR_TRANS (must be a subset of subpage in - SOURCE). */ - CAP_COPY_COPY_ADDR_TRANS_SUBPAGE = 1 << 0, - /* Use guard in TARGET, not the guard in CAP_ADDR_TRANS. */ - CAP_COPY_COPY_ADDR_TRANS_GUARD = 1 << 1, - /* Use guard in SOURCE. */ - CAP_COPY_COPY_SOURCE_GUARD = 1 << 2, - - /* When copying the capability copies a weakened reference. */ - CAP_COPY_WEAKEN = 1 << 3, - - /* Set the discardable bit on the capability. */ - CAP_COPY_DISCARDABLE_SET = 1 << 4, - - /* Set the priority of the object. */ - CAP_COPY_PRIORITY_SET = 1 << 5, -}; - -/* Copy the capability in capability slot SOURCE to the slot at ADDR - in the object OBJECT. If OBJECT is ADDR_VOID, then the calling - thread's address space root is used. - - By default, preserves SOURCE's subpage specification and copies - TARGET's guard and policy. - - If CAP_COPY_COPY_SUBPAGE is set, then uses the subpage - specification in CAP_PROPERTIES. If CAP_COPY_COPY_ADDR_TRANS_GUARD - is set, uses the guard description in CAP_PROPERTIES. - - If CAP_COPY_COPY_SOURCE_GUARD is set, uses the guard description in - source. Otherwise, preserves the guard in TARGET. - - If CAP_COPY_WEAKEN is set, saves a weakened version of SOURCE - (e.g., if SOURCE's type is cap_page, a cap_rpage is saved). - - If CAP_COPY_DISCARDABLE_SET is set, then sets the discardable bit - based on the value in PROPERTIES. Otherwise, copies SOURCE's - value. - - If CAP_COPY_PRIORITY_SET is set, then sets the priority based on - the value in properties. Otherwise, copies SOURCE's value. */ -RPC(cap_copy, 5, 0, 0, - /* cap_t activity, cap_t object, */ addr_t, addr, - cap_t, source_object, addr_t, source_addr, - uintptr_t, flags, struct cap_properties, properties) - -/* Overwrite the capability slot at ADDR in the object OBJECT with a - void capability. */ -RPC(cap_rubout, 1, 0, 0, - /* cap_t activity, cap_t object, */ addr_t, addr) - -/* Returns the public bits of the capability at address ADDR in OBJECT - in TYPE and CAP_PROPERTIES. */ -RPC(cap_read, 1, 2, 0, - /* cap_t activity, cap_t object, */ addr_t, addr, - /* Out: */ - uintptr_t, type, struct cap_properties, properties) - -/* Clear the discarded bit of the object at ADDR in object OBJECT. */ -RPC(object_discarded_clear, 1, 0, 0, - /* cap_t activity, cap_t object, */ addr_t, addr) - -/* If the object designated by OBJECT is in memory, discard it. - OBJECT must have write authority. This does not set the object's - discarded bit and thus does not result in a fault. Instead, the - next access will see, e.g., zero-filled memory. */ -RPC(object_discard, 0, 0, 0 - /* cap_t activity, cap_t object, */) - -enum -{ - object_dirty = 1 << 0, - object_referenced = 1 << 1, -}; - -/* Returns whether OBJECT is dirty. If CLEAR is set, the dirty bit is - clear. An object's dirty bit is set when the object is modified. - (Note: this is not the state of a frame but an indication of - whether the object has been modified since the last time it the - dirty bit was cleared.) */ -RPC (object_status, 1, 1, 0, - /* addr_t activity, addr_t object, */ bool, clear, - uintptr_t, status) - -/* Returns the object's return code in RETURN_CODE on object - destruction. */ -RPC (object_reply_on_destruction, 0, 1, 0, - /* cap_t principal, cap_t object, */ - /* Out: */ - uintptr_t, return_code); - -struct object_name -{ - char name[12]; -}; - -/* Give object OBJECT a name. This is only used for debugging - purposes and is only supported by some objects, in particular, - activities and threads. */ -RPC (object_name, 1, 0, 0, - /* cap_t activity, cap_t object, */ struct object_name, name); - - -#undef RPC_STUB_PREFIX -#undef RPC_ID_PREFIX - -/* An object. */ - -/* The number of capabilities per page. */ -enum - { - CAPPAGE_SLOTS = PAGESIZE / 16, - }; -/* The log2 of the number of capabilities per page. */ -enum - { - CAPPAGE_SLOTS_LOG2 = PAGESIZE_LOG2 - 4, - }; - -struct object -{ - union - { - char data[PAGESIZE]; - struct cap caps[CAPPAGE_SLOTS]; - }; -}; - -#ifdef RM_INTERN -typedef struct activity *activity_t; -#else -typedef addr_t activity_t; -#endif - -#ifndef RM_INTERN -/* Return the address of cap CAP's shadow object. */ -static inline void * -cap_get_shadow (const struct cap *cap) -{ - return cap->shadow; -} - -/* Set CAP's shadow object to SHADOW. */ -static inline void -cap_set_shadow (struct cap *cap, void *shadow) -{ - cap->shadow = shadow; -} -#endif - -/* Given cap CAP, return the corresponding object, or NULL, if there - is none. */ -#ifdef RM_INTERN -extern struct object *cap_to_object (activity_t activity, struct cap *cap); -#else -static inline struct object * -cap_to_object (activity_t activity, struct cap *cap) -{ - return cap_get_shadow (cap); -} -#endif - -/* Wrapper for the cap_copy method. Also updates shadow - capabilities. */ -static inline bool -cap_copy_x (activity_t activity, - addr_t target_address_space, struct cap *target, addr_t target_addr, - addr_t source_address_space, struct cap source, addr_t source_addr, - int flags, struct cap_properties properties) -{ - /* By default, we preserve SOURCE's subpage specification. */ - int subpage = CAP_SUBPAGE (&source); - int subpages = CAP_SUBPAGES (&source); - - if ((flags & CAP_COPY_COPY_ADDR_TRANS_SUBPAGE)) - /* Copy the subpage descriptor from PROPERTIES.ADDR_TRANS. */ - { - if (CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans) != 1 - && (source.type != cap_cappage - && source.type != cap_rcappage)) - /* A subpage descriptor is only valid for - cappages. */ - { - debug (1, "subpages (%d) specified for non-cappage " - "cap " CAP_FMT, - CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans), - CAP_PRINTF (&source)); - return false; - } - - if (! - (/* Start of PROPERTIES.ADDR_TRANS must be at or after start of - SOURCE. */ - subpage * (256 / subpages) - <= (CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans) * - (256 / CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans))) - /* End of PROPERTIES.ADDR_TRANS must be before or at end of - SOURCE. */ - && (((CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans) + 1) * - (256 / CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans))) - <= (subpage + 1) * (256 / subpages)))) - /* The subpage descriptor does not narrow the - rights. */ - { - debug (1, "specified subpage (%d/%d) not a subset " - " of source " CAP_FMT, - CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans), - CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans), - CAP_PRINTF (&source)); - return false; - } - - subpage = CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans); - subpages = CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans); - } - - /* By default, we preserve the guard in TARGET. */ - int guard = CAP_GUARD (target); - int gbits = CAP_GUARD_BITS (target); - - if ((flags & CAP_COPY_COPY_ADDR_TRANS_GUARD)) - /* Copy guard from PROPERTIES.ADDR_TRANS. */ - { - guard = CAP_ADDR_TRANS_GUARD (properties.addr_trans); - gbits = CAP_ADDR_TRANS_GUARD_BITS (properties.addr_trans); - } - else if ((flags & CAP_COPY_COPY_SOURCE_GUARD)) - /* Copy guard from SOURCE. */ - { - guard = CAP_GUARD (&source); - gbits = CAP_GUARD_BITS (&source); - } - - int type = source.type; - if ((flags & CAP_COPY_WEAKEN)) - type = cap_type_weaken (type); - -#ifdef RM_INTERN - /* Changing a capability can change how addresses are translated. - In this case, we need to shoot down all cached translations. */ - bool changes_translation = false; - - if (target->oid != source.oid) - { - debug (5, "OID mismatch, changes translation"); - changes_translation = true; - } - else if (target->version != source.version) - { - debug (5, "Version mismatch, changes translation"); - changes_translation = true; - } - - if (subpage != CAP_SUBPAGE (target) || subpages != CAP_SUBPAGES (target)) - { - debug (5, "Subpage specification differs %d/%d -> %d/%d.", - subpage, subpages, CAP_SUBPAGE (target), CAP_SUBPAGES (target)); - changes_translation = true; - } - - if (guard != CAP_GUARD (target) - || gbits != CAP_GUARD_BITS (target)) - { - debug (5, "Guard changed invalidating translation " - "0x%x/%d -> %llx/%d", - guard, gbits, CAP_GUARD (target), CAP_GUARD_BITS (target)); - changes_translation = true; - } - - if (type != target->type) - { - debug (5, "Type changed, invalidating translation"); - changes_translation = true; - } - - if (changes_translation) - { - extern void cap_shootdown (struct activity *activity, struct cap *cap); - - debug (5, "Translation changed: " CAP_FMT " -> " CAP_FMT, - CAP_PRINTF (target), CAP_PRINTF (&source)); - - cap_shootdown (activity, target); - } -#endif - - if (! CAP_ADDR_TRANS_SET_GUARD_SUBPAGE (&properties.addr_trans, - guard, gbits, - subpage, subpages)) - return false; - -#ifndef RM_INTERN - assert (! ADDR_IS_VOID (target_addr)); - assert (! ADDR_IS_VOID (source_addr)); - - error_t err = rm_cap_copy (activity, target_address_space, target_addr, - source_address_space, source_addr, - flags, properties); - assert (err == 0); -#endif - - *target = source; - target->addr_trans = properties.addr_trans; - target->type = type; - - if ((flags & CAP_COPY_DISCARDABLE_SET)) - target->discardable = properties.policy.discardable; - - if ((flags & CAP_COPY_PRIORITY_SET)) - target->priority = properties.policy.priority; - - return true; -} - -/* Copy the capability SOURCE to capability TARGET. Preserves - SOURCE's subpage specification and TARGET's guard. Copies SOURCE's - policy. */ -static inline bool -cap_copy (activity_t activity, - addr_t target_as, struct cap *target, addr_t target_addr, - addr_t source_as, struct cap source, addr_t source_addr) -{ - return cap_copy_x (activity, target_as, target, target_addr, - source_as, source, source_addr, - CAP_COPY_DISCARDABLE_SET | CAP_COPY_PRIORITY_SET, - CAP_PROPERTIES_GET (source)); -} - -#endif diff --git a/hurd/exceptions.h b/hurd/exceptions.h index 765fc5f..6d27d6e 100644 --- a/hurd/exceptions.h +++ b/hurd/exceptions.h @@ -26,14 +26,14 @@ #ifndef ASM #include -#include -#include +#include +#include #include #include #define RPC_STUB_PREFIX activation #define RPC_ID_PREFIX ACTIVATION -#include +#include /* Activation message ids. */ enum @@ -102,7 +102,7 @@ extern void hurd_activation_handler_init (void); /* Return the calling thread's UTCB. Threading libraries should set this to their own implementation once they are up and running. */ -extern struct vg_utcb *(*hurd_utcb) (void); +extern struct hurd_utcb *(*hurd_utcb) (void); /* Allocate a utcb buffer and associated data structures (including an exception messenger) for the thread THEAD (which must already exist @@ -110,11 +110,11 @@ extern struct vg_utcb *(*hurd_utcb) (void); messenger in the thread object. Returns the new UTCB in *UTCB. Returns 0 on success, otherwise an error code. */ extern error_t hurd_activation_state_alloc (addr_t thread, - struct vg_utcb **utcb); + struct hurd_utcb **utcb); /* Release the state allocated by hurd_activation_state_alloc. May not be called by a thread on its own UTCB! */ -extern void hurd_activation_state_free (struct vg_utcb *utcb); +extern void hurd_activation_state_free (struct hurd_utcb *utcb); /* When a thread causes an activation, the kernel invokes the thread's @@ -139,10 +139,10 @@ extern void hurd_activation_state_free (struct vg_utcb *utcb); stack. When this function returns, the interrupted state is restored. */ extern struct activation_frame *hurd_activation_handler_activated - (struct vg_utcb *utcb); + (struct hurd_utcb *utcb); extern void hurd_activation_handler_normal - (struct activation_frame *activation_frame, struct vg_utcb *utcb); + (struct activation_frame *activation_frame, struct hurd_utcb *utcb); /* The first instruction of activation handler dispatcher. */ diff --git a/hurd/folio.h b/hurd/folio.h deleted file mode 100644 index 9ad36c3..0000000 --- a/hurd/folio.h +++ /dev/null @@ -1,442 +0,0 @@ -/* folio.h - Folio definitions. - Copyright (C) 2007, 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - GNU Hurd is free software: you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with GNU Hurd. If not, see - . */ - -#ifndef _HURD_FOLIO_H -#define _HURD_FOLIO_H 1 - -#include -#include -#include -#include -#include - -/* Number of user objects per folio. */ -enum - { - FOLIO_OBJECTS = 128, - }; -enum - { - FOLIO_OBJECTS_LOG2 = 7, - }; - -/* User settable folio policy. */ - -/* The range of valid folio priorities. A lower numerical value - corresponds to a lower priority. */ -#define FOLIO_PRIORITY_BITS 15 -#define FOLIO_PRIORITY_MIN (-(1 << (FOLIO_PRIORITY_BITS - 1))) -#define FOLIO_PRIORITY_LRU (0) -#define FOLIO_PRIORITY_MAX ((1 << (FOLIO_PRIORITY_BITS - 1)) - 1) - -/* The folio group range. */ -#define FOLIO_GROUP_BITS 15 -#define FOLIO_GROUP_NONE 0 -#define FOLIO_GROUP_MIN 0 -#define FOLIO_GROUP_MAX ((1 << FOLIO_BITS) - 1) - -struct folio_policy -{ - union - { - struct - { - /* Whether a folio is discardable. If an activity reaches it - quota, rather than returning an out of memory error, the - system may reclaim storage with the discardable bit set. It - performs the equivalent of calling folio_free on the - folio. */ - int32_t discardable : 1; - - /* The following are only used if DISCARABLE is true. */ - - /* Folios can belong to a group. When one folio is discarded, - all folios in that group are discarded, unless GROUP is - FOLIO_GROUP_NONE. */ - uint32_t group : FOLIO_GROUP_BITS; - - /* By default, the system tries to discard folios according to - an LRU policy. This can be overridden using this field. In - this case, folios from the lowest priority group are - discarded. */ - int32_t priority : FOLIO_PRIORITY_BITS; - }; - uint32_t raw; - }; -}; - -#define FOLIO_POLICY_INIT { { raw: 0 } } -#define FOLIO_POLICY_VOID (struct folio_policy) FOLIO_POLICY_INIT -/* The default policy is not discardable. */ -#define FOLIO_POLICY_DEFAULT FOLIO_POLICY_VOID - -/* The format of the first page of a folio. This page is followed (on - disk) by FOLIO_OBJECTS pages. */ -struct folio -{ -#ifdef RM_INTERN - /* Folios are the unit of storage accounting. Every folio belongs - to exactly one activity. To track what folios belong to a - particular activity, each folio is attached to a doubly-linked - list originating at its owner activity. */ - struct cap activity; - struct cap next; - struct cap prev; - - /* The storage policy. */ - struct folio_policy policy; - - struct - { - /* Each object in the folio Disk version of each object. */ - uint32_t version : CAP_VERSION_BITS; - - /* Whether a page has any content (i.e., if it is not - uninitialized). */ - uint32_t content : 1; - - /* The object's memory policy when accessed via the folio. */ - uint32_t discardable : 1; - int32_t priority : OBJECT_PRIORITY_BITS; - } misc[1 + FOLIO_OBJECTS]; - - /* The type. */ - uint8_t types[FOLIO_OBJECTS]; - - /* Bit array indicating whether the an object has a non-empty wait - queue. */ - uint8_t wait_queues_p[(1 + FOLIO_OBJECTS + (8 - 1)) / 8]; - - uint8_t discarded[(FOLIO_OBJECTS + (8 - 1)) / 8]; - - /* User reference and dirty bits. Optionally reset on read. Set - respectively when an object is referenced or modified. Flushing - the object to disk does not clear this. */ - uint8_t dirty[(1 + FOLIO_OBJECTS + (8 - 1)) / 8]; - uint8_t referenced[(1 + FOLIO_OBJECTS + (8 - 1)) / 8]; - - /* Head of the list of objects waiting for some event on this - object. An element of this array is only valid if the - corresponding element of WAIT_QUEUES_P is true. The list is a - circular list. HEAD->PREV points to the tail. TAIL->NEXT points - to the OBJECT (NOT HEAD). */ - oid_t wait_queues[1 + FOLIO_OBJECTS]; - - uint64_t checksums[1 + FOLIO_OBJECTS][2]; -#else - /* User-space folio. */ - struct cap objects[FOLIO_OBJECTS]; -#endif -}; - -#ifdef RM_INTERN -typedef struct folio *folio_t; -#else -typedef addr_t folio_t; -#endif - -/* OBJECT is from -1 to FOLIO_OBJECTS. */ -static inline enum cap_type -folio_object_type (struct folio *folio, int object) -{ -#ifdef RM_INTERN - assert (object >= -1 && object < FOLIO_OBJECTS); - - if (object == -1) - return cap_folio; - return folio->types[object]; -#else - assert (object >= 0 && object < FOLIO_OBJECTS); - return folio->objects[object].type; -#endif -} - -static inline void -folio_object_type_set (struct folio *folio, int object, enum cap_type type) -{ - assert (object >= 0 && object < FOLIO_OBJECTS); - -#ifdef RM_INTERN - folio->types[object] = type; -#else - folio->objects[object].type = type; -#endif -} - -static inline struct object_policy -folio_object_policy (struct folio *folio, int object) -{ - struct object_policy policy; - -#ifdef RM_INTERN - assert (object >= -1 && object < FOLIO_OBJECTS); - - policy.discardable = folio->misc[object + 1].discardable; - policy.priority = folio->misc[object + 1].priority; -#else - assert (object >= 0 && object < FOLIO_OBJECTS); - - policy.discardable = folio->objects[object].discardable; - policy.priority = folio->objects[object].priority; -#endif - - return policy; -} - -static inline void -folio_object_policy_set (struct folio *folio, int object, - struct object_policy policy) -{ -#ifdef RM_INTERN - assert (object >= -1 && object < FOLIO_OBJECTS); - - folio->misc[object + 1].discardable = policy.discardable; - folio->misc[object + 1].priority = policy.priority; -#else - assert (object >= 0 && object < FOLIO_OBJECTS); - - folio->objects[object].discardable = policy.discardable; - folio->objects[object].priority = policy.priority; -#endif -} - -#ifdef RM_INTERN -#include - -static inline bool -folio_object_wait_queue_p (struct folio *folio, int object) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - return bit_test (folio->wait_queues_p, object + 1); -} - -static inline void -folio_object_wait_queue_p_set (struct folio *folio, int object, - bool valid) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - bit_set_to (folio->wait_queues_p, sizeof (folio->wait_queues_p), - object + 1, valid); -} - -static inline oid_t -folio_object_wait_queue (struct folio *folio, int object) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - return folio->wait_queues[object + 1]; -} - -static inline void -folio_object_wait_queue_set (struct folio *folio, int object, - oid_t head) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - folio->wait_queues[object + 1] = head; -} - -static inline uint32_t -folio_object_version (struct folio *folio, int object) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - return folio->misc[object + 1].version; -} - -static inline void -folio_object_version_set (struct folio *folio, int object, - uint32_t version) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - folio->misc[object + 1].version = version; -} - -static inline bool -folio_object_content (struct folio *folio, int object) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - return folio->misc[object + 1].content; -} - -static inline void -folio_object_content_set (struct folio *folio, int object, - bool content) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - folio->misc[object + 1].content = content; -} - -static inline bool -folio_object_discarded (struct folio *folio, int object) -{ - assert (object >= 0 && object < FOLIO_OBJECTS); - - return bit_test (folio->discarded, object); -} - -static inline void -folio_object_discarded_set (struct folio *folio, int object, bool valid) -{ - assert (object >= 0 && object < FOLIO_OBJECTS); - - bit_set_to (folio->discarded, sizeof (folio->discarded), - object, valid); -} - -static inline bool -folio_object_referenced (struct folio *folio, int object) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - return bit_test (folio->referenced, object + 1); -} - -static inline void -folio_object_referenced_set (struct folio *folio, int object, bool p) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - bit_set_to (folio->referenced, sizeof (folio->referenced), object + 1, p); -} - -static inline bool -folio_object_dirty (struct folio *folio, int object) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - return bit_test (folio->dirty, object + 1); -} - -static inline void -folio_object_dirty_set (struct folio *folio, int object, bool p) -{ - assert (object >= -1 && object < FOLIO_OBJECTS); - - bit_set_to (folio->dirty, sizeof (folio->dirty), object + 1, p); -} -#endif /* RM_INTERN */ - -/* Return a cap designating folio FOLIO's OBJECT'th object. */ -#ifdef RM_INTERN -/* This needs to be a macro as we use object_to_object_desc which is - made available by object.h but object.h includes this file. */ -#define folio_object_cap(__foc_folio, __foc_object) \ - ({ \ - struct cap __foc_cap; \ - \ - __foc_cap.type = folio_object_type (__foc_folio, __foc_object); \ - __foc_cap.version = folio_object_version (__foc_folio, \ - __foc_object); \ - \ - struct cap_properties __foc_cap_properties \ - = CAP_PROPERTIES (folio_object_policy (__foc_folio, __foc_object), \ - CAP_ADDR_TRANS_VOID); \ - CAP_PROPERTIES_SET (&__foc_cap, __foc_cap_properties); \ - \ - __foc_cap.oid \ - = object_to_object_desc ((struct object *) __foc_folio)->oid \ - + 1 + __foc_object; \ - \ - __foc_cap; \ - }) -#else -static inline struct cap -folio_object_cap (struct folio *folio, int object) -{ - assert (0 <= object && object < FOLIO_OBJECTS); - return folio->objects[object]; -} -#endif - -#define RPC_STUB_PREFIX rm -#define RPC_ID_PREFIX RM - -#include - -enum - { - RM_folio_alloc = 200, - RM_folio_free, - RM_folio_object_alloc, - RM_folio_policy - }; - -/* Allocate a folio against ACTIVITY. Return a capability in the - caller's cspace in slot FOLIO. POLICY specifies the storage - policy. */ -RPC(folio_alloc, 1, 0, 1, - /* cap_t, principal, cap_t, activity, */ - struct folio_policy, policy, cap_t, folio) - -/* Free the folio designated by FOLIO. */ -RPC(folio_free, 0, 0, 0 - /* cap_t, principal, cap_t, folio */) - -/* Destroys the INDEXth object in folio FOLIO and allocate in its - place an object of tye TYPE. If TYPE is CAP_VOID, any existing - object is destroyed, however, no object is instantiated in its - place. POLICY specifies the object's policy when accessed via the - folio. If an object is destroyed and there are waiters, they are - passed the return code RETURN_CODE. - - Returns a capability to the allocated object in OBJECT. Returns a - weak capability to the object in OBJECT_WEAK. */ -RPC(folio_object_alloc, 4, 0, 2, - /* cap_t, principal, cap_t, folio, */ - uintptr_t, index, uintptr_t, type, - struct object_policy, policy, uintptr_t, return_code, - /* Out: */ - cap_t, object, cap_t, object_weak) - -/* Flags for folio_policy. */ -enum -{ - FOLIO_POLICY_DELIVER = 1 << 0, - - FOLIO_POLICY_DISCARDABLE_SET = 1 << 1, - FOLIO_POLICY_GROUP_SET = 1 << 2, - FOLIO_POLICY_PRIORITY_SET = 1 << 3, - - FOLIO_POLICY_SET = (FOLIO_POLICY_DISCARDABLE_SET - | FOLIO_POLICY_GROUP_SET - | FOLIO_POLICY_PRIORITY_SET) -}; - -/* Get and set the management policy for folio FOLIO. - - If FOLIO_POLICY_DELIVER is set in FLAGS, then return FOLIO's - current paging policy in OLD. Then, if any of the set flags are - set, set the corresponding values based on the value of POLICY. */ -RPC(folio_policy, 2, 1, 0, - /* cap_t, principal, cap_t, folio, */ - uintptr_t, flags, struct folio_policy, policy, - /* Out: */ - struct folio_policy, old) - -#undef RPC_STUB_PREFIX -#undef RPC_ID_PREFIX - -#endif diff --git a/hurd/futex.h b/hurd/futex.h deleted file mode 100644 index e1e71a3..0000000 --- a/hurd/futex.h +++ /dev/null @@ -1,219 +0,0 @@ -/* futex.h - Futex definitions. - Copyright (C) 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - GNU Hurd is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNU Hurd. If not, see - . */ - -#ifndef _HURD_FUTEX_H -#define _HURD_FUTEX_H 1 - -#include -#include -#include -#include -#define __need_timespec -#include - -/* The interface to the kernel futex implementation. This is only - here because glibc really wants futexes. If this project gets - sufficient momentum, the kernel futex implementation should be - replaced with a more microkernel friendly approach to locks. */ - -enum - { - RM_futex = 800, - }; - -#define RPC_STUB_PREFIX rm -#define RPC_ID_PREFIX RM - -#include - -/* Operations. */ -enum - { - FUTEX_WAIT, - FUTEX_WAKE, - FUTEX_WAKE_OP, - FUTEX_CMP_REQUEUE, -#if 0 - /* We don't support these operations. The first is deprecated and - the second requires FDs which the kernel doesn't support. - Although we could return EOPNOTSUPP, commenting them out - catches any uses at compile-time. */ - FUTEX_REQUEUE, - FUTEX_FD, -#endif - }; - -enum - { - FUTEX_OP_SET = 0, - FUTEX_OP_ADD = 1, - FUTEX_OP_OR = 2, - FUTEX_OP_ANDN = 3, - FUTEX_OP_XOR = 4 - }; - -enum - { - FUTEX_OP_CMP_EQ = 0, - FUTEX_OP_CMP_NE = 1, - FUTEX_OP_CMP_LT = 2, - FUTEX_OP_CMP_LE = 3, - FUTEX_OP_CMP_GT = 4, - FUTEX_OP_CMP_GE = 5 - }; - -union futex_val2 -{ - struct timespec timespec; - int value; -}; - -union futex_val3 -{ - int value; - struct - { - int cmparg: 12; - int oparg: 12; - int cmp: 4; - int op: 4; - }; -}; -#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE \ - (union futex_val3) { { 1, 0, FUTEX_OP_CMP_GT, FUTEX_OP_SET } } - -RPC (futex, 7, 1, 0, - /* cap_t principal, cap_t thread, */ - void *, addr1, int, op, int, val1, - bool, timeout, union futex_val2, val2, - void *, addr2, union futex_val3, val3, - /* Out: */ - long, out); - -#undef RPC_STUB_PREFIX -#undef RPC_ID_PREFIX - -#ifndef RM_INTERN -#include - -struct futex_return -{ - error_t err; - long ret; -}; - -static inline struct futex_return -__attribute__((always_inline)) -futex_using (struct hurd_message_buffer *mb, - void *addr1, int op, int val1, struct timespec *timespec, - void *addr2, int val3) -{ - union futex_val2 val2; - if (timespec) - val2.timespec = *timespec; - else - __builtin_memset (&val2, 0, sizeof (val2)); - - error_t err; - long ret = 0; /* Elide gcc warning. */ - if (mb) - err = rm_futex_using (mb, - ADDR_VOID, ADDR_VOID, - addr1, op, val1, !! timespec, val2, addr2, - (union futex_val3) val3, &ret); - else - err = rm_futex (ADDR_VOID, ADDR_VOID, - addr1, op, val1, !! timespec, val2, addr2, - (union futex_val3) val3, &ret); - return (struct futex_return) { err, ret }; -} - -/* Standard futex signatures. See futex documentation, e.g., Futexes - are Tricky by Ulrich Drepper. */ -static inline struct futex_return -__attribute__((always_inline)) -futex (void *addr1, int op, int val1, struct timespec *timespec, - void *addr2, int val3) -{ - return futex_using (NULL, addr1, op, val1, timespec, addr2, val3); -} - - -/* If *F is VAL, wait until woken. */ -static inline long -__attribute__((always_inline)) -futex_wait_using (struct hurd_message_buffer *mb, int *f, int val) -{ - struct futex_return ret; - ret = futex_using (mb, f, FUTEX_WAIT, val, NULL, 0, 0); - if (ret.err) - { - errno = ret.err; - return -1; - } - return ret.ret; -} - -static inline long -__attribute__((always_inline)) -futex_wait (int *f, int val) -{ - return futex_wait_using (NULL, f, val); -} - - -/* If *F is VAL, wait until woken. */ -static inline long -__attribute__((always_inline)) -futex_timed_wait (int *f, int val, struct timespec *timespec) -{ - struct futex_return ret; - ret = futex (f, FUTEX_WAIT, val, timespec, 0, 0); - if (ret.err) - { - errno = ret.err; - return -1; - } - return ret.ret; -} - - -/* Signal NWAKE waiters waiting on futex F. */ -static inline long -__attribute__((always_inline)) -futex_wake_using (struct hurd_message_buffer *mb, int *f, int nwake) -{ - struct futex_return ret; - ret = futex_using (mb, f, FUTEX_WAKE, nwake, NULL, 0, 0); - if (ret.err) - { - errno = ret.err; - return -1; - } - return ret.ret; -} - -static inline long -__attribute__((always_inline)) -futex_wake (int *f, int nwake) -{ - return futex_wake_using (NULL, f, nwake); -} -#endif /* !RM_INTERN */ - -#endif diff --git a/hurd/headers.m4 b/hurd/headers.m4 index 51b19fd..d5842fb 100644 --- a/hurd/headers.m4 +++ b/hurd/headers.m4 @@ -13,23 +13,13 @@ AC_CONFIG_LINKS([sysroot/include/hurd/stddef.h:hurd/stddef.h sysroot/include/hurd/types.h:hurd/types.h sysroot/include/hurd/startup.h:hurd/startup.h - sysroot/include/hurd/addr.h:hurd/addr.h - sysroot/include/hurd/addr-trans.h:hurd/addr-trans.h - sysroot/include/hurd/cap.h:hurd/cap.h - sysroot/include/hurd/folio.h:hurd/folio.h - sysroot/include/hurd/rpc.h:hurd/rpc.h sysroot/include/hurd/exceptions.h:hurd/exceptions.h sysroot/include/hurd/thread.h:hurd/thread.h - sysroot/include/hurd/activity.h:hurd/activity.h sysroot/include/hurd/lock.h:hurd/lock.h sysroot/include/hurd/trace.h:hurd/trace.h sysroot/include/hurd/mutex.h:hurd/mutex.h sysroot/include/hurd/rmutex.h:hurd/rmutex.h - sysroot/include/hurd/futex.h:hurd/futex.h sysroot/include/hurd/error.h:hurd/error.h - sysroot/include/hurd/message.h:hurd/message.h - sysroot/include/hurd/messenger.h:hurd/messenger.h - sysroot/include/hurd/ipc.h:hurd/ipc.h sysroot/include/hurd/math.h:hurd/math.h sysroot/include/hurd/bits/math.h:hurd/bits/${arch}/math.h ]) diff --git a/hurd/ipc.h b/hurd/ipc.h deleted file mode 100644 index 95588a0..0000000 --- a/hurd/ipc.h +++ /dev/null @@ -1,296 +0,0 @@ -/* ipc.h - Interprocess communication interface. - Copyright (C) 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - GNU Hurd is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNU Hurd. If not, see - . */ - -#ifndef _VIENGOOS_IPC_H -#define _VIENGOOS_IPC_H 1 - -#include -#include -#include -#include -#include -#include - -#ifdef USE_L4 -#include -#endif - -/* IPC flags. */ -enum - { - /* IPC includes a receive phase. */ - VG_IPC_RECEIVE = 1 << 0, - /* Don't unblock the receive buffer if there is no message queued - for delivery. */ - VG_IPC_RECEIVE_NONBLOCKING = 1 << 1, - /* Activate the thread on message receipt. */ - VG_IPC_RECEIVE_ACTIVATE = 1 << 2, - /* Set the receive messenger's thread to the caller. */ - VG_IPC_RECEIVE_SET_THREAD_TO_CALLER = 1 << 3, - /* Set the receive messener's address space root to the - caller's. */ - VG_IPC_RECEIVE_SET_ASROOT_TO_CALLERS = 1 << 4, - /* Whether to receive the message inline. */ - VG_IPC_RECEIVE_INLINE = 1 << 5, - /* Whether to receive any capabilities inline when receiving a - message inline (i.e., when VG_IPC_RECEIVE_INLINE is set). */ - VG_IPC_RECEIVE_INLINE_CAP1 = 1 << 6, - - /* IPC includes a send phase. */ - VG_IPC_SEND = 1 << 7, - /* If the object is blocked, return EWOULDBLOCK. */ - VG_IPC_SEND_NONBLOCKING = 1 << 8, - /* Activate the thread on message transfer. */ - VG_IPC_SEND_ACTIVATE = 1 << 9, - /* Set the send messenger's thread to the caller. */ - VG_IPC_SEND_SET_THREAD_TO_CALLER = 1 << 10, - /* Set the sender messener's address space root to the - caller's. */ - VG_IPC_SEND_SET_ASROOT_TO_CALLERS = 1 << 11, - /* Whether to send the message inline. */ - VG_IPC_SEND_INLINE = 1 << 12, - - /* Which inline data to transfer when sending a message. Inline - data is ignored if the send buffer is not ADDR_VOID. */ - VG_IPC_SEND_INLINE_WORD1 = 1 << 13, - VG_IPC_SEND_INLINE_WORD2 = 1 << 14, - VG_IPC_SEND_INLINE_CAP1 = 1 << 15, - - - /* The IPC includes a return phase. */ - VG_IPC_RETURN = 1 << 16, - - }; - -#ifndef RM_INTERN -/* An IPC consists of three phases: the receive phase, the send phase - and the return phase. All three phases are optional. Each phase - is executed after the previous phase has completed. If a phase - does not complete successfully, the phase is aborted and the - remaining phases are not executed. - - - RECEIVE PHASE - - If FLAGS contains VG_IPC_RECEIVE, the IPC includes a receive phase. - - If RECV_BUF is not ADDR_VOID, associates RECV_BUF with - RECV_MESSENGER. - - If FLAGS contains VG_IPC_RECEIVE_NONBLOCKING: - - Unblocks RECV_MESSENGER if RECV_MESSENGER has a messenger waiting - to deliver a message. Otherwise, returns EWOUDBLOCK. - - Otherwise: - - Unblocks RECV_MESSENGER. - - Resources are charged to RECV_ACTIVITY. - - If VG_IPC_RECEIVE_ACTIVATE is set, an activation is sent to the - thread associated with RECV_MESSENGER when RECV_MESSENGER receives - a message. - - - SEND PHASE - - If FLAGS contains VG_IPC_SEND, the IPC includes a send phase. - - If SEND_MESSENGER is ADDR_VOID, an implicit messenger is allocated - and VG_IPC_SEND_NONBLOCKING is assumed to be on. - - If SEND_BUF is not ADDR_VOID, assocaiates SEND_BUF with - SEND_MESSENGER. Otherwise, associates inline data (INLINE_WORD1, - INLINE_WORD2 and INLINE_CAP) according to the inline flags with - SEND_MESSENGER. - - If FLAGS contains VG_IPC_SEND_NONBLOCKING: - - If TARGET_MESSENGER is blocked, returns ETIMEDOUT. - - Otherwise: - - Blocks SEND_MESSENGER and enqueues it on TARGET_MESSENGER. - - When TARGET_MESSENGER becomes unblocked, SEND_MESSENGER delivers - its message to TARGET_MESSENGER. - - Resources are charged to SEND_ACTIVITY. - - If VG_IPC_SEND_ACTIVATE is set, an activation is sent to the thread - associated with SEND_MESSENGER when SEND_MESSENGER's message is - transferred to TARGET_MESSENGER (or, when TARGET_MESSENGER is - destroyed). - - - RETURN PHASE - - If FLAGS contains VG_IPC_RETURN, the IPC returns. Otherwise, the - calling thread is suspended until it is next activated. */ -static inline error_t -vg_ipc_full (uintptr_t flags, - addr_t recv_activity, addr_t recv_messenger, addr_t recv_buf, - addr_t recv_inline_cap, - addr_t send_activity, addr_t target_messenger, - addr_t send_messenger, addr_t send_buf, - uintptr_t send_inline_word1, uintptr_t send_inline_word2, - addr_t send_inline_cap) -{ - error_t err = 0; - -#ifdef USE_L4 - l4_msg_tag_t tag = l4_niltag; - l4_msg_tag_set_label (&tag, 8194); - - l4_msg_t msg; - l4_msg_clear (msg); - l4_msg_set_msg_tag (msg, tag); - - void msg_append_addr (addr_t addr) - { - int i; - for (i = 0; i < sizeof (addr_t) / sizeof (uintptr_t); i ++) - l4_msg_append_word (msg, ((uintptr_t *) &addr)[i]); - } - - l4_msg_append_word (msg, flags); - - msg_append_addr (recv_activity); - msg_append_addr (recv_messenger); - msg_append_addr (recv_buf); - msg_append_addr (recv_inline_cap); - - msg_append_addr (send_activity); - msg_append_addr (target_messenger); - - msg_append_addr (send_messenger); - msg_append_addr (send_buf); - - l4_msg_append_word (msg, send_inline_word1); - l4_msg_append_word (msg, send_inline_word2); - msg_append_addr (send_inline_cap); - - l4_msg_load (msg); - l4_accept (l4_map_grant_items (L4_COMPLETE_ADDRESS_SPACE)); - - bool call = true; - - while (1) - { - extern struct hurd_startup_data *__hurd_startup_data; - - if (call) - tag = l4_call (__hurd_startup_data->rm); - else - tag = l4_receive (__hurd_startup_data->rm); - - if (likely (l4_ipc_failed (tag))) - { - if (((l4_error_code () >> 1) & 0x7) == 3) - { - if (l4_error_code () & 1) - /* IPC was interrupted in the receive phase, i.e., we - got a response. */ - break; - else - call = false; - } - else - return EHOSTDOWN; - } - else - { - assert (l4_untyped_words (tag) == 1); - l4_msg_store (tag, msg); - /* Potential error performing IPC (or VG_RETURN specified). */ - err = l4_msg_word (msg, 1); - break; - } - } -#else -# warning vg_ipc not ported to this architecture. -#endif - - return err; -} - -static inline error_t -vg_ipc (uintptr_t flags, - addr_t recv_activity, addr_t recv_messenger, addr_t recv_buf, - addr_t send_activity, addr_t target_messenger, - addr_t send_messenger, addr_t send_buf) -{ - return vg_ipc_full (flags, - recv_activity, recv_messenger, recv_buf, ADDR_VOID, - send_activity, target_messenger, - send_messenger, send_buf, - 0, 0, ADDR_VOID); -} - -static inline error_t -vg_ipc_short (uintptr_t flags, - addr_t recv_activity, addr_t recv_messenger, addr_t recv_cap, - addr_t send_activity, addr_t target_messenger, - addr_t send_messenger, - uintptr_t inline_word1, uintptr_t inline_word2, - addr_t inline_cap) -{ - return vg_ipc_full (flags, - recv_activity, recv_messenger, ADDR_VOID, recv_cap, - send_activity, target_messenger, - send_messenger, ADDR_VOID, - inline_word1, inline_word2, inline_cap); -} - -static inline error_t -vg_send (uintptr_t flags, addr_t send_activity, addr_t target_messenger, - addr_t send_messenger, addr_t send_buf) -{ - return vg_ipc_full (flags | VG_IPC_SEND | VG_IPC_SEND_ACTIVATE, - ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, - send_activity, target_messenger, - send_messenger, send_buf, - 0, 0, ADDR_VOID); -} - -static inline error_t -vg_reply (uintptr_t flags, addr_t send_activity, addr_t target_messenger, - addr_t send_messenger, addr_t send_buf) -{ - return vg_ipc_full (flags | VG_IPC_SEND | VG_IPC_SEND_NONBLOCKING, - ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, - send_activity, target_messenger, send_messenger, send_buf, - 0, 0, ADDR_VOID); -} - -/* Suspend the caller until the next activation. */ -static inline error_t -vg_suspend (void) -{ - return vg_ipc_full (0, - ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, - ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, - 0, 0, ADDR_VOID); -} - -#endif - -#endif diff --git a/hurd/message.h b/hurd/message.h deleted file mode 100644 index d59e41d..0000000 --- a/hurd/message.h +++ /dev/null @@ -1,229 +0,0 @@ -/* message.h - Message buffer definitions. - Copyright (C) 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - GNU Hurd is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNU Hurd. If not, see - . */ - -#ifndef _VIENGOOS_MESSAGE_H -#define _VIENGOOS_MESSAGE_H 1 - -#include -#include -#include -#include - -/* A message. - - When handing a message structure to a messenger, it must start at - the beginning of a page and it cannot extend past the end of that - page. */ -struct vg_message -{ - union - { - struct - { - /* The number of capability addresses in the message. */ - uint16_t cap_count; - /* The number of bytes of data transferred in this message. */ - uint16_t data_count; - - addr_t caps[/* cap_count */]; - // char data[data_count]; - }; - - char raw[PAGESIZE]; - }; -}; - - -/* Clear the msg so that it references no capabilities and - contains no data. */ -static inline void -vg_message_clear (struct vg_message *msg) -{ - msg->cap_count = 0; - msg->data_count = 0; -} - - -/* Return the number of capabilities referenced by MSG. */ -static inline int -vg_message_cap_count (struct vg_message *msg) -{ - int max = (PAGESIZE - __builtin_offsetof (struct vg_message, caps)) - / sizeof (addr_t); - - int count = msg->cap_count; - if (count > max) - count = max; - - return count; -} - -/* Return the number of bytes of data in MSG. */ -static inline int -vg_message_data_count (struct vg_message *msg) -{ - int max = PAGESIZE - - vg_message_cap_count (msg) * sizeof (addr_t) - - __builtin_offsetof (struct vg_message, caps); - - int count = msg->data_count; - if (count > max) - count = max; - - return count; -} - - -/* Return the start of the capability address array in msg MSG. */ -static inline addr_t * -vg_message_caps (struct vg_message *msg) -{ - return msg->caps; -} - -/* Return capability IDX in msg MSG. */ -static inline addr_t -vg_message_cap (struct vg_message *msg, int idx) -{ - assert (idx < msg->cap_count); - - return msg->caps[idx]; -} - - -/* Return the start of the data in msg MSG. */ -static inline char * -vg_message_data (struct vg_message *msg) -{ - return (void *) msg - + __builtin_offsetof (struct vg_message, caps) - + msg->cap_count * sizeof (addr_t); -} - -/* Return data word WORD in msg MSG. */ -static inline uintptr_t -vg_message_word (struct vg_message *msg, int word) -{ - assert (word < msg->data_count / sizeof (uintptr_t)); - - return ((uintptr_t *) vg_message_data (msg))[word]; -} - - -/* Append the array of capability addresses CAPS to the msg MSG. - There must be sufficient room in the message buffer. */ -static inline void -vg_message_append_caps (struct vg_message *msg, int cap_count, addr_t *caps) -{ - assert ((void *) vg_message_data (msg) - (void *) msg - + vg_message_data_count (msg) + cap_count * sizeof (*caps) - <= PAGESIZE); - - __builtin_memmove (&msg->caps[msg->cap_count + cap_count], - &msg->caps[msg->cap_count], - msg->data_count); - - __builtin_memcpy (&msg->caps[msg->cap_count], - caps, - cap_count * sizeof (addr_t)); - - msg->cap_count += cap_count; -} - -/* Append the capability address CAP to the msg MSG. There must be - sufficient room in the message buffer. */ -static inline void -vg_message_append_cap (struct vg_message *msg, addr_t cap) -{ - vg_message_append_caps (msg, 1, &cap); -} - - -/* Append DATA to the msg MSG. There must be sufficient room in the - message buffer. */ -static inline void -vg_message_append_data (struct vg_message *msg, int bytes, char *data) -{ - int dstart = __builtin_offsetof (struct vg_message, caps) - + msg->cap_count * sizeof (addr_t); - int dend = dstart + msg->data_count; - - int new_dend = dend + bytes; - assert (new_dend <= PAGESIZE); - - msg->data_count += bytes; - __builtin_memcpy ((void *) msg + dend, data, bytes); -} - -/* Append the word WORD to the msg MSG. There must be - sufficient room in the message buffer. */ -static inline void -vg_message_append_word (struct vg_message *msg, uintptr_t word) -{ - vg_message_append_data (msg, sizeof (word), (char *) &word); -} - -/* Return data word WORD in msg MSG. */ -static inline void -vg_message_word_set (struct vg_message *msg, int pos, uintptr_t word) -{ - if (msg->data_count < pos * sizeof (uintptr_t)) - msg->data_count = pos * sizeof (uintptr_t); - - ((uintptr_t *) vg_message_data (msg))[pos] = word; -} - -#include - -static inline void -vg_message_dump (struct vg_message *message) -{ - s_printf ("%d bytes, %d caps\n", - vg_message_data_count (message), - vg_message_cap_count (message)); - - char d2h[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F' }; - unsigned char *data = vg_message_data (message); - - int i = 0; - while (i < vg_message_data_count (message)) - { - s_printf ("%d: ", i); - - int j, k; - for (j = 0, k = 0; - i < vg_message_data_count (message) && j < 4 * 8; - j ++, i ++) - { - s_printf ("%c%c", d2h[data[i] >> 4], d2h[data[i] & 0xf]); - if (j % 4 == 3) - s_printf (" "); - } - s_printf ("\n"); - } - - for (i = 0; i < vg_message_cap_count (message); i ++) - s_printf ("cap %d: " ADDR_FMT "\n", - i, ADDR_PRINTF (vg_message_cap (message, i))); -} - - -#endif /* _VIENGOOS_MESSAGE_H */ diff --git a/hurd/messenger.h b/hurd/messenger.h deleted file mode 100644 index 78d42f1..0000000 --- a/hurd/messenger.h +++ /dev/null @@ -1,87 +0,0 @@ -/* messenger.h - Messenger buffer definitions. - Copyright (C) 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - GNU Hurd is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNU Hurd. If not, see - . */ - -#ifndef _VIENGOOS_MESSENGER_H -#define _VIENGOOS_MESSENGER_H 1 - -#include -#include - -/* A messenger references a message buffer. It can transfer a message - (contained in its message buffer) to another messenger. It can - also receive a message from another messenger. A messenger can - block waiting to deliver a message to or receive a message from - another messenger. - - To send a message, a payload is loaded into a message buffer and - associated with a messenger. The messenger is then enqueued on - another messenger. When the latter messenger is unblocked, the - message is delivered. - - To avoid messages from being overwritten, messengers are blocked on - message delivery and must be explicitly unblocked before another - message is sent. */ -#ifdef RM_INTERN -struct messenger; -typedef struct messenger *vg_messenger_t; -#else -typedef addr_t vg_messenger_t; -#endif - -#define VG_MESSENGER_INLINE_WORDS 2 -#define VG_MESSENGER_INLINE_CAPS 1 - -/* Number of user-settable capability slots at the start of the - messenger structure. */ -enum - { - /* The thread to activate. */ - VG_MESSENGER_THREAD_SLOT = 0, - /* The address space root relative to which all capability - addresses in the message buffer will be resolved. */ - VG_MESSENGER_ASROOT_SLOT, - /* The assocaited message buffer. */ - VG_MESSENGER_BUFFER_SLOT, - /* The activity that was delivered with the last message. */ - VG_MESSENGER_ACTIVITY_SLOT, - - VG_MESSENGER_SLOTS = 4, - }; -#define VG_MESSENGER_SLOTS_LOG2 2 - -enum - { - VG_messenger_id = 900, - }; - -#define RPC_STUB_PREFIX vg -#define RPC_ID_PREFIX VG - -#include - -/* Set MESSENGER's ID to ID and return the old ID in OLD. */ -RPC(messenger_id, 1, 1, 0, - /* cap_t activity, cap_t messenger, */ - uint64_t, id, uint64_t, old) - -#undef RPC_STUB_PREFIX vg -#undef RPC_ID_PREFIX VG - -#endif /* _VIENGOOS_MESSENGER_H */ diff --git a/hurd/mutex.h b/hurd/mutex.h index cded557..4e68701 100644 --- a/hurd/mutex.h +++ b/hurd/mutex.h @@ -39,7 +39,7 @@ typedef int ss_mutex_t; #include #include #include -#include +#include /* Unlocked. */ #define _MUTEX_UNLOCKED 0 diff --git a/hurd/rpc.h b/hurd/rpc.h deleted file mode 100644 index 55fe8be..0000000 --- a/hurd/rpc.h +++ /dev/null @@ -1,1054 +0,0 @@ -/* rpc.h - RPC template definitions. - Copyright (C) 2007, 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - GNU Hurd is free software: you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with GNU Hurd. If not, see - . */ - -#define RPC_CONCAT2(a,b) a##b -#define RPC_CONCAT(a,b) RPC_CONCAT2(a,b) - -/* If RPC_STUB_PREFIX is defined, the prefix prepended plus an - underscore to all function names. If using, don't forget to #undef - after all uses to avoid potential redefinition errors. */ -#undef RPC_STUB_PREFIX_ -#ifndef RPC_STUB_PREFIX -#define RPC_STUB_PREFIX_(x) x -#else -#define RPC_STUB_PREFIX_(name) RPC_CONCAT(RPC_STUB_PREFIX,_##name) -#endif - -/* If RPC_STUB_PREFIX is defined, the prefix prepended plus an - underscore to all function names. If using, don't forget to #undef - after all uses to avoid potential redefinition errors. */ -#undef RPC_ID_PREFIX_ -#ifndef RPC_ID_PREFIX -#define RPC_ID_PREFIX_(x) x -#else -#define RPC_ID_PREFIX_(name) RPC_CONCAT(RPC_ID_PREFIX,_##name) -#endif - -#ifndef _HURD_RPC_H -#define _HURD_RPC_H - -#include -#include -#include -#include - -#ifdef RM_INTERN -extern struct vg_message *reply_buffer; - -/* We can't include messenger.h as it includes hurd/cap.h which in turn - includes this file. */ -struct messenger; -struct activity; -extern bool messenger_message_load (struct activity *activity, - struct messenger *target, - struct vg_message *message); -#else -# include -#endif -typedef addr_t cap_t; - -/* First we define some cpp help macros. */ -#define CPP_IFELSE_0(when, whennot) whennot -#define CPP_IFELSE_1(when, whennot) when -#define CPP_IFELSE_2(when, whennot) when -#define CPP_IFELSE_3(when, whennot) when -#define CPP_IFELSE_4(when, whennot) when -#define CPP_IFELSE_5(when, whennot) when -#define CPP_IFELSE_6(when, whennot) when -#define CPP_IFELSE_7(when, whennot) when -#define CPP_IFELSE_8(when, whennot) when -#define CPP_IFELSE_9(when, whennot) when -#define CPP_IFELSE_10(when, whennot) when -#define CPP_IFELSE_11(when, whennot) when -#define CPP_IFELSE_12(when, whennot) when -#define CPP_IFELSE_13(when, whennot) when -#define CPP_IFELSE_14(when, whennot) when -#define CPP_IFELSE_15(when, whennot) when -#define CPP_IFELSE_16(when, whennot) when -#define CPP_IFELSE_17(when, whennot) when -#define CPP_IFELSE_18(when, whennot) when -#define CPP_IFELSE_19(when, whennot) when -#define CPP_IFELSE_20(when, whennot) when -#define CPP_IFELSE_21(when, whennot) when -#define CPP_IFELSE_22(when, whennot) when -#define CPP_IFELSE_23(when, whennot) when -#define CPP_IFELSE_24(when, whennot) when -#define CPP_IFELSE_25(when, whennot) when - -#define CPP_IFELSE_(expr, when, whennot) \ - CPP_IFELSE_##expr(when, whennot) -#define CPP_IFELSE(expr, when, whennot) \ - CPP_IFELSE_(expr, when, whennot) -#define CPP_IF(expr, when) \ - CPP_IFELSE(expr, when,) -#define CPP_IFNOT(expr, whennot) \ - CPP_IFELSE(expr, , whennot) - -#define CPP_SUCC_0 1 -#define CPP_SUCC_1 2 -#define CPP_SUCC_2 3 -#define CPP_SUCC_3 4 -#define CPP_SUCC_4 5 -#define CPP_SUCC_5 6 -#define CPP_SUCC_6 7 -#define CPP_SUCC_7 8 -#define CPP_SUCC_8 9 -#define CPP_SUCC_9 10 -#define CPP_SUCC_10 11 -#define CPP_SUCC_11 12 -#define CPP_SUCC_12 13 -#define CPP_SUCC_13 14 -#define CPP_SUCC_14 15 -#define CPP_SUCC_15 16 -#define CPP_SUCC_16 17 -#define CPP_SUCC_17 18 -#define CPP_SUCC_18 19 -#define CPP_SUCC_19 20 -#define CPP_SUCC_20 21 -#define CPP_SUCC_21 22 -#define CPP_SUCC_22 23 -#define CPP_SUCC_23 24 -#define CPP_SUCC_24 25 -#define CPP_SUCC_25 26 - -#define CPP_SUCC_(x) CPP_SUCC_##x -#define CPP_SUCC(x) CPP_SUCC_(x) - -/* We'd like to define CPP_ADD as: - - #define CPP_ADD(x, y) \ - CPP_IFELSE(y, CPP_ADD(SUCC(x), SUCC(y)), y) - - This does not work as while a macro is being expanded, it becomes - ineligible for expansion. Thus, any references (including indirect - references) are not expanded. Repeated applications of a macro are, - however, allowed, and this is what the CPP_APPLY macro does. */ -#define CPP_APPLY1(x, y) x(y) -#define CPP_APPLY2(x, y) x(CPP_APPLY1(x, y)) -#define CPP_APPLY3(x, y) x(CPP_APPLY2(x, y)) -#define CPP_APPLY4(x, y) x(CPP_APPLY3(x, y)) -#define CPP_APPLY5(x, y) x(CPP_APPLY4(x, y)) -#define CPP_APPLY6(x, y) x(CPP_APPLY5(x, y)) -#define CPP_APPLY7(x, y) x(CPP_APPLY6(x, y)) -#define CPP_APPLY8(x, y) x(CPP_APPLY7(x, y)) -#define CPP_APPLY9(x, y) x(CPP_APPLY8(x, y)) -#define CPP_APPLY10(x, y) x(CPP_APPLY9(x, y)) -#define CPP_APPLY11(x, y) x(CPP_APPLY10(x, y)) -#define CPP_APPLY12(x, y) x(CPP_APPLY11(x, y)) -#define CPP_APPLY13(x, y) x(CPP_APPLY12(x, y)) -#define CPP_APPLY14(x, y) x(CPP_APPLY13(x, y)) -#define CPP_APPLY15(x, y) x(CPP_APPLY14(x, y)) -#define CPP_APPLY16(x, y) x(CPP_APPLY15(x, y)) -#define CPP_APPLY17(x, y) x(CPP_APPLY16(x, y)) -#define CPP_APPLY18(x, y) x(CPP_APPLY17(x, y)) -#define CPP_APPLY19(x, y) x(CPP_APPLY18(x, y)) -#define CPP_APPLY20(x, y) x(CPP_APPLY19(x, y)) -#define CPP_APPLY21(x, y) x(CPP_APPLY20(x, y)) -#define CPP_APPLY22(x, y) x(CPP_APPLY21(x, y)) -#define CPP_APPLY23(x, y) x(CPP_APPLY22(x, y)) -#define CPP_APPLY24(x, y) x(CPP_APPLY23(x, y)) -#define CPP_APPLY25(x, y) x(CPP_APPLY24(x, y)) - -#define CPP_ADD(x, y) \ - CPP_IFELSE(y, CPP_APPLY##y(CPP_SUCC, x), x) - -/* Apply a function to each of the first n arguments. - - - CPP_FOREACH(2, CPP_SAFE_DEREF, NULL, a, b) - - => - - ((a) ? *(a) : NULL), ((b) ? *(b) : NULL) - */ -#define CPP_FOREACH_0(func, cookie, ...) -#define CPP_FOREACH_1(func, cookie, element, ...) func(cookie, element) -#define CPP_FOREACH_2(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_1(func, cookie, __VA_ARGS__) -#define CPP_FOREACH_3(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_2(func, cookie, __VA_ARGS__) -#define CPP_FOREACH_4(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_3(func, cookie, __VA_ARGS__) -#define CPP_FOREACH_5(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_4(func, cookie, __VA_ARGS__) -#define CPP_FOREACH_6(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_5(func, cookie, __VA_ARGS__) -#define CPP_FOREACH_7(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_6(func, cookie, __VA_ARGS__) -#define CPP_FOREACH_8(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_7(func, cookie, __VA_ARGS__) -#define CPP_FOREACH_9(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_8(func, cookie, __VA_ARGS__) - -#define CPP_FOREACH_(n, func, cookie, ...) \ - CPP_FOREACH_##n(func, cookie, __VA_ARGS__) -#define CPP_FOREACH(n, func, cookie, ...) \ - CPP_FOREACH_(n, func, cookie, __VA_ARGS__) - -/* Used in conjunction with CPP_FOREACH. Generates C code that - dereferences ELEMENT if it is not NULL, otherwise, returns - COOKIE. */ -#define CPP_SAFE_DEREF(cookie, element) ((element) ? *(element) : (cookie)) - - -/* CPP treats commas specially so we have to be smart about how we - insert them algorithmically. For instance, this won't work: - - #define COMMA , - CPP_IFELSE(x, COMMA, ) - - To optional insert a comma, use this function instead. When the - result is need, invoke the result. For instance: - - RPC_IF_COMMA(x) () - */ -#define RPC_COMMA() , -#define RPC_NOCOMMA() -#define RPC_IF_COMMA(x) CPP_IFELSE(x, RPC_COMMA, RPC_NOCOMMA) - -/* Append the argument __RLA_ARG, whose type is __RLA_TYPE, to the - message buffer MSG. */ -#define RPCLOADARG(__rla_type, __rla_arg) \ - { \ - if (__builtin_strcmp (#__rla_type, "cap_t") == 0) \ - { \ - union \ - { \ - __rla_type __rla_a; \ - RPC_GRAB2 (, 1, RPC_TYPE_SHIFT (1, struct cap *, cap_t, __rla_foo)); \ - cap_t __rla_cap; \ - } __rla_arg2 = { (__rla_arg) }; \ - vg_message_append_cap (msg, __rla_arg2.__rla_cap); \ - } \ - else \ - { \ - union \ - { \ - __rla_type __rla_a; \ - uintptr_t __rla_raw[(sizeof (__rla_type) + sizeof (uintptr_t) - 1) \ - / sizeof (uintptr_t)]; \ - } __rla_arg2 = { (__rla_arg) }; \ - int __rla_i; \ - for (__rla_i = 0; \ - __rla_i < sizeof (__rla_arg2) / sizeof (uintptr_t); \ - __rla_i ++) \ - vg_message_append_word (msg, __rla_arg2.__rla_raw[__rla_i]); \ - } \ - } - -#define RPCLOAD0(...) -#define RPCLOAD1(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD0(__VA_ARGS__) -#define RPCLOAD2(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD1(__VA_ARGS__) -#define RPCLOAD3(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD2(__VA_ARGS__) -#define RPCLOAD4(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD3(__VA_ARGS__) -#define RPCLOAD5(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD4(__VA_ARGS__) -#define RPCLOAD6(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD5(__VA_ARGS__) -#define RPCLOAD7(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD6(__VA_ARGS__) -#define RPCLOAD8(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD7(__VA_ARGS__) -#define RPCLOAD9(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD8(__VA_ARGS__) -#define RPCLOAD10(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD9(__VA_ARGS__) -#define RPCLOAD11(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD10(__VA_ARGS__) -#define RPCLOAD12(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD11(__VA_ARGS__) -#define RPCLOAD13(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD12(__VA_ARGS__) -#define RPCLOAD14(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD13(__VA_ARGS__) -#define RPCLOAD15(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD14(__VA_ARGS__) -#define RPCLOAD16(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD15(__VA_ARGS__) -#define RPCLOAD17(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD16(__VA_ARGS__) -#define RPCLOAD18(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD17(__VA_ARGS__) -#define RPCLOAD19(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD18(__VA_ARGS__) -#define RPCLOAD20(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD19(__VA_ARGS__) -#define RPCLOAD21(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD20(__VA_ARGS__) -#define RPCLOAD22(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD21(__VA_ARGS__) -#define RPCLOAD23(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD22(__VA_ARGS__) -#define RPCLOAD24(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD23(__VA_ARGS__) -#define RPCLOAD25(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD24(__VA_ARGS__) -#define RPCLOAD_(__rl_count, ...) RPCLOAD##__rl_count (__VA_ARGS__) -#define RPCLOAD(__rl_count, ...) RPCLOAD_ (__rl_count, __VA_ARGS__) - -/* Store the next argument in the message MSG whose type is __RSA_TYPE - in *__RSA_ARG. */ -#define RPCSTOREARG(__rsa_type, __rsa_arg) \ - { \ - if (__builtin_strcmp (#__rsa_type, "cap_t") == 0) \ - { \ - union \ - { \ - __rsa_type *__rsa_a; \ - cap_t *__rsa_cap; \ - } __rsa_arg2; \ - __rsa_arg2.__rsa_a = __rsa_arg; \ - if (vg_message_cap_count (msg) > __rsu_cap_idx) \ - { \ - if (__rsa_arg) \ - *__rsa_arg2.__rsa_cap = vg_message_cap (msg, __rsu_cap_idx); \ - __rsu_cap_idx ++; \ - } \ - else \ - __rsu_err = EINVAL; \ - } \ - else \ - { \ - union \ - { \ - __rsa_type __rsa_a; \ - uintptr_t __rsa_raw[(sizeof (__rsa_type) + sizeof (uintptr_t) - 1) \ - / sizeof (uintptr_t)]; \ - } __rsa_arg2; \ - int __rsa_i; \ - for (__rsa_i = 0; \ - __rsa_i < sizeof (__rsa_arg2) / sizeof (uintptr_t); \ - __rsa_i ++) \ - if (vg_message_data_count (msg) / sizeof (uintptr_t) \ - > __rsu_data_idx) \ - __rsa_arg2.__rsa_raw[__rsa_i] \ - = vg_message_word (msg, __rsu_data_idx ++); \ - else \ - __rsu_err = EINVAL; \ - if (! __rsu_err && __rsa_arg) \ - *(__rsa_arg) = __rsa_arg2.__rsa_a; \ - } \ - } - -#define RPCSTORE0(...) -#define RPCSTORE1(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE0(__VA_ARGS__) -#define RPCSTORE2(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE1(__VA_ARGS__) -#define RPCSTORE3(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE2(__VA_ARGS__) -#define RPCSTORE4(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE3(__VA_ARGS__) -#define RPCSTORE5(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE4(__VA_ARGS__) -#define RPCSTORE6(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE5(__VA_ARGS__) -#define RPCSTORE7(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE6(__VA_ARGS__) -#define RPCSTORE8(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE7(__VA_ARGS__) -#define RPCSTORE9(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE8(__VA_ARGS__) -#define RPCSTORE10(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE9(__VA_ARGS__) -#define RPCSTORE11(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE10(__VA_ARGS__) -#define RPCSTORE12(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE11(__VA_ARGS__) -#define RPCSTORE13(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE12(__VA_ARGS__) -#define RPCSTORE14(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE13(__VA_ARGS__) -#define RPCSTORE15(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE14(__VA_ARGS__) -#define RPCSTORE16(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE15(__VA_ARGS__) -#define RPCSTORE17(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE16(__VA_ARGS__) -#define RPCSTORE18(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE17(__VA_ARGS__) -#define RPCSTORE19(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE18(__VA_ARGS__) -#define RPCSTORE20(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE19(__VA_ARGS__) -#define RPCSTORE21(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE20(__VA_ARGS__) -#define RPCSTORE22(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE21(__VA_ARGS__) -#define RPCSTORE23(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE22(__VA_ARGS__) -#define RPCSTORE24(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE23(__VA_ARGS__) -#define RPCSTORE25(__rs_type, __rs_arg, ...) \ - RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE24(__VA_ARGS__) - -#define RPCSTORE_(__rs_count, ...) RPCSTORE##__rs_count (__VA_ARGS__) -#define RPCSTORE(__rs_count, ...) RPCSTORE_ (__rs_count, __VA_ARGS__) - -/* Marshal a request. */ -#define RPC_SEND_MARSHAL(id, icount, ...) \ - static inline void \ - __attribute__((always_inline)) \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_marshal) \ - (struct vg_message *msg, \ - RPC_GRAB2 (, icount, ##__VA_ARGS__) RPC_IF_COMMA(icount) () \ - cap_t reply_messenger) \ - { \ - vg_message_clear (msg); \ - /* Add the label. */ \ - vg_message_append_word (msg, RPC_ID_PREFIX_(id)); \ - /* Then load the arguments. */ \ - RPCLOAD (icount, ##__VA_ARGS__); \ - /* Finally, add the reply messenger. */ \ - vg_message_append_cap (msg, reply_messenger); \ - } - -/* Unmarshal a request. */ -#define RPC_SEND_UNMARSHAL(id, icount, ...) \ - static inline error_t \ - __attribute__((always_inline)) \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_unmarshal) \ - (struct vg_message *msg, \ - RPC_GRAB2 (*, icount, ##__VA_ARGS__) RPC_IF_COMMA(icount) () \ - cap_t *reply_messenger) \ - { \ - uintptr_t label = 0; \ - if (likely (vg_message_data_count (msg) >= sizeof (uintptr_t))) \ - label = vg_message_word (msg, 0); \ - if (label != RPC_ID_PREFIX_(id)) \ - { \ - debug (1, #id " has bad method id, %d, excepted %d", \ - label, RPC_ID_PREFIX_(id)); \ - return EINVAL; \ - } \ - \ - int __rsu_data_idx __attribute__ ((unused)) = 1; \ - int __rsu_cap_idx __attribute__ ((unused)) = 0; \ - error_t __rsu_err = 0; \ - RPCSTORE (icount, ##__VA_ARGS__); \ - if (unlikely (__rsu_err \ - || (__rsu_data_idx * sizeof (uintptr_t) \ - != vg_message_data_count (msg) \ - && __rsu_cap_idx + 1 != vg_message_cap_count (msg)))) \ - { \ - debug (1, #id " has wrong number of arguments: " \ - "got %d bytes and %d caps; expected %d/%d", \ - __rsu_data_idx * sizeof (uintptr_t), __rsu_cap_idx + 1, \ - vg_message_data_count (msg), \ - vg_message_cap_count (msg)); \ - return EINVAL; \ - } \ - \ - if (reply_messenger) \ - *reply_messenger = vg_message_cap (msg, __rsu_cap_idx); \ - return 0; \ - } - -/* Prepare a receive buffer. */ -#ifdef RM_INTERN -#define RPC_RECEIVE_MARSHAL(id, ret_cap_count, ...) -#else -#define RPC_RECEIVE_MARSHAL(id, ret_cap_count, ...) \ - static inline void \ - __attribute__((always_inline)) \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _receive_marshal) \ - (struct vg_message *msg RPC_IF_COMMA(ret_cap_count) () \ - RPC_GRAB2 (, ret_cap_count, ##__VA_ARGS__)) \ - { \ - vg_message_clear (msg); \ - /* Load the arguments. */ \ - RPCLOAD (ret_cap_count, ##__VA_ARGS__); \ - assert (vg_message_data_count (msg) == 0); \ - assert (vg_message_cap_count (msg) == ret_cap_count); \ - } -#endif - -/* Marshal a reply. */ -#define RPC_REPLY_MARSHAL(id, out_count, ret_cap_count, ...) \ - static inline void \ - __attribute__((always_inline)) \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_marshal) \ - (struct vg_message *msg \ - RPC_IF_COMMA (out_count) () \ - RPC_GRAB2 (, out_count, ##__VA_ARGS__) \ - RPC_IF_COMMA (ret_cap_count) () \ - RPC_GRAB2 (, ret_cap_count, \ - RPC_TYPE_SHIFT (ret_cap_count, struct cap *, \ - RPC_CHOP2 (out_count, __VA_ARGS__)))) \ - { \ - vg_message_clear (msg); \ - \ - /* The error code. */ \ - vg_message_append_word (msg, 0); \ - RPCLOAD (CPP_ADD (out_count, ret_cap_count), ##__VA_ARGS__); \ - \ - assert (vg_message_cap_count (msg) == ret_cap_count); \ - } - -/* Unmarshal a reply. */ -#define RPC_REPLY_UNMARSHAL(id, out_count, ret_cap_count, ...) \ - static inline error_t \ - __attribute__((always_inline)) \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_unmarshal) \ - (struct vg_message *msg \ - RPC_IF_COMMA (CPP_ADD (out_count, ret_cap_count)) () \ - RPC_GRAB2(*, CPP_ADD (out_count, ret_cap_count), ##__VA_ARGS__)) \ - { \ - /* The server error code. */ \ - error_t __rsu_err = EINVAL; \ - if (likely (vg_message_data_count (msg) >= sizeof (uintptr_t))) \ - __rsu_err = vg_message_word (msg, 0); \ - if (unlikely (__rsu_err)) \ - return __rsu_err; \ - \ - int __rsu_data_idx __attribute__ ((unused)) = 1; \ - int __rsu_cap_idx __attribute__ ((unused)) = 0; \ - RPCSTORE (CPP_ADD (out_count, ret_cap_count), ##__VA_ARGS__); \ - if (unlikely (__rsu_err \ - || (__rsu_data_idx * sizeof (uintptr_t) \ - != vg_message_data_count (msg) \ - || __rsu_cap_idx != vg_message_cap_count (msg)))) \ - { \ - debug (1, #id " has wrong number of arguments: " \ - "got %d bytes and %d caps; expected %d/%d", \ - __rsu_data_idx * sizeof (uintptr_t), __rsu_cap_idx, \ - vg_message_data_count (msg), \ - vg_message_cap_count (msg)); \ - return EINVAL; \ - } \ - return 0; \ - } - -/* RPC_ARGUMENTS takes a list of types and arguments and returns the first - COUNT arguments. (NB: the list may contain more than COUNT - arguments!). - - RPC_ARGUMENTS(2, &, int, i, int, j, double, d) - - => - - &i, &j -*/ -#define RPC_ARGUMENTS0(...) -#define RPC_ARGUMENTS1(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg RPC_ARGUMENTS0(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS2(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS1(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS3(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS2(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS4(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS3(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS5(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS4(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS6(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS5(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS7(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS6(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS8(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS7(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS9(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS8(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS10(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS9(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS11(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS10(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS12(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS11(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS13(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS12(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS14(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS13(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS15(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS14(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS16(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS15(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS17(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS16(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS18(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS17(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS19(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS18(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS20(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS19(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS_(__ra_count, __ra_prefix, ...) RPC_ARGUMENTS##__ra_count(__ra_prefix, __VA_ARGS__) -#define RPC_ARGUMENTS(__ra_count, __ra_prefix, ...) RPC_ARGUMENTS_(__ra_count, __ra_prefix, __VA_ARGS__) - -/* Given a list of arguments, returns the arguments minus the first - COUNT **pairs** of arguments. For example: - - RPC_CHOP2(1, int, i, int, j, double, d) - - => - - int, j, double, d - - */ -#define RPC_CHOP2_0(...) __VA_ARGS__ -#define RPC_CHOP2_1(__rc_a, __rc_b, ...) RPC_CHOP2_0(__VA_ARGS__) -#define RPC_CHOP2_2(__rc_a, __rc_b, ...) RPC_CHOP2_1(__VA_ARGS__) -#define RPC_CHOP2_3(__rc_a, __rc_b, ...) RPC_CHOP2_2(__VA_ARGS__) -#define RPC_CHOP2_4(__rc_a, __rc_b, ...) RPC_CHOP2_3(__VA_ARGS__) -#define RPC_CHOP2_5(__rc_a, __rc_b, ...) RPC_CHOP2_4(__VA_ARGS__) -#define RPC_CHOP2_6(__rc_a, __rc_b, ...) RPC_CHOP2_5(__VA_ARGS__) -#define RPC_CHOP2_7(__rc_a, __rc_b, ...) RPC_CHOP2_6(__VA_ARGS__) -#define RPC_CHOP2_8(__rc_a, __rc_b, ...) RPC_CHOP2_7(__VA_ARGS__) -#define RPC_CHOP2_9(__rc_a, __rc_b, ...) RPC_CHOP2_8(__VA_ARGS__) -#define RPC_CHOP2_10(__rc_a, __rc_b, ...) RPC_CHOP2_9(__VA_ARGS__) -#define RPC_CHOP2_11(__rc_a, __rc_b, ...) RPC_CHOP2_10(__VA_ARGS__) -#define RPC_CHOP2_12(__rc_a, __rc_b, ...) RPC_CHOP2_11(__VA_ARGS__) -#define RPC_CHOP2_13(__rc_a, __rc_b, ...) RPC_CHOP2_12(__VA_ARGS__) -#define RPC_CHOP2_14(__rc_a, __rc_b, ...) RPC_CHOP2_13(__VA_ARGS__) -#define RPC_CHOP2_15(__rc_a, __rc_b, ...) RPC_CHOP2_14(__VA_ARGS__) -#define RPC_CHOP2_16(__rc_a, __rc_b, ...) RPC_CHOP2_15(__VA_ARGS__) -#define RPC_CHOP2_17(__rc_a, __rc_b, ...) RPC_CHOP2_16(__VA_ARGS__) -#define RPC_CHOP2_18(__rc_a, __rc_b, ...) RPC_CHOP2_17(__VA_ARGS__) -#define RPC_CHOP2_19(__rc_a, __rc_b, ...) RPC_CHOP2_18(__VA_ARGS__) -#define RPC_CHOP2_20(__rc_a, __rc_b, ...) RPC_CHOP2_19(__VA_ARGS__) -#define RPC_CHOP2_21(__rc_a, __rc_b, ...) RPC_CHOP2_20(__VA_ARGS__) -#define RPC_CHOP2_22(__rc_a, __rc_b, ...) RPC_CHOP2_21(__VA_ARGS__) -#define RPC_CHOP2_23(__rc_a, __rc_b, ...) RPC_CHOP2_22(__VA_ARGS__) -#define RPC_CHOP2_24(__rc_a, __rc_b, ...) RPC_CHOP2_23(__VA_ARGS__) -#define RPC_CHOP2_25(__rc_a, __rc_b, ...) RPC_CHOP2_24(__VA_ARGS__) -#define RPC_CHOP2_(__rc_count, ...) RPC_CHOP2_##__rc_count (__VA_ARGS__) -#define RPC_CHOP2(__rc_count, ...) RPC_CHOP2_(__rc_count, __VA_ARGS__) - -/* Given a list of arguments, returns the first COUNT **pairs** of - arguments, the elements of each pair separated by SEP and each pair - separated by a comma. For example: - - For example: - - RPC_GRAB2(, 2, int, i, int, j, double, d) - - => - - int i, int j -*/ -#define RPC_GRAB2_0(__rg_sep, ...) -#define RPC_GRAB2_1(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b RPC_GRAB2_0(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_2(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_1(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_3(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_2(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_4(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_3(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_5(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_4(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_6(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_5(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_7(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_6(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_8(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_7(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_9(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_8(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_10(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_9(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_11(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_10(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_12(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_11(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_13(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_12(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_14(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_13(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_15(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_14(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_16(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_15(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_17(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_16(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_18(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_17(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_19(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_18(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_20(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_19(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_21(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_20(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_22(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_21(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_23(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_22(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_24(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_23(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_25(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_24(__rg_sep, __VA_ARGS__) -#define RPC_GRAB2_(__rg_sep, __rg_count, ...) RPC_GRAB2_##__rg_count (__rg_sep, __VA_ARGS__) -#define RPC_GRAB2(__rg_sep, __rg_count, ...) RPC_GRAB2_(__rg_sep, __rg_count, __VA_ARGS__) - -#define RPC_GRAB_0(...) -#define RPC_GRAB_1(__rg_a, ...) __rg_a RPC_GRAB_0(__VA_ARGS__) -#define RPC_GRAB_2(__rg_a, ...) __rg_a, RPC_GRAB_1(__VA_ARGS__) -#define RPC_GRAB_3(__rg_a, ...) __rg_a, RPC_GRAB_2(__VA_ARGS__) -#define RPC_GRAB_4(__rg_a, ...) __rg_a, RPC_GRAB_3(__VA_ARGS__) -#define RPC_GRAB_5(__rg_a, ...) __rg_a, RPC_GRAB_4(__VA_ARGS__) -#define RPC_GRAB_6(__rg_a, ...) __rg_a, RPC_GRAB_5(__VA_ARGS__) -#define RPC_GRAB_7(__rg_a, ...) __rg_a, RPC_GRAB_6(__VA_ARGS__) -#define RPC_GRAB_8(__rg_a, ...) __rg_a, RPC_GRAB_7(__VA_ARGS__) -#define RPC_GRAB_9(__rg_a, ...) __rg_a, RPC_GRAB_8(__VA_ARGS__) -#define RPC_GRAB_10(__rg_a, ...) __rg_a, RPC_GRAB_9(__VA_ARGS__) -#define RPC_GRAB_11(__rg_a, ...) __rg_a, RPC_GRAB_10(__VA_ARGS__) -#define RPC_GRAB_12(__rg_a, ...) __rg_a, RPC_GRAB_11(__VA_ARGS__) -#define RPC_GRAB_13(__rg_a, ...) __rg_a, RPC_GRAB_12(__VA_ARGS__) -#define RPC_GRAB_14(__rg_a, ...) __rg_a, RPC_GRAB_13(__VA_ARGS__) -#define RPC_GRAB_15(__rg_a, ...) __rg_a, RPC_GRAB_14(__VA_ARGS__) -#define RPC_GRAB_16(__rg_a, ...) __rg_a, RPC_GRAB_15(__VA_ARGS__) -#define RPC_GRAB_17(__rg_a, ...) __rg_a, RPC_GRAB_16(__VA_ARGS__) -#define RPC_GRAB_18(__rg_a, ...) __rg_a, RPC_GRAB_17(__VA_ARGS__) -#define RPC_GRAB_19(__rg_a, ...) __rg_a, RPC_GRAB_18(__VA_ARGS__) -#define RPC_GRAB_20(__rg_a, ...) __rg_a, RPC_GRAB_19(__VA_ARGS__) -#define RPC_GRAB_21(__rg_a, ...) __rg_a, RPC_GRAB_20(__VA_ARGS__) -#define RPC_GRAB_22(__rg_a, ...) __rg_a, RPC_GRAB_21(__VA_ARGS__) -#define RPC_GRAB_23(__rg_a, ...) __rg_a, RPC_GRAB_22(__VA_ARGS__) -#define RPC_GRAB_24(__rg_a, ...) __rg_a, RPC_GRAB_23(__VA_ARGS__) -#define RPC_GRAB_25(__rg_a, ...) __rg_a, RPC_GRAB_24(__VA_ARGS__) -#define RPC_GRAB_(__rg_count, ...) RPC_GRAB_##__rg_count (__VA_ARGS__) -#define RPC_GRAB(__rg_count, ...) RPC_GRAB_(__rg_count, __VA_ARGS__) - -#define RPC_TYPE_SHIFT_0(...) -#define RPC_TYPE_SHIFT_1(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg RPC_TYPE_SHIFT_0(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_2(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_1(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_3(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_2(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_4(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_3(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_5(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_4(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_6(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_5(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_7(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_6(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_8(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_7(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_9(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_8(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_10(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_9(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_11(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_10(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_12(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_11(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_13(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_12(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_14(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_13(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_15(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_14(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_16(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_15(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_17(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_16(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_18(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_17(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_19(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_18(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_20(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_19(__ra_new_type, __VA_ARGS__) -#define RPC_TYPE_SHIFT_(__ra_count, __ra_new_type, ...) RPC_TYPE_SHIFT_##__ra_count(__ra_new_type, __VA_ARGS__) -#ifdef RM_INTERN -# define RPC_TYPE_SHIFT(__ra_count, __ra_new_type, ...) RPC_TYPE_SHIFT_(__ra_count, __ra_new_type, __VA_ARGS__) -#else -# define RPC_TYPE_SHIFT(__ra_count, __ra_new_type, ...) __VA_ARGS__ -#endif - -/* Ensure that there are X pairs of arguments. */ -#define RPC_INVALID_NUMBER_OF_ARGUMENTS_ -#define RPC_EMPTY_LIST_(x) RPC_INVALID_NUMBER_OF_ARGUMENTS_##x -#define RPC_EMPTY_LIST(x) RPC_EMPTY_LIST_(x) -#define RPC_ENSURE_ARGS(count, ...) \ - RPC_EMPTY_LIST (RPC_CHOP2 (count, __VA_ARGS__)) - -#define RPC_SEND_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ...) \ - RPC_SEND_MARSHAL(id, in_count, ##__VA_ARGS__) \ - RPC_SEND_UNMARSHAL(id, in_count, ##__VA_ARGS__) - -#define RPC_RECEIVE_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ...) \ - RPC_RECEIVE_MARSHAL(id, ret_cap_count, \ - RPC_CHOP2 (CPP_ADD (in_count, out_count), \ - ##__VA_ARGS__)) - -#define RPC_REPLY_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ...) \ - RPC_REPLY_MARSHAL(id, out_count, ret_cap_count, \ - RPC_CHOP2 (in_count, ##__VA_ARGS__)) \ - RPC_REPLY_UNMARSHAL(id, out_count, ret_cap_count, \ - RPC_CHOP2 (in_count, ##__VA_ARGS__)) - -#define RPC_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ...) \ - RPC_ENSURE_ARGS(CPP_ADD (CPP_ADD (in_count, out_count), \ - ret_cap_count), \ - ##__VA_ARGS__) \ - RPC_SEND_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, \ - ##__VA_ARGS__) \ - RPC_RECEIVE_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, \ - ##__VA_ARGS__) \ - RPC_REPLY_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, \ - ##__VA_ARGS__) - -/* Send a message. __RPC_REPY_MESSENGER designates the messenger that - should receive the reply. (Its buffer should have already been - prepared using, e.g., the corresponding receive_marshal - function.) */ -#ifndef RM_INTERN -#define RPC_SEND_(postfix, id, in_count, out_count, ret_cap_count, ...) \ - static inline error_t \ - __attribute__((always_inline)) \ - RPC_CONCAT(RPC_STUB_PREFIX_(id), postfix) \ - (cap_t __rpc_activity, cap_t __rpc_object \ - RPC_IF_COMMA (in_count) () \ - RPC_GRAB2 (, in_count, __VA_ARGS__), \ - cap_t __rpc_reply_messenger) \ - { \ - struct hurd_message_buffer *mb = hurd_message_buffer_alloc (); \ - mb->just_free = true; \ - \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_marshal) \ - (mb->request \ - RPC_IF_COMMA (in_count) () RPC_ARGUMENTS(in_count,, __VA_ARGS__), \ - __rpc_reply_messenger); \ - \ - error_t err = vg_send (VG_IPC_SEND_SET_THREAD_TO_CALLER \ - | VG_IPC_SEND_SET_ASROOT_TO_CALLERS, \ - __rpc_activity, __rpc_object, \ - mb->sender, ADDR_VOID); \ - \ - return err; \ - } -#else -#define RPC_SEND_(postfix, id, in_count, out_count, ret_cap_count, ...) -#endif - -/* Send a message. Abort if the target is not ready. */ -#ifndef RM_INTERN -#define RPC_SEND_NONBLOCKING_(postfix, id, in_count, out_count, ret_cap_count, ...) \ - static inline error_t \ - __attribute__((always_inline)) \ - RPC_CONCAT(RPC_STUB_PREFIX_(id), postfix) \ - (cap_t __rpc_activity, cap_t __rpc_object \ - RPC_IF_COMMA (in_count) () \ - RPC_GRAB2 (, in_count, __VA_ARGS__), \ - cap_t __rpc_reply_messenger) \ - { \ - struct hurd_message_buffer *mb = hurd_message_buffer_alloc (); \ - \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_marshal) \ - (mb->request \ - RPC_IF_COMMA (in_count) () RPC_ARGUMENTS(in_count,, __VA_ARGS__), \ - __rpc_reply_messenger); \ - \ - error_t err = vg_reply (VG_IPC_SEND_SET_THREAD_TO_CALLER \ - | VG_IPC_SEND_SET_ASROOT_TO_CALLERS, \ - __rpc_activity, __rpc_object, \ - mb->sender, ADDR_VOID); \ - \ - hurd_message_buffer_free (mb); \ - \ - return err; \ - } -#else -#define RPC_SEND_NONBLOCKING_(postfix, id, in_count, out_count, ret_cap_count, ...) -#endif - -/* Send a message and wait for a reply. */ -#ifndef RM_INTERN -#define RPC_(postfix, id, in_count, out_count, ret_cap_count, ...) \ - static inline error_t \ - __attribute__((always_inline)) \ - RPC_CONCAT (RPC_CONCAT (RPC_STUB_PREFIX_(id), _using), postfix) \ - (struct hurd_message_buffer *mb, \ - addr_t __rpc_activity, \ - addr_t __rpc_object \ - /* In arguments. */ \ - RPC_IF_COMMA (in_count) () \ - RPC_GRAB2 (, in_count, __VA_ARGS__) \ - /* Out arguments (data and caps). */ \ - RPC_IF_COMMA (CPP_ADD (out_count, ret_cap_count)) () \ - RPC_GRAB2 (*, CPP_ADD (out_count, ret_cap_count), \ - RPC_CHOP2 (in_count, __VA_ARGS__))) \ - { \ - /* Prepare the reply buffer. */ \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _receive_marshal) \ - (mb->reply \ - RPC_IF_COMMA (ret_cap_count) () \ - CPP_FOREACH(ret_cap_count, CPP_SAFE_DEREF, ADDR_VOID, \ - RPC_ARGUMENTS (ret_cap_count, , \ - RPC_CHOP2 (CPP_ADD (in_count, out_count), \ - __VA_ARGS__)))); \ - \ - /* Then the send buffer. */ \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_marshal) \ - (mb->request \ - RPC_IF_COMMA (in_count) () \ - RPC_ARGUMENTS (in_count,, __VA_ARGS__), \ - mb->receiver); \ - \ - hurd_activation_message_register (mb); \ - \ - /* We will be resumed via an activation. */ \ - error_t err = vg_ipc (VG_IPC_RECEIVE | VG_IPC_SEND \ - | VG_IPC_RECEIVE_ACTIVATE \ - | VG_IPC_SEND_SET_THREAD_TO_CALLER \ - | VG_IPC_SEND_SET_ASROOT_TO_CALLERS \ - | VG_IPC_RECEIVE_SET_THREAD_TO_CALLER \ - | VG_IPC_RECEIVE_SET_ASROOT_TO_CALLERS, \ - __rpc_activity, \ - mb->receiver_strong, ADDR_VOID, \ - __rpc_activity, __rpc_object, \ - mb->sender, ADDR_VOID); \ - if (err) \ - /* Error sending the IPC. */ \ - hurd_activation_message_unregister (mb); \ - else \ - err = RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_unmarshal) \ - (mb->reply \ - RPC_IF_COMMA (CPP_ADD (out_count, ret_cap_count)) () \ - RPC_ARGUMENTS (CPP_ADD (out_count, ret_cap_count),, \ - RPC_CHOP2 (in_count, ##__VA_ARGS__))); \ - \ - return err; \ - } \ - \ - static inline error_t \ - __attribute__((always_inline)) \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), postfix) \ - (addr_t __rpc_activity, \ - addr_t __rpc_object \ - /* In arguments. */ \ - RPC_IF_COMMA (in_count) () \ - RPC_GRAB2 (, in_count, __VA_ARGS__) \ - /* Out arguments (data and caps). */ \ - RPC_IF_COMMA (CPP_ADD (out_count, ret_cap_count)) () \ - RPC_GRAB2 (*, CPP_ADD (out_count, ret_cap_count), \ - RPC_CHOP2 (in_count, __VA_ARGS__))) \ - { \ - struct hurd_message_buffer *mb = hurd_message_buffer_alloc (); \ - \ - error_t err; \ - err = RPC_CONCAT (RPC_CONCAT (RPC_STUB_PREFIX_(id), _using), postfix) \ - (mb, __rpc_activity, __rpc_object \ - RPC_IF_COMMA (CPP_ADD (CPP_ADD (in_count, out_count), \ - ret_cap_count)) () \ - RPC_ARGUMENTS (CPP_ADD (CPP_ADD (in_count, out_count), \ - ret_cap_count),, __VA_ARGS__)); \ - \ - hurd_message_buffer_free (mb); \ - \ - return err; \ - } -#else -# define RPC_(postfix, id, in_count, out_count, ret_cap_count, ...) -#endif - -/* Send a reply to __RPC_TARGET. If __RPC_TARGET does not accept the - message immediately, abort sending. */ -#ifndef RM_INTERN -#define RPC_REPLY_(id, in_count, out_count, ret_cap_count, ...) \ - static inline error_t \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply) \ - (addr_t __rpc_activity, \ - addr_t __rpc_target \ - /* Out data. */ \ - RPC_IF_COMMA (out_count) () \ - RPC_GRAB2 (, out_count, RPC_CHOP2 (in_count, ##__VA_ARGS__)) \ - /* Return capabilities. */ \ - RPC_IF_COMMA (ret_cap_count) () \ - RPC_GRAB2 (, ret_cap_count, \ - RPC_CHOP2 (CPP_ADD (in_count, out_count), \ - ##__VA_ARGS__))) \ - { \ - struct hurd_message_buffer *mb = hurd_message_buffer_alloc (); \ - \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_marshal) \ - (mb->request \ - /* Out data. */ \ - RPC_IF_COMMA (out_count) () \ - RPC_ARGUMENTS(out_count,, RPC_CHOP2 (in_count, __VA_ARGS__)) \ - /* Out capabilities. */ \ - RPC_IF_COMMA (ret_cap_count) () \ - RPC_ARGUMENTS(ret_cap_count,, \ - RPC_CHOP2 (CPP_ADD (in_count, out_count), \ - __VA_ARGS__))); \ - \ - error_t err = vg_reply (VG_IPC_SEND_SET_THREAD_TO_CALLER \ - | VG_IPC_SEND_SET_ASROOT_TO_CALLERS, \ - __rpc_activity, __rpc_target, \ - mb->sender, ADDR_VOID); \ - \ - hurd_message_buffer_free (mb); \ - \ - return err; \ - } -#else -#define RPC_REPLY_(id, in_count, out_count, ret_cap_count, ...) \ - static inline error_t \ - __attribute__((always_inline)) \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply) \ - (struct activity *__rpc_activity, \ - struct messenger *__rpc_target \ - /* Out data. */ \ - RPC_IF_COMMA (out_count) () \ - RPC_GRAB2 (, out_count, RPC_CHOP2 (in_count, ##__VA_ARGS__)) \ - /* Return capabilities. */ \ - RPC_IF_COMMA (ret_cap_count) () \ - RPC_GRAB2 (, ret_cap_count, \ - RPC_TYPE_SHIFT (ret_cap_count, struct cap, \ - RPC_CHOP2 (CPP_ADD (in_count, out_count), \ - ##__VA_ARGS__)))) \ - { \ - RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_marshal) \ - (reply_buffer \ - /* Out data. */ \ - RPC_IF_COMMA (out_count) () \ - RPC_ARGUMENTS(out_count,, RPC_CHOP2 (in_count, ##__VA_ARGS__)) \ - /* Out capabilities. */ \ - RPC_IF_COMMA (ret_cap_count) () \ - RPC_ARGUMENTS (ret_cap_count, &, \ - RPC_CHOP2 (CPP_ADD (in_count, out_count), \ - ##__VA_ARGS__))); \ - \ - bool ret = messenger_message_load (__rpc_activity, \ - __rpc_target, reply_buffer); \ - \ - return ret ? 0 : EWOULDBLOCK; \ - } -#endif - -/* RPC template. ID is the method name. IN_COUNT is the number of - arguments. OUT_COUNT is the number of out arguments. - RET_CAP_COUNT is the number of capabilities that are returned. The - remaining arguments correspond to pairs of types and argument - names. - - Consider: - - RPC(method, 2, 1, 1, - // In (data and capability) parameters - int, foo, cap_t, bar, - // Out data parameters - int bam, - // Out capabilities - cap_t xyzzy) - - This will generate marshalling and unmarshalling functions as well - as send, reply and call functions. For instance, the signature for - the correspond send marshal function is: - - error_t method_send_marshal (struct vg_message *message, - int foo, cap_t bar, cap_t reply) - - that of the send unmarshal function is: - - error_t method_send_unmarshal (struct vg_message *message, - int *foo, cap_t *bar, cap_t *reply) - - that of the receive marshal function is: - - error_t method_receive_marshal (struct vg_message *message, - cap_t xyzzy) - - - that of the reply marshal function is: - - error_t method_reply_marshal (struct vg_message *message, - int bam, cap_t xyzzy) - - that of the reply unmarshal function is: - - error_t method_reply_unmarshal (struct vg_message *message, - int *bam, cap_t *xyzzy) - - Functions to send requests and replies as well as to produce calls - are also generated. - - error_t method_call (cap_t activity, cap_t object, - int foo, cap_t bar, int *bam, cap_t *xyzzy) - - Note that *XYZZY must be initialize with the location of a - capability slot to store the returned capability. *XYZZY is set to - ADDR_VOID if the sender did not provide a capability. - - To send a message and not wait for a reply, a function with the - following prototype is generated: - - error_t method_send (cap_t activity, cap_t object, - int foo, cap_t bar, - cap_t reply_messenger) - - To reply to a request, a function with the following prototype is - generated: - - error_t method_reply (cap_t activity, cap_t reply_messenger, - int bam, cap_t xyzzy) -*/ - -#define RPC(id, in_count, out_count, ret_cap_count, ...) \ - RPC_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ##__VA_ARGS__) \ - \ - RPC_(, id, in_count, out_count, ret_cap_count, ##__VA_ARGS__) \ - RPC_SEND_(_send, id, in_count, out_count, ret_cap_count, \ - ##__VA_ARGS__) \ - RPC_SEND_NONBLOCKING_(_send_nonblocking, \ - id, in_count, out_count, ret_cap_count, \ - ##__VA_ARGS__) \ - RPC_REPLY_(id, in_count, out_count, ret_cap_count, ##__VA_ARGS__) - -/* Marshal a reply consisting of the error code ERR in *MSG. */ -static inline void -__attribute__((always_inline)) -rpc_error_reply_marshal (struct vg_message *msg, error_t err) -{ - vg_message_clear (msg); - vg_message_append_word (msg, err); -} - -/* Reply to the target TARGET with error code ERROR. */ -#ifdef RM_INTERN -static inline error_t -__attribute__((always_inline)) -rpc_error_reply (struct activity *activity, struct messenger *target, - error_t err) -{ - rpc_error_reply_marshal (reply_buffer, err); - bool ret = messenger_message_load (activity, target, reply_buffer); - return ret ? 0 : EWOULDBLOCK; -} -#else -static inline error_t -__attribute__((always_inline)) -rpc_error_reply (cap_t activity, cap_t target, error_t err) -{ - return vg_ipc_short (VG_IPC_SEND_NONBLOCKING | VG_IPC_SEND_INLINE - | VG_IPC_SEND_INLINE_WORD1, - ADDR_VOID, ADDR_VOID, ADDR_VOID, - ADDR_VOID, target, - ADDR_VOID, err, 0, ADDR_VOID); -} -#endif - -#endif diff --git a/hurd/startup.h b/hurd/startup.h index 0c31d9f..8ca0da0 100644 --- a/hurd/startup.h +++ b/hurd/startup.h @@ -24,7 +24,7 @@ #include #include -#include +#include #ifdef USE_L4 # include diff --git a/hurd/t-addr-trans.c b/hurd/t-addr-trans.c deleted file mode 100644 index c3607ad..0000000 --- a/hurd/t-addr-trans.c +++ /dev/null @@ -1,84 +0,0 @@ -/* t-cap.c - Test the implementation of the various cap functions. - Copyright (C) 2007, 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 3 of the - License, or (at your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - . */ - -#include -#include -#include - -#include "stddef.h" -#include "addr-trans.h" - -int output_debug; -char *program_name = "t-addr-trans"; - -int -main (int argc, char *argv[]) -{ - printf ("Checking CAP_ADDR_TRANS_SET_GUARD_SUBPAGE... "); - - struct cap_addr_trans cap_addr_trans; - - bool r; - int subpage_bits; - for (subpage_bits = 0; subpage_bits < 16; subpage_bits ++) - { - int subpages = 1 << subpage_bits; - int subpage_size_log2 = 8 - subpage_bits; - int subpage_size = 1 << subpage_size_log2; - - memset (&cap_addr_trans, 0, sizeof (cap_addr_trans)); - - r = CAP_ADDR_TRANS_SET_SUBPAGE (&cap_addr_trans, 0, subpages); - assert (r == (subpage_bits <= 8)); - if (subpage_bits >= 8) - continue; - - assert (CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans) == subpages); - assert (CAP_ADDR_TRANS_SUBPAGE_SIZE (cap_addr_trans) == subpage_size); - assert (CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 (cap_addr_trans) - == subpage_size_log2); - - int gdepth; - for (gdepth = 0; gdepth < sizeof (uintptr_t) * 8; gdepth ++) - { - int guard_bits; - for (guard_bits = 0; guard_bits < sizeof (uintptr_t) * 8; guard_bits ++) - { - int guard = (1 << guard_bits) - 1; - r = CAP_ADDR_TRANS_SET_GUARD (&cap_addr_trans, guard, gdepth); - if (guard_bits <= gdepth - && (guard_bits + subpage_bits - <= CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS)) - { - assert (r); - assert (CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans) - == gdepth); - assert (CAP_ADDR_TRANS_GUARD (cap_addr_trans) == guard); - } - else - assert (! r); - } - } - } - - printf ("ok\n"); - - return 0; -} diff --git a/hurd/t-addr.c b/hurd/t-addr.c deleted file mode 100644 index 66e69cc..0000000 --- a/hurd/t-addr.c +++ /dev/null @@ -1,74 +0,0 @@ -/* t-addr.c - Test the implementation of the various addr functions. - Copyright (C) 2007 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 3 of the - License, or (at your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - . */ - -#include -#include -#include -#include -#include - -char *program_name = "t-addr"; -int output_debug = 0; - -int -main (int argc, char *argv[]) -{ - addr_t addr; - int i, j; - - printf ("Checking ADDR... "); - for (i = 0; i < ADDR_BITS; i ++) - { - addr = ADDR (1ULL << i, ADDR_BITS - i); - debug (1, "%llx/%d =? %llx/%d\n", - 1ULL << i, ADDR_BITS - i, - addr_prefix (addr), addr_depth (addr)); - assert (addr_depth (addr) == ADDR_BITS - i); - assert (addr_prefix (addr) == 1ull << i); - } - printf ("ok.\n"); - - printf ("Checking addr_extend... "); - addr = ADDR (0, 0); - for (i = 1; i < ADDR_BITS; i ++) - { - addr = addr_extend (addr, 1, 1); - assert (addr_depth (addr) == i); - assert (l4_msb64 (addr_prefix (addr)) == ADDR_BITS); - assert (l4_lsb64 (addr_prefix (addr)) == ADDR_BITS - i + 1); - } - printf ("ok.\n"); - - printf ("Checking addr_extract... "); - addr = ADDR (0, 0); - for (i = 0; i < ADDR_BITS; i ++) - { - addr = ADDR (((1ULL << i) - 1) << (ADDR_BITS - i), i); - - for (j = 0; j <= i; j ++) - { - l4_uint64_t idx = addr_extract (addr, j); - assert (idx == (1ULL << j) - 1); - } - } - printf ("ok.\n"); - - return 0; -} diff --git a/hurd/t-rpc.c b/hurd/t-rpc.c deleted file mode 100644 index b286296..0000000 --- a/hurd/t-rpc.c +++ /dev/null @@ -1,185 +0,0 @@ -#include -#include -#include - -char *program_name = "t-rpc"; -int output_debug = 1; - -#define RPC_STUB_PREFIX rpc -#define RPC_ID_PREFIX RPC - -#include - -/* Exception message ids. */ -enum - { - RPC_noargs = 0x1ABE100, - RPC_onein, - RPC_oneout, - RPC_onlyin, - RPC_onlyout, - RPC_mix, - RPC_caps, - }; - -struct foo -{ - int a; - char b; -}; - -RPC(noargs, 0, 0, 0) -RPC(onein, 1, 0, 0, uint32_t, arg) -RPC(oneout, 0, 1, 0, uint32_t, arg) -RPC(onlyin, 4, 0, 0, uint32_t, arg, uint32_t, idx, struct foo, foo, bool, p) -RPC(onlyout, 0, 4, 0, uint32_t, arg, uint32_t, idx, struct foo, foo, bool, p) -RPC(mix, 2, 3, 0, uint32_t, arg, uint32_t, idx, - struct foo, foo, bool, p, int, i) -RPC(caps, 3, 2, 2, - /* In: */ - int, i, cap_t, c, struct foo, foo, - /* Out: */ - int, a, int, b, cap_t, x, cap_t, y) - -#undef RPC_STUB_PREFIX -#undef RPC_ID_PREFIX - -int -main (int argc, char *argv[]) -{ - printf ("Checking RPC... "); - - error_t err; - struct vg_message *msg; - - -#define REPLY ADDR (0x1000, ADDR_BITS - 12) - addr_t reply = REPLY; - - msg = malloc (sizeof (*msg)); - rpc_noargs_send_marshal (msg, REPLY); - err = rpc_noargs_send_unmarshal (msg, &reply); - assert (! err); - assert (ADDR_EQ (reply, REPLY)); - free (msg); - - msg = malloc (sizeof (*msg)); - rpc_noargs_reply_marshal (msg); - err = rpc_noargs_reply_unmarshal (msg); - assert (err == 0); - free (msg); - - - msg = malloc (sizeof (*msg)); -#define VALUE 0xfde8963a - uint32_t arg = VALUE; - uint32_t arg_out; - - rpc_onein_send_marshal (msg, arg, REPLY); - err = rpc_onein_send_unmarshal (msg, &arg_out, &reply); - assert (! err); - assert (arg_out == VALUE); - assert (ADDR_EQ (reply, REPLY)); - free (msg); - - msg = malloc (sizeof (*msg)); - rpc_onein_reply_marshal (msg); - err = rpc_onein_reply_unmarshal (msg); - assert (! err); - free (msg); - - msg = malloc (sizeof (*msg)); - rpc_oneout_send_marshal (msg, REPLY); - err = rpc_oneout_send_unmarshal (msg, &reply); - assert (! err); - assert (ADDR_EQ (reply, REPLY)); - free (msg); - - msg = malloc (sizeof (*msg)); - rpc_oneout_reply_marshal (msg, arg); - err = rpc_oneout_reply_unmarshal (msg, &arg_out); - assert (! err); - assert (arg_out == VALUE); - free (msg); - - msg = malloc (sizeof (*msg)); - - struct foo foo; - foo.a = 1 << 31; - foo.b = 'l'; - uint32_t idx_out; - struct foo foo_out; - bool p_out; - - rpc_onlyin_send_marshal (msg, 0x1234567, 0xABC, foo, true, REPLY); - err = rpc_onlyin_send_unmarshal (msg, &arg_out, &idx_out, &foo_out, &p_out, - &reply); - assert (! err); - assert (arg_out == 0x1234567); - assert (idx_out == 0xABC); - assert (foo_out.a == foo.a); - assert (foo_out.b == foo.b); - assert (p_out == true); - assert (ADDR_EQ (reply, REPLY)); - free (msg); - - msg = malloc (sizeof (*msg)); - rpc_onlyin_reply_marshal (msg); - err = rpc_onlyin_reply_unmarshal (msg); - assert (! err); - free (msg); - - msg = malloc (sizeof (*msg)); - rpc_onlyout_send_marshal (msg, REPLY); - err = rpc_onlyout_send_unmarshal (msg, &reply); - assert (! err); - assert (ADDR_EQ (reply, REPLY)); - free (msg); - - msg = malloc (sizeof (*msg)); - rpc_onlyout_reply_marshal (msg, 0x1234567, 321, foo, true); - err = rpc_onlyout_reply_unmarshal (msg, &arg_out, &idx_out, - &foo_out, &p_out); - assert (! err); - assert (arg_out == 0x1234567); - assert (idx_out == 321); - assert (foo_out.a == foo.a); - assert (foo_out.b == foo.b); - assert (p_out == true); - free (msg); - - - msg = malloc (sizeof (*msg)); - rpc_mix_send_marshal (msg, arg, 456789, REPLY); - err = rpc_mix_send_unmarshal (msg, &arg_out, &idx_out, &reply); - assert (! err); - assert (arg_out == arg); - assert (idx_out == 456789); - assert (ADDR_EQ (reply, REPLY)); - free (msg); - - msg = malloc (sizeof (*msg)); - int i_out = 0; - rpc_mix_reply_marshal (msg, foo, false, 4200042); - err = rpc_mix_reply_unmarshal (msg, &foo_out, &p_out, &i_out); - assert (! err); - assert (foo_out.a == foo.a); - assert (foo_out.b == foo.b); - assert (p_out == false); - assert (i_out == 4200042); - free (msg); - - msg = malloc (sizeof (*msg)); - rpc_caps_send_marshal (msg, 54, ADDR (1, ADDR_BITS), foo, REPLY); - addr_t addr; - err = rpc_caps_send_unmarshal (msg, &i_out, &addr, &foo_out, &reply); - assert (! err); - assert (i_out == 54); - assert (ADDR_EQ (addr, ADDR (1, ADDR_BITS))); - assert (foo_out.a == foo.a); - assert (foo_out.b == foo.b); - free (msg); - - printf ("ok\n"); - return 0; -} diff --git a/hurd/thread.h b/hurd/thread.h index 522d13a..4427db3 100644 --- a/hurd/thread.h +++ b/hurd/thread.h @@ -16,23 +16,6 @@ License along with GNU Hurd. If not, see . */ -#ifndef __have_vg_thread_id_t -# define __have_vg_thread_id_t - -# ifdef USE_L4 -# include -typedef l4_thread_id_t vg_thread_id_t; -# define vg_niltid l4_nilthread -# define VG_THREAD_ID_FMT "%x" -# else -# include -typedef uint64_t vg_thread_id_t; -# define vg_niltid -1 -# define VG_THREAD_ID_FMT "%llx" -# endif - -#endif /* !__have_vg_thread_id_t */ - #ifndef __have_activation_frame # define __have_activation_frame @@ -95,22 +78,59 @@ struct activation_frame }; #endif -#if defined(__need_vg_thread_id_t) || defined (__need_activation_frame) -# undef __need_vg_thread_id_t +#if defined (__need_activation_frame) # undef __need_activation_frame #else #ifndef _HURD_THREAD_H #define _HURD_THREAD_H 1 +#include + #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include +/* The user thread control block. */ +struct hurd_utcb +{ + struct vg_utcb vg; + + /* Top of the activation frame stack (i.e., the active + activation). */ + struct activation_frame *activation_stack; + /* The bottom of the activation stack. */ + struct activation_frame *activation_stack_bottom; + + /* The CRC protects the above fields by checking for + modification, which can happen if a call back function uses + too much stack. The fields following crc are not protected + by the crc as they are expected to be changed by the + activation handler. */ + + uintptr_t crc; + + /* The exception buffer. */ + struct hurd_message_buffer *exception_buffer; + /* The current extant IPC. */ + struct hurd_message_buffer *extant_message; + + struct hurd_fault_catcher *catchers; + + /* The alternate activation stack. */ + void *alternate_stack; + bool alternate_stack_inuse; + +#define UTCB_CANARY0 0xCA17A1 +#define UTCB_CANARY1 0xDEADB15D + uintptr_t canary0; + uintptr_t canary1; +}; + /* Cause the activation frame to assume the state of the long jump buffer BUF. If SET_RET is true, the normal function return value is set to RET. */ @@ -141,258 +161,6 @@ extern void hurd_fault_catcher_register (struct hurd_fault_catcher *catcher); /* Unregister a fault catch handler. */ extern void hurd_fault_catcher_unregister (struct hurd_fault_catcher *catcher); - -/* The user thread control block. */ -struct vg_utcb -{ - union - { - /* The following structures are examined or modified by the - kernel. */ - - /* **** ia32-exception-entry.S silently depends on the layout of - this structure **** */ - struct - { - union - { - struct - { - /* Whether the thread is in activated mode. If so, any - activations that arrive during this time will be queued - or dropped. */ - uintptr_t activated_mode : 1; - /* Set by the kernel to indicated that there is a pending - message. */ - uintptr_t pending_message : 1; - /* Set by the kernel to indicate whether the thread was - interrupted while the EIP is in the transition range. */ - uintptr_t interrupt_in_transition : 1; - }; - uintptr_t mode; - }; - - /* The value of the IP and SP when the thread was running. */ - uintptr_t saved_ip; - uintptr_t saved_sp; - - /* Top of the activation frame stack (i.e., the active - activation). */ - struct activation_frame *activation_stack; - /* The bottom of the activation stack. */ - struct activation_frame *activation_stack_bottom; - - uintptr_t activation_handler_sp; - uintptr_t activation_handler_ip; - uintptr_t activation_handler_end; - - /* The protected payload of the capability that invoked the - messenger that caused this activation. */ - uint64_t protected_payload; - /* The messenger's id. */ - uint64_t messenger_id; - - uintptr_t inline_words[VG_MESSENGER_INLINE_WORDS]; - addr_t inline_caps[VG_MESSENGER_INLINE_CAPS]; - - union - { - struct - { - int inline_word_count : 2; - int inline_cap_count : 1; - }; - int inline_data : 3; - }; - - /* The following fields are not examined or modified by the - kernel. */ - - /* The CRC protects the above fields by checking for - modification, which can happen if a call back function uses - too much stack. The fields following crc are not protected - by the crc as they are expected to be changed by the - activation handler. */ - - uintptr_t crc; - - /* The exception buffer. */ - struct hurd_message_buffer *exception_buffer; - /* The current extant IPC. */ - struct hurd_message_buffer *extant_message; - - struct hurd_fault_catcher *catchers; - - /* The alternate activation stack. */ - void *alternate_stack; - bool alternate_stack_inuse; - -#define UTCB_CANARY0 0xCA17A1 -#define UTCB_CANARY1 0xDEADB15D - uintptr_t canary0; - uintptr_t canary1; - }; - char data[PAGESIZE]; - }; -}; - -/* A thread object's user accessible capability slots. */ -enum - { - /* Root of the address space. */ - THREAD_ASPACE_SLOT = 0, - /* The activity the thread is bound to. */ - THREAD_ACTIVITY_SLOT = 1, - /* The messenger to post exceptions to. */ - THREAD_EXCEPTION_MESSENGER = 2, - /* The user thread control block. Must be a cap_page. */ - THREAD_UTCB = 3, - - /* Total number of capability slots in a thread object. This must - be a power of 2. */ - THREAD_SLOTS = 4, - }; -#define THREAD_SLOTS_LOG2 2 - -enum -{ - HURD_EXREGS_SET_UTCB = 0x2000, - HURD_EXREGS_SET_EXCEPTION_MESSENGER = 0x1000, - HURD_EXREGS_SET_ASPACE = 0x800, - HURD_EXREGS_SET_ACTIVITY = 0x400, - HURD_EXREGS_SET_SP = _L4_XCHG_REGS_SET_SP, - HURD_EXREGS_SET_IP = _L4_XCHG_REGS_SET_IP, - HURD_EXREGS_SET_SP_IP = _L4_XCHG_REGS_SET_SP | _L4_XCHG_REGS_SET_IP, - HURD_EXREGS_SET_EFLAGS = _L4_XCHG_REGS_SET_FLAGS, - HURD_EXREGS_SET_USER_HANDLE = _L4_XCHG_REGS_SET_USER_HANDLE, - HURD_EXREGS_SET_REGS = (HURD_EXREGS_SET_UTCB - | HURD_EXREGS_SET_EXCEPTION_MESSENGER - | HURD_EXREGS_SET_ASPACE - | HURD_EXREGS_SET_ACTIVITY - | HURD_EXREGS_SET_SP - | HURD_EXREGS_SET_IP - | HURD_EXREGS_SET_EFLAGS - | HURD_EXREGS_SET_USER_HANDLE), - - HURD_EXREGS_GET_REGS = _L4_XCHG_REGS_DELIVER, - - HURD_EXREGS_START = _L4_XCHG_REGS_SET_HALT, - HURD_EXREGS_STOP = _L4_XCHG_REGS_SET_HALT | _L4_XCHG_REGS_HALT, - - HURD_EXREGS_ABORT_SEND = _L4_XCHG_REGS_CANCEL_SEND, - HURD_EXREGS_ABORT_RECEIVE = _L4_XCHG_REGS_CANCEL_RECV, - HURD_EXREGS_ABORT_IPC = HURD_EXREGS_ABORT_SEND | _L4_XCHG_REGS_CANCEL_RECV, -}; - -enum - { - RM_thread_exregs = 600, - RM_thread_id, - RM_thread_activation_collect, - }; - -#ifdef RM_INTERN -struct thread; -typedef struct thread *thread_t; -#else -typedef addr_t thread_t; -#endif - -#define RPC_STUB_PREFIX rm -#define RPC_ID_PREFIX RM - -#include - -struct hurd_thread_exregs_in -{ - uintptr_t aspace_cap_properties_flags; - struct cap_properties aspace_cap_properties; - - uintptr_t sp; - uintptr_t ip; - uintptr_t eflags; - uintptr_t user_handle; -}; - -struct hurd_thread_exregs_out -{ - uintptr_t sp; - uintptr_t ip; - uintptr_t eflags; - uintptr_t user_handle; -}; - -/* l4_exregs wrapper. */ -RPC (thread_exregs, 6, 1, 4, - /* cap_t principal, cap_t thread, */ - uintptr_t, control, struct hurd_thread_exregs_in, in, - cap_t, aspace, cap_t, activity, cap_t, utcb, cap_t, exception_messenger, - /* Out: */ - struct hurd_thread_exregs_out, out, - cap_t, aspace_out, cap_t, activity_out, cap_t, utcb_out, - cap_t, exception_messenger_out) - -static inline error_t -thread_start (addr_t thread) -{ - struct hurd_thread_exregs_in in; - struct hurd_thread_exregs_out out; - - return rm_thread_exregs (ADDR_VOID, thread, - HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC, - in, ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, - &out, NULL, NULL, NULL, NULL); -} - -static inline error_t -thread_start_sp_ip (addr_t thread, uintptr_t sp, uintptr_t ip) -{ - struct hurd_thread_exregs_in in; - struct hurd_thread_exregs_out out; - - in.sp = sp; - in.ip = ip; - - return rm_thread_exregs (ADDR_VOID, thread, - HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC - | HURD_EXREGS_SET_SP_IP, - in, ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, - &out, NULL, NULL, NULL, NULL); -} - -static inline error_t -thread_stop (addr_t thread) -{ - struct hurd_thread_exregs_in in; - struct hurd_thread_exregs_out out; - - return rm_thread_exregs (ADDR_VOID, thread, - HURD_EXREGS_STOP | HURD_EXREGS_ABORT_IPC, - in, ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, - &out, NULL, NULL, NULL, NULL); -} - -/* Return the unique integer associated with thread THREAD. */ -RPC(thread_id, 0, 1, 0, - /* cap_t, principal, cap_t, thread, */ - vg_thread_id_t, tid) - -/* Cause the delivery of a pending message, if any. */ -RPC(thread_activation_collect, 0, 0, 0 - /* cap_t principal, cap_t thread */) - -#undef RPC_STUB_PREFIX -#undef RPC_ID_PREFIX - -static inline vg_thread_id_t -vg_myself (void) -{ - vg_thread_id_t tid; - error_t err = rm_thread_id (ADDR_VOID, ADDR_VOID, &tid); - if (err) - return vg_niltid; - return tid; -} #endif /* _HURD_THREAD_H */ -#endif /* __need_vg_thread_id_t */ +#endif /* __need_activation_frame */ diff --git a/hurd/types.h b/hurd/types.h index fefe928..7d5e9be 100644 --- a/hurd/types.h +++ b/hurd/types.h @@ -22,6 +22,6 @@ #ifndef _HURD_TYPES_H #define _HURD_TYPES_H 1 -#include +#include #endif /* _HURD_TYPES_H */ diff --git a/libc-parts/_exit.c b/libc-parts/_exit.c index fc9630d..6e07898 100644 --- a/libc-parts/_exit.c +++ b/libc-parts/_exit.c @@ -20,7 +20,7 @@ #include #include -#include +#include int __global_zero; diff --git a/libc-parts/backtrace.c b/libc-parts/backtrace.c index 5439413..342c65d 100644 --- a/libc-parts/backtrace.c +++ b/libc-parts/backtrace.c @@ -33,6 +33,7 @@ #else # include +# include # include # define RA(level) \ diff --git a/libc-parts/process-spawn.c b/libc-parts/process-spawn.c index 4211951..843da21 100644 --- a/libc-parts/process-spawn.c +++ b/libc-parts/process-spawn.c @@ -18,10 +18,10 @@ along with this program. If not, see . */ -#include -#include +#include +#include +#include #include -#include #include #include diff --git a/libc-parts/process-spawn.h b/libc-parts/process-spawn.h index af23a77..b11d5ae 100644 --- a/libc-parts/process-spawn.h +++ b/libc-parts/process-spawn.h @@ -18,8 +18,8 @@ along with this program. If not, see . */ -#include -#include +#include +#include /* Load a task. Return a capability designating the main thread. The slot is allocated with capalloc. If MAKE_RUNNABLE is true, makes diff --git a/libc-parts/profile.c b/libc-parts/profile.c index 01525e5..58d8dec 100644 --- a/libc-parts/profile.c +++ b/libc-parts/profile.c @@ -31,8 +31,8 @@ #ifdef __gnu_hurd_viengoos__ # include -# include -# include +# include +# include #else # include # include diff --git a/libc-parts/s_printf.c b/libc-parts/s_printf.c index 7940af8..fa417fb 100644 --- a/libc-parts/s_printf.c +++ b/libc-parts/s_printf.c @@ -29,7 +29,7 @@ #endif #include -#include +#include #include "s-printf.h" diff --git a/libhurd-mm/anonymous.c b/libhurd-mm/anonymous.c index dc5a78b..c6f0bcb 100644 --- a/libhurd-mm/anonymous.c +++ b/libhurd-mm/anonymous.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include diff --git a/libhurd-mm/anonymous.h b/libhurd-mm/anonymous.h index e946dc2..fe5491e 100644 --- a/libhurd-mm/anonymous.h +++ b/libhurd-mm/anonymous.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff --git a/libhurd-mm/as-build-custom.c b/libhurd-mm/as-build-custom.c index d393f54..5c200ce 100644 --- a/libhurd-mm/as-build-custom.c +++ b/libhurd-mm/as-build-custom.c @@ -18,9 +18,9 @@ along with this program. If not, see . */ -#include -#include -#include +#include +#include +#include /* Expose as_slot_ensure_full_custom and as_insert_custom. */ #define ID_SUFFIX custom diff --git a/libhurd-mm/as-build.c b/libhurd-mm/as-build.c index 728183b..b2266cb 100644 --- a/libhurd-mm/as-build.c +++ b/libhurd-mm/as-build.c @@ -22,12 +22,12 @@ #include #include -#include +#include #include -#include +#include #include #include -#include +#include #ifndef RM_INTERN # include diff --git a/libhurd-mm/as-compute-gbits.h b/libhurd-mm/as-compute-gbits.h index 72faf8e..4fe1d42 100644 --- a/libhurd-mm/as-compute-gbits.h +++ b/libhurd-mm/as-compute-gbits.h @@ -18,7 +18,7 @@ along with this program. If not, see . */ -#include +#include struct as_guard_cappage { diff --git a/libhurd-mm/as-dump.c b/libhurd-mm/as-dump.c index f0f8e1f..4eb4168 100644 --- a/libhurd-mm/as-dump.c +++ b/libhurd-mm/as-dump.c @@ -18,8 +18,8 @@ along with this program. If not, see . */ -#include -#include +#include +#include #include #include #include diff --git a/libhurd-mm/as-lookup.c b/libhurd-mm/as-lookup.c index ca8fb30..7639fd1 100644 --- a/libhurd-mm/as-lookup.c +++ b/libhurd-mm/as-lookup.c @@ -18,8 +18,8 @@ along with this program. If not, see . */ -#include -#include +#include +#include #include #include #include diff --git a/libhurd-mm/as.c b/libhurd-mm/as.c index 4daed0c..be9dc09 100644 --- a/libhurd-mm/as.c +++ b/libhurd-mm/as.c @@ -20,11 +20,11 @@ #include "as.h" #include "storage.h" -#include +#include #include -#include -#include +#include +#include #include #include #include diff --git a/libhurd-mm/as.h b/libhurd-mm/as.h index 1e281b6..8343fdd 100644 --- a/libhurd-mm/as.h +++ b/libhurd-mm/as.h @@ -22,8 +22,8 @@ #ifndef _HURD_AS_H #define _HURD_AS_H -#include -#include +#include +#include #include #include #include diff --git a/libhurd-mm/capalloc.c b/libhurd-mm/capalloc.c index dde4956..998b123 100644 --- a/libhurd-mm/capalloc.c +++ b/libhurd-mm/capalloc.c @@ -24,7 +24,7 @@ #include "storage.h" #include "as.h" -#include +#include #include #include #include diff --git a/libhurd-mm/capalloc.h b/libhurd-mm/capalloc.h index 77d6359..5583f3f 100644 --- a/libhurd-mm/capalloc.h +++ b/libhurd-mm/capalloc.h @@ -22,7 +22,7 @@ #ifndef _HURD_CAP_ALLOC_H #define _HURD_CAP_ALLOC_H -#include +#include /* Allocate a capability slot. */ extern addr_t capalloc (void); diff --git a/libhurd-mm/exceptions.c b/libhurd-mm/exceptions.c index 26ad7c7..73d9a9f 100644 --- a/libhurd-mm/exceptions.c +++ b/libhurd-mm/exceptions.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -38,7 +38,7 @@ void hurd_fault_catcher_register (struct hurd_fault_catcher *catcher) { - struct vg_utcb *utcb = hurd_utcb (); + struct hurd_utcb *utcb = hurd_utcb (); assert (utcb); assert (catcher); @@ -153,7 +153,7 @@ hurd_activation_message_register (struct hurd_message_buffer *message_buffer) if (unlikely (! mm_init_done)) return; - struct vg_utcb *utcb = hurd_utcb (); + struct hurd_utcb *utcb = hurd_utcb (); assert (utcb); assert (message_buffer); @@ -173,7 +173,7 @@ hurd_activation_message_unregister (struct hurd_message_buffer *message_buffer) if (unlikely (! mm_init_done)) return; - struct vg_utcb *utcb = hurd_utcb (); + struct hurd_utcb *utcb = hurd_utcb (); assert (utcb); assert (message_buffer); assert (utcb->extant_message == message_buffer); @@ -218,7 +218,7 @@ activation_frame_slab_dealloc (void *hook, void *buffer, size_t size) } static void -check_activation_frame_reserve (struct vg_utcb *utcb) +check_activation_frame_reserve (struct hurd_utcb *utcb) { if (unlikely (! utcb->activation_stack || ! utcb->activation_stack->prev)) @@ -244,7 +244,7 @@ check_activation_frame_reserve (struct vg_utcb *utcb) } static struct activation_frame * -activation_frame_alloc (struct vg_utcb *utcb) +activation_frame_alloc (struct hurd_utcb *utcb) { struct activation_frame *activation_frame; @@ -272,7 +272,7 @@ activation_frame_alloc (struct vg_utcb *utcb) void hurd_activation_stack_dump (void) { - struct vg_utcb *utcb = hurd_utcb (); + struct hurd_utcb *utcb = hurd_utcb (); int depth = 0; struct activation_frame *activation_frame; @@ -300,7 +300,7 @@ hurd_activation_stack_dump (void) void hurd_activation_handler_normal (struct activation_frame *activation_frame, - struct vg_utcb *utcb) + struct hurd_utcb *utcb) { assert (utcb == hurd_utcb ()); assert (activation_frame->canary == ACTIVATION_FRAME_CANARY); @@ -451,7 +451,7 @@ hurd_activation_handler_normal (struct activation_frame *activation_frame, #ifndef NDEBUG static uintptr_t -crc (struct vg_utcb *utcb) +crc (struct hurd_utcb *utcb) { uintptr_t crc = 0; uintptr_t *p; @@ -463,15 +463,15 @@ crc (struct vg_utcb *utcb) #endif struct activation_frame * -hurd_activation_handler_activated (struct vg_utcb *utcb) +hurd_activation_handler_activated (struct hurd_utcb *utcb) { assert (((uintptr_t) utcb & (PAGESIZE - 1)) == 0); assert (utcb->canary0 == UTCB_CANARY0); assert (utcb->canary1 == UTCB_CANARY1); - assert (utcb->activated_mode); + assert (utcb->vg.activated_mode); /* XXX: Assumption that stack grows down... */ - assert (utcb->activation_handler_sp - PAGESIZE <= (uintptr_t) &utcb); - assert ((uintptr_t) &utcb <= utcb->activation_handler_sp); + assert (utcb->vg.activation_handler_sp - PAGESIZE <= (uintptr_t) &utcb); + assert ((uintptr_t) &utcb <= utcb->vg.activation_handler_sp); if (unlikely (! mm_init_done)) /* Just returns: during initialization, we don't except any faults or @@ -485,14 +485,14 @@ hurd_activation_handler_activated (struct vg_utcb *utcb) assertx (utcb == hurd_utcb (), "%p != %p (func: %p; ip: %p, sp: %p)", utcb, hurd_utcb (), hurd_utcb, - (void *) utcb->saved_ip, (void *) utcb->saved_sp); + (void *) utcb->vg.saved_ip, (void *) utcb->vg.saved_sp); debug (5, "Activation handler called (utcb: %p)", utcb); struct hurd_message_buffer *mb - = (struct hurd_message_buffer *) (uintptr_t) utcb->messenger_id; + = (struct hurd_message_buffer *) (uintptr_t) utcb->vg.messenger_id; - debug (5, "Got message %llx (utcb: %p)", utcb->messenger_id, utcb); + debug (5, "Got message %llx (utcb: %p)", utcb->vg.messenger_id, utcb); assert (mb->magic == HURD_MESSAGE_BUFFER_MAGIC); @@ -608,7 +608,7 @@ hurd_activation_handler_activated (struct vg_utcb *utcb) else { panic ("Unknown messenger %llx (extant: %p; exception: %p) (label: %d)", - utcb->messenger_id, + utcb->vg.messenger_id, utcb->extant_message, utcb->exception_buffer, vg_message_word (mb->reply, 0)); } @@ -643,9 +643,9 @@ static char activation_handler_area0[PAGESIZE] __attribute__ ((aligned (PAGESIZE))); static char activation_handler_msg[PAGESIZE] __attribute__ ((aligned (PAGESIZE))); -static struct vg_utcb *initial_utcb = (void *) &activation_handler_area0[0]; +static struct hurd_utcb *initial_utcb = (void *) &activation_handler_area0[0]; -static struct vg_utcb * +static struct hurd_utcb * simple_utcb_fetcher (void) { assert (initial_utcb->canary0 == UTCB_CANARY0); @@ -654,7 +654,7 @@ simple_utcb_fetcher (void) return initial_utcb; } -struct vg_utcb *(*hurd_utcb) (void); +struct hurd_utcb *(*hurd_utcb) (void); void hurd_activation_handler_init_early (void) @@ -664,21 +664,21 @@ hurd_activation_handler_init_early (void) hurd_utcb = simple_utcb_fetcher; - struct vg_utcb *utcb = hurd_utcb (); + struct hurd_utcb *utcb = hurd_utcb (); assert (utcb == initial_utcb); /* XXX: We assume the stack grows down! SP is set to the end of the exception page. */ - utcb->activation_handler_sp + utcb->vg.activation_handler_sp = (uintptr_t) activation_handler_area0 + sizeof (activation_handler_area0); /* The word beyond the base of the stack is interpreted as a pointer to the exception page. Make it so. */ - utcb->activation_handler_sp -= sizeof (void *); - * (void **) utcb->activation_handler_sp = utcb; + utcb->vg.activation_handler_sp -= sizeof (void *); + * (void **) utcb->vg.activation_handler_sp = utcb; - utcb->activation_handler_ip = (uintptr_t) &hurd_activation_handler_entry; - utcb->activation_handler_end = (uintptr_t) &hurd_activation_handler_end; + utcb->vg.activation_handler_ip = (uintptr_t) &hurd_activation_handler_entry; + utcb->vg.activation_handler_end = (uintptr_t) &hurd_activation_handler_end; struct hurd_thread_exregs_in in; memset (&in, 0, sizeof (in)); @@ -703,14 +703,14 @@ hurd_activation_handler_init_early (void) 0, 0, ADDR_VOID); if (err) panic ("Failed to send IPC: %d", err); - if (utcb->inline_words[0]) - panic ("Failed to install utcb page: %d", utcb->inline_words[0]); + if (utcb->vg.inline_words[0]) + panic ("Failed to install utcb page: %d", utcb->vg.inline_words[0]); } void hurd_activation_handler_init (void) { - struct vg_utcb *utcb; + struct hurd_utcb *utcb; error_t err = hurd_activation_state_alloc (__hurd_startup_data->thread, &utcb); if (err) @@ -730,7 +730,7 @@ hurd_activation_handler_init (void) #define ACTIVATION_AREA_SIZE (1 << ACTIVATION_AREA_SIZE_LOG2) error_t -hurd_activation_state_alloc (addr_t thread, struct vg_utcb **utcbp) +hurd_activation_state_alloc (addr_t thread, struct hurd_utcb **utcbp) { debug (5, DEBUG_BOLD ("allocating activation state for " ADDR_FMT), ADDR_PRINTF (thread)); @@ -780,7 +780,7 @@ hurd_activation_state_alloc (addr_t thread, struct vg_utcb **utcbp) int page = SKIP; /* Allocate the utcb. */ - struct vg_utcb *utcb = activation_area_base + page * PAGESIZE; + struct hurd_utcb *utcb = activation_area_base + page * PAGESIZE; alloc (utcb); page += 1 + SKIP; @@ -790,30 +790,31 @@ hurd_activation_state_alloc (addr_t thread, struct vg_utcb **utcbp) XXX: We assume the stack grows down! */ #ifndef NDEBUG /* Use a dedicated page. */ - utcb->activation_handler_sp + utcb->vg.activation_handler_sp = (uintptr_t) activation_area_base + page * PAGESIZE; - alloc ((void *) utcb->activation_handler_sp); + alloc ((void *) utcb->vg.activation_handler_sp); - utcb->activation_handler_sp += PAGESIZE; + utcb->vg.activation_handler_sp += PAGESIZE; page += 1 + SKIP; #else /* Use the end of the UTCB. */ - utcb->activation_handler_sp = utcb + PAGESIZE; + utcb->vg.activation_handler_sp = utcb + PAGESIZE; #endif /* At the top of the stack page, we use some space to remember the storage we allocate so that we can free it later. */ - utcb->activation_handler_sp + utcb->vg.activation_handler_sp -= sizeof (addr_t) * ACTIVATION_AREA_SIZE / PAGESIZE; - memset (utcb->activation_handler_sp, 0, + memset ((void *) utcb->vg.activation_handler_sp, 0, sizeof (addr_t) * ACTIVATION_AREA_SIZE / PAGESIZE); - memcpy (utcb->activation_handler_sp, pages, sizeof (addr_t) * page_count); - pages = (addr_t *) utcb->activation_handler_sp; + memcpy ((void *) utcb->vg.activation_handler_sp, pages, + sizeof (addr_t) * page_count); + pages = (addr_t *) utcb->vg.activation_handler_sp; /* The word beyond the base of the stack is a pointer to the exception page. */ - utcb->activation_handler_sp -= sizeof (void *); - * (void **) utcb->activation_handler_sp = utcb; + utcb->vg.activation_handler_sp -= sizeof (void *); + * (void **) utcb->vg.activation_handler_sp = utcb; /* And a medium-sized alternate stack. */ @@ -829,8 +830,8 @@ hurd_activation_state_alloc (addr_t thread, struct vg_utcb **utcbp) utcb->alternate_stack = a; - utcb->activation_handler_ip = (uintptr_t) &hurd_activation_handler_entry; - utcb->activation_handler_end = (uintptr_t) &hurd_activation_handler_end; + utcb->vg.activation_handler_ip = (uintptr_t) &hurd_activation_handler_entry; + utcb->vg.activation_handler_end = (uintptr_t) &hurd_activation_handler_end; utcb->exception_buffer = hurd_message_buffer_alloc_long (); utcb->extant_message = NULL; @@ -841,7 +842,7 @@ hurd_activation_state_alloc (addr_t thread, struct vg_utcb **utcbp) debug (5, "Activation area: %p-%p; utcb: %p; stack: %p; alt stack: %p", (void *) activation_area_base, (void *) activation_area_base + ACTIVATION_AREA_SIZE - 1, - utcb, (void *) utcb->activation_handler_sp, utcb->alternate_stack); + utcb, (void *) utcb->vg.activation_handler_sp, utcb->alternate_stack); /* Unblock the exception handler messenger. */ @@ -880,7 +881,7 @@ hurd_activation_state_alloc (addr_t thread, struct vg_utcb **utcbp) } void -hurd_activation_state_free (struct vg_utcb *utcb) +hurd_activation_state_free (struct hurd_utcb *utcb) { assert (utcb->canary0 == UTCB_CANARY0); assert (utcb->canary1 == UTCB_CANARY1); @@ -902,7 +903,7 @@ hurd_activation_state_free (struct vg_utcb *utcb) in. */ addr_t pages[ACTIVATION_AREA_SIZE / PAGESIZE]; memcpy (pages, - utcb->activation_handler_sp + sizeof (uintptr_t), + (void *) utcb->vg.activation_handler_sp + sizeof (uintptr_t), sizeof (addr_t) * ACTIVATION_AREA_SIZE / PAGESIZE); int i; diff --git a/libhurd-mm/ia32-exception-entry.S b/libhurd-mm/ia32-exception-entry.S index c7f0b8c..f4212bf 100644 --- a/libhurd-mm/ia32-exception-entry.S +++ b/libhurd-mm/ia32-exception-entry.S @@ -26,7 +26,7 @@ #define UTCB_MODE (0*4) #define UTCB_SAVED_IP (1*4) #define UTCB_SAVED_SP (2*4) -#define UTCB_ACTIVATION_FRAME_STACK (3*4) +#define UTCB_ACTIVATION_FRAME_STACK (512 + 0*4) /* The bits of the mode word. */ #define ACTIVATED_MODE_BIT 0 diff --git a/libhurd-mm/madvise.c b/libhurd-mm/madvise.c index 529c2be..853226d 100644 --- a/libhurd-mm/madvise.c +++ b/libhurd-mm/madvise.c @@ -19,7 +19,7 @@ . */ #include -#include +#include #include #include #include diff --git a/libhurd-mm/map.h b/libhurd-mm/map.h index 382a6e9..206b392 100644 --- a/libhurd-mm/map.h +++ b/libhurd-mm/map.h @@ -22,7 +22,7 @@ #define _HURD_MAP_H #include -#include +#include #include #include #include diff --git a/libhurd-mm/message-buffer.h b/libhurd-mm/message-buffer.h index 21e44b4..0c35b27 100644 --- a/libhurd-mm/message-buffer.h +++ b/libhurd-mm/message-buffer.h @@ -23,7 +23,7 @@ # include # include -# include +# include /* Forward. */ struct vg_message; diff --git a/libhurd-mm/mm-init.c b/libhurd-mm/mm-init.c index ea12898..caf362e 100644 --- a/libhurd-mm/mm-init.c +++ b/libhurd-mm/mm-init.c @@ -25,6 +25,7 @@ #include #include +#include #ifdef i386 #include @@ -87,7 +88,7 @@ mm_init (addr_t activity) assert (a == (void *) (fault_addr & ~(PAGESIZE - 1))); assert (count == 1); - struct vg_utcb *utcb = hurd_utcb (); + struct hurd_utcb *utcb = hurd_utcb (); struct activation_frame *activation_frame = utcb->activation_stack; debug (4, "Fault at %p (ip: %p, sp: %p, eax: %p, " "ebx: %p, ecx: %p, edx: %p, edi: %p, esi: %p, ebp: %p, " diff --git a/libhurd-mm/mm.h b/libhurd-mm/mm.h index 52b7ed8..8baace8 100644 --- a/libhurd-mm/mm.h +++ b/libhurd-mm/mm.h @@ -22,7 +22,7 @@ #ifndef HURD_MM_MM_H #define HURD_MM_MM_H -#include +#include /* Set to one by mm_init just before returning. */ extern int mm_init_done; diff --git a/libhurd-mm/mmap.c b/libhurd-mm/mmap.c index 3535ce2..bda87cf 100644 --- a/libhurd-mm/mmap.c +++ b/libhurd-mm/mmap.c @@ -20,7 +20,7 @@ #include -#include +#include #include #include #include diff --git a/libhurd-mm/mprotect.c b/libhurd-mm/mprotect.c index 10cf1de..e80d08c 100644 --- a/libhurd-mm/mprotect.c +++ b/libhurd-mm/mprotect.c @@ -19,7 +19,7 @@ . */ #include -#include +#include #include #include #include diff --git a/libhurd-mm/storage.c b/libhurd-mm/storage.c index 3f774e1..8079036 100644 --- a/libhurd-mm/storage.c +++ b/libhurd-mm/storage.c @@ -23,10 +23,10 @@ #include #include #include -#include -#include +#include +#include #include -#include +#include #include #include diff --git a/libhurd-mm/storage.h b/libhurd-mm/storage.h index 887f477..c7b4f66 100644 --- a/libhurd-mm/storage.h +++ b/libhurd-mm/storage.h @@ -22,8 +22,8 @@ #ifndef _HURD_STORAGE_H #define _HURD_STORAGE_H -#include -#include +#include +#include enum storage_expectancy { diff --git a/libpthread/ChangeLog b/libpthread/ChangeLog index cd6013f..65ba0d4 100644 --- a/libpthread/ChangeLog +++ b/libpthread/ChangeLog @@ -1,3 +1,10 @@ +2008-12-17 Neal H. Walfield + + * sysdeps/viengoos/bits/pthread-np.h (pthread_hurd_utcb_np): + Return a struct hurd_utcb *, not a struct vg_utcb *. + * sysdeps/viengoos/pt-sysdep.h (PTHREAD_SYSDEP_MEMBERS): Change + utcb's type to a struct hurd_utcb *. + 2008-12-11 Neal H. Walfield Update to new RPC interfaces, IPC semantics. diff --git a/libpthread/signal/sigwaiter.c b/libpthread/signal/sigwaiter.c index 8d041ac..adc05ca 100644 --- a/libpthread/signal/sigwaiter.c +++ b/libpthread/signal/sigwaiter.c @@ -20,7 +20,7 @@ #include "sig-internal.h" -#include +#include struct sigwaiter *sigwaiters; diff --git a/libpthread/sysdeps/viengoos/bits/pthread-np.h b/libpthread/sysdeps/viengoos/bits/pthread-np.h index aea3bab..9986a62 100644 --- a/libpthread/sysdeps/viengoos/bits/pthread-np.h +++ b/libpthread/sysdeps/viengoos/bits/pthread-np.h @@ -24,12 +24,12 @@ #ifndef _BITS_PTHREAD_NP_H #define _BITS_PTHREAD_NP_H 1 -#include -#include +#include +#include int pthread_setactivity_np (addr_t activity); /* Returns the caller's activation state block. */ -struct vg_utcb *pthread_hurd_utcb_np (void) __attribute__ ((pure)); +struct hurd_utcb *pthread_hurd_utcb_np (void) __attribute__ ((pure)); #endif /* bits/pthread-np.h */ diff --git a/libpthread/sysdeps/viengoos/ia32/pt-setup.c b/libpthread/sysdeps/viengoos/ia32/pt-setup.c index 88a60e8..bdd814a 100644 --- a/libpthread/sysdeps/viengoos/ia32/pt-setup.c +++ b/libpthread/sysdeps/viengoos/ia32/pt-setup.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include /* The stack layout used on the i386 is: diff --git a/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c b/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c index 8dd9be7..091815b 100644 --- a/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c +++ b/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include diff --git a/libpthread/sysdeps/viengoos/pt-block.c b/libpthread/sysdeps/viengoos/pt-block.c index 548cc3f..8e6a17f 100644 --- a/libpthread/sysdeps/viengoos/pt-block.c +++ b/libpthread/sysdeps/viengoos/pt-block.c @@ -20,7 +20,7 @@ #include #include -#include +#include /* Block THREAD. */ void diff --git a/libpthread/sysdeps/viengoos/pt-hurd-utcb-np.c b/libpthread/sysdeps/viengoos/pt-hurd-utcb-np.c index b3a76f4..ec08baf 100644 --- a/libpthread/sysdeps/viengoos/pt-hurd-utcb-np.c +++ b/libpthread/sysdeps/viengoos/pt-hurd-utcb-np.c @@ -19,7 +19,7 @@ #include -struct vg_utcb * +struct hurd_utcb * pthread_hurd_utcb_np (void) { struct __pthread *thread = _pthread_self (); diff --git a/libpthread/sysdeps/viengoos/pt-setactivity-np.c b/libpthread/sysdeps/viengoos/pt-setactivity-np.c index efcc9b7..db695b9 100644 --- a/libpthread/sysdeps/viengoos/pt-setactivity-np.c +++ b/libpthread/sysdeps/viengoos/pt-setactivity-np.c @@ -19,8 +19,8 @@ #include -#include -#include +#include +#include int pthread_setactivity_np (addr_t activity) diff --git a/libpthread/sysdeps/viengoos/pt-sysdep.h b/libpthread/sysdeps/viengoos/pt-sysdep.h index 0733640..15e0a03 100644 --- a/libpthread/sysdeps/viengoos/pt-sysdep.h +++ b/libpthread/sysdeps/viengoos/pt-sysdep.h @@ -36,7 +36,7 @@ #define PTHREAD_SYSDEP_MEMBERS \ addr_t object; \ vg_thread_id_t threadid; \ - struct vg_utcb *utcb; \ + struct hurd_utcb *utcb; \ struct hurd_message_buffer *lock_message_buffer; \ /* If the above fields are valid. */ \ bool have_kernel_resources; \ diff --git a/libpthread/sysdeps/viengoos/pt-thread-alloc.c b/libpthread/sysdeps/viengoos/pt-thread-alloc.c index 3cc02be..3c7df34 100644 --- a/libpthread/sysdeps/viengoos/pt-thread-alloc.c +++ b/libpthread/sysdeps/viengoos/pt-thread-alloc.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/libpthread/sysdeps/viengoos/pt-thread-dealloc.c b/libpthread/sysdeps/viengoos/pt-thread-dealloc.c index 9e174a9..f7d732b 100644 --- a/libpthread/sysdeps/viengoos/pt-thread-dealloc.c +++ b/libpthread/sysdeps/viengoos/pt-thread-dealloc.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include void diff --git a/libpthread/sysdeps/viengoos/pt-thread-halt.c b/libpthread/sysdeps/viengoos/pt-thread-halt.c index cfa861b..d721500 100644 --- a/libpthread/sysdeps/viengoos/pt-thread-halt.c +++ b/libpthread/sysdeps/viengoos/pt-thread-halt.c @@ -22,7 +22,7 @@ #include -#include +#include void __pthread_thread_halt (struct __pthread *thread) diff --git a/libpthread/sysdeps/viengoos/pt-thread-start.c b/libpthread/sysdeps/viengoos/pt-thread-start.c index f03f4c2..f4478ac 100644 --- a/libpthread/sysdeps/viengoos/pt-thread-start.c +++ b/libpthread/sysdeps/viengoos/pt-thread-start.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include diff --git a/libpthread/sysdeps/viengoos/pt-wakeup.c b/libpthread/sysdeps/viengoos/pt-wakeup.c index 60804ea..6435689 100644 --- a/libpthread/sysdeps/viengoos/pt-wakeup.c +++ b/libpthread/sysdeps/viengoos/pt-wakeup.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include /* Wakeup THREAD. */ diff --git a/libviengoos/ChangeLog b/libviengoos/ChangeLog new file mode 100644 index 0000000..1e3bbc5 --- /dev/null +++ b/libviengoos/ChangeLog @@ -0,0 +1,21 @@ +2008-12-17 Neal H. Walfield + + * Makefile.am: New file. + * headers.m4: Likewise. + * t-addr-trans.c: Move from ../hurd. + * t-addr.c: Likewise. + * t-rpc.c: Likewise. + * viengoos.h: Likewise. + * viengoos/activity.h: Likewise. + * viengoos/addr-trans.h: Likewise. + * viengoos/addr.h: Likewise. + * viengoos/cap.h: Likewise. + * viengoos/folio.h: Likewise. + * viengoos/futex.h: Likewise. + * viengoos/ipc.h: Likewise. + * viengoos/message.h: Likewise. + * viengoos/messenger.h: Likewise. + * viengoos/rpc.h: Likewise. + * viengoos/misc.h: Moved from ../viengoos/rm.h. + * viengoos/thread.h: New file split from ../hurd/thread.h. + diff --git a/libviengoos/Makefile.am b/libviengoos/Makefile.am new file mode 100644 index 0000000..6e7b1c4 --- /dev/null +++ b/libviengoos/Makefile.am @@ -0,0 +1,40 @@ +# Makefile.am - Makefile template for libviengoos. +# Copyright (C) 2008 Free Software Foundation, Inc. +# Written by Neal H. Walfield +# +# This file is part of the GNU Hurd. +# +# The GNU Hurd is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# The GNU Hurd is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +viengoos_headers = addr.h addr-trans.h cap.h \ + thread.h folio.h activity.h futex.h messenger.h \ + message.h ipc.h \ + rpc.h \ + misc.h + +nobase_include_HEADERS = viengoos.h \ + $(addprefix viengoos/, $(viengoos_headers)) + +TESTS = t-addr t-addr-trans t-rpc +check_PROGRAMS = $(TESTS) + +t_addr_CPPFLAGS = $(CHECK_CPPFLAGS) +t_addr_SOURCES = t-addr.c + +t_addr_trans_CPPFLAGS = $(CHECK_CPPFLAGS) +t_addr_trans_SOURCES = t-addr-trans.c + +t_rpc_CPPFLAGS = $(CHECK_CPPFLAGS) +t_rpc_SOURCES = t-rpc.c diff --git a/libviengoos/headers.m4 b/libviengoos/headers.m4 new file mode 100644 index 0000000..834985f --- /dev/null +++ b/libviengoos/headers.m4 @@ -0,0 +1,28 @@ +# headers.m4 - Autoconf snippets to install links for header files. +# Copyright 2008 Free Software Foundation, Inc. +# Written by Neal H. Walfield +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +AC_CONFIG_LINKS([ + sysroot/include/viengoos.h:libviengoos/viengoos.h + sysroot/include/viengoos/addr.h:libviengoos/viengoos/addr.h + sysroot/include/viengoos/addr-trans.h:libviengoos/viengoos/addr-trans.h + sysroot/include/viengoos/cap.h:libviengoos/viengoos/cap.h + sysroot/include/viengoos/thread.h:libviengoos/viengoos/thread.h + sysroot/include/viengoos/folio.h:libviengoos/viengoos/folio.h + sysroot/include/viengoos/activity.h:libviengoos/viengoos/activity.h + sysroot/include/viengoos/futex.h:libviengoos/viengoos/futex.h + sysroot/include/viengoos/messenger.h:libviengoos/viengoos/messenger.h + sysroot/include/viengoos/message.h:libviengoos/viengoos/message.h + sysroot/include/viengoos/ipc.h:libviengoos/viengoos/ipc.h + sysroot/include/viengoos/rpc.h:libviengoos/viengoos/rpc.h + sysroot/include/viengoos/misc.h:libviengoos/viengoos/misc.h +]) + diff --git a/libviengoos/t-addr-trans.c b/libviengoos/t-addr-trans.c new file mode 100644 index 0000000..c3607ad --- /dev/null +++ b/libviengoos/t-addr-trans.c @@ -0,0 +1,84 @@ +/* t-cap.c - Test the implementation of the various cap functions. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + . */ + +#include +#include +#include + +#include "stddef.h" +#include "addr-trans.h" + +int output_debug; +char *program_name = "t-addr-trans"; + +int +main (int argc, char *argv[]) +{ + printf ("Checking CAP_ADDR_TRANS_SET_GUARD_SUBPAGE... "); + + struct cap_addr_trans cap_addr_trans; + + bool r; + int subpage_bits; + for (subpage_bits = 0; subpage_bits < 16; subpage_bits ++) + { + int subpages = 1 << subpage_bits; + int subpage_size_log2 = 8 - subpage_bits; + int subpage_size = 1 << subpage_size_log2; + + memset (&cap_addr_trans, 0, sizeof (cap_addr_trans)); + + r = CAP_ADDR_TRANS_SET_SUBPAGE (&cap_addr_trans, 0, subpages); + assert (r == (subpage_bits <= 8)); + if (subpage_bits >= 8) + continue; + + assert (CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans) == subpages); + assert (CAP_ADDR_TRANS_SUBPAGE_SIZE (cap_addr_trans) == subpage_size); + assert (CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 (cap_addr_trans) + == subpage_size_log2); + + int gdepth; + for (gdepth = 0; gdepth < sizeof (uintptr_t) * 8; gdepth ++) + { + int guard_bits; + for (guard_bits = 0; guard_bits < sizeof (uintptr_t) * 8; guard_bits ++) + { + int guard = (1 << guard_bits) - 1; + r = CAP_ADDR_TRANS_SET_GUARD (&cap_addr_trans, guard, gdepth); + if (guard_bits <= gdepth + && (guard_bits + subpage_bits + <= CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS)) + { + assert (r); + assert (CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans) + == gdepth); + assert (CAP_ADDR_TRANS_GUARD (cap_addr_trans) == guard); + } + else + assert (! r); + } + } + } + + printf ("ok\n"); + + return 0; +} diff --git a/libviengoos/t-addr.c b/libviengoos/t-addr.c new file mode 100644 index 0000000..1c2494d --- /dev/null +++ b/libviengoos/t-addr.c @@ -0,0 +1,74 @@ +/* t-addr.c - Test the implementation of the various addr functions. + Copyright (C) 2007 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + . */ + +#include +#include +#include +#include +#include + +char *program_name = "t-addr"; +int output_debug = 0; + +int +main (int argc, char *argv[]) +{ + addr_t addr; + int i, j; + + printf ("Checking ADDR... "); + for (i = 0; i < ADDR_BITS; i ++) + { + addr = ADDR (1ULL << i, ADDR_BITS - i); + debug (1, "%llx/%d =? %llx/%d\n", + 1ULL << i, ADDR_BITS - i, + addr_prefix (addr), addr_depth (addr)); + assert (addr_depth (addr) == ADDR_BITS - i); + assert (addr_prefix (addr) == 1ull << i); + } + printf ("ok.\n"); + + printf ("Checking addr_extend... "); + addr = ADDR (0, 0); + for (i = 1; i < ADDR_BITS; i ++) + { + addr = addr_extend (addr, 1, 1); + assert (addr_depth (addr) == i); + assert (l4_msb64 (addr_prefix (addr)) == ADDR_BITS); + assert (l4_lsb64 (addr_prefix (addr)) == ADDR_BITS - i + 1); + } + printf ("ok.\n"); + + printf ("Checking addr_extract... "); + addr = ADDR (0, 0); + for (i = 0; i < ADDR_BITS; i ++) + { + addr = ADDR (((1ULL << i) - 1) << (ADDR_BITS - i), i); + + for (j = 0; j <= i; j ++) + { + l4_uint64_t idx = addr_extract (addr, j); + assert (idx == (1ULL << j) - 1); + } + } + printf ("ok.\n"); + + return 0; +} diff --git a/libviengoos/t-rpc.c b/libviengoos/t-rpc.c new file mode 100644 index 0000000..0f40fe9 --- /dev/null +++ b/libviengoos/t-rpc.c @@ -0,0 +1,185 @@ +#include +#include +#include + +char *program_name = "t-rpc"; +int output_debug = 1; + +#define RPC_STUB_PREFIX rpc +#define RPC_ID_PREFIX RPC + +#include + +/* Exception message ids. */ +enum + { + RPC_noargs = 0x1ABE100, + RPC_onein, + RPC_oneout, + RPC_onlyin, + RPC_onlyout, + RPC_mix, + RPC_caps, + }; + +struct foo +{ + int a; + char b; +}; + +RPC(noargs, 0, 0, 0) +RPC(onein, 1, 0, 0, uint32_t, arg) +RPC(oneout, 0, 1, 0, uint32_t, arg) +RPC(onlyin, 4, 0, 0, uint32_t, arg, uint32_t, idx, struct foo, foo, bool, p) +RPC(onlyout, 0, 4, 0, uint32_t, arg, uint32_t, idx, struct foo, foo, bool, p) +RPC(mix, 2, 3, 0, uint32_t, arg, uint32_t, idx, + struct foo, foo, bool, p, int, i) +RPC(caps, 3, 2, 2, + /* In: */ + int, i, cap_t, c, struct foo, foo, + /* Out: */ + int, a, int, b, cap_t, x, cap_t, y) + +#undef RPC_STUB_PREFIX +#undef RPC_ID_PREFIX + +int +main (int argc, char *argv[]) +{ + printf ("Checking RPC... "); + + error_t err; + struct vg_message *msg; + + +#define REPLY ADDR (0x1000, ADDR_BITS - 12) + addr_t reply = REPLY; + + msg = malloc (sizeof (*msg)); + rpc_noargs_send_marshal (msg, REPLY); + err = rpc_noargs_send_unmarshal (msg, &reply); + assert (! err); + assert (ADDR_EQ (reply, REPLY)); + free (msg); + + msg = malloc (sizeof (*msg)); + rpc_noargs_reply_marshal (msg); + err = rpc_noargs_reply_unmarshal (msg); + assert (err == 0); + free (msg); + + + msg = malloc (sizeof (*msg)); +#define VALUE 0xfde8963a + uint32_t arg = VALUE; + uint32_t arg_out; + + rpc_onein_send_marshal (msg, arg, REPLY); + err = rpc_onein_send_unmarshal (msg, &arg_out, &reply); + assert (! err); + assert (arg_out == VALUE); + assert (ADDR_EQ (reply, REPLY)); + free (msg); + + msg = malloc (sizeof (*msg)); + rpc_onein_reply_marshal (msg); + err = rpc_onein_reply_unmarshal (msg); + assert (! err); + free (msg); + + msg = malloc (sizeof (*msg)); + rpc_oneout_send_marshal (msg, REPLY); + err = rpc_oneout_send_unmarshal (msg, &reply); + assert (! err); + assert (ADDR_EQ (reply, REPLY)); + free (msg); + + msg = malloc (sizeof (*msg)); + rpc_oneout_reply_marshal (msg, arg); + err = rpc_oneout_reply_unmarshal (msg, &arg_out); + assert (! err); + assert (arg_out == VALUE); + free (msg); + + msg = malloc (sizeof (*msg)); + + struct foo foo; + foo.a = 1 << 31; + foo.b = 'l'; + uint32_t idx_out; + struct foo foo_out; + bool p_out; + + rpc_onlyin_send_marshal (msg, 0x1234567, 0xABC, foo, true, REPLY); + err = rpc_onlyin_send_unmarshal (msg, &arg_out, &idx_out, &foo_out, &p_out, + &reply); + assert (! err); + assert (arg_out == 0x1234567); + assert (idx_out == 0xABC); + assert (foo_out.a == foo.a); + assert (foo_out.b == foo.b); + assert (p_out == true); + assert (ADDR_EQ (reply, REPLY)); + free (msg); + + msg = malloc (sizeof (*msg)); + rpc_onlyin_reply_marshal (msg); + err = rpc_onlyin_reply_unmarshal (msg); + assert (! err); + free (msg); + + msg = malloc (sizeof (*msg)); + rpc_onlyout_send_marshal (msg, REPLY); + err = rpc_onlyout_send_unmarshal (msg, &reply); + assert (! err); + assert (ADDR_EQ (reply, REPLY)); + free (msg); + + msg = malloc (sizeof (*msg)); + rpc_onlyout_reply_marshal (msg, 0x1234567, 321, foo, true); + err = rpc_onlyout_reply_unmarshal (msg, &arg_out, &idx_out, + &foo_out, &p_out); + assert (! err); + assert (arg_out == 0x1234567); + assert (idx_out == 321); + assert (foo_out.a == foo.a); + assert (foo_out.b == foo.b); + assert (p_out == true); + free (msg); + + + msg = malloc (sizeof (*msg)); + rpc_mix_send_marshal (msg, arg, 456789, REPLY); + err = rpc_mix_send_unmarshal (msg, &arg_out, &idx_out, &reply); + assert (! err); + assert (arg_out == arg); + assert (idx_out == 456789); + assert (ADDR_EQ (reply, REPLY)); + free (msg); + + msg = malloc (sizeof (*msg)); + int i_out = 0; + rpc_mix_reply_marshal (msg, foo, false, 4200042); + err = rpc_mix_reply_unmarshal (msg, &foo_out, &p_out, &i_out); + assert (! err); + assert (foo_out.a == foo.a); + assert (foo_out.b == foo.b); + assert (p_out == false); + assert (i_out == 4200042); + free (msg); + + msg = malloc (sizeof (*msg)); + rpc_caps_send_marshal (msg, 54, ADDR (1, ADDR_BITS), foo, REPLY); + addr_t addr; + err = rpc_caps_send_unmarshal (msg, &i_out, &addr, &foo_out, &reply); + assert (! err); + assert (i_out == 54); + assert (ADDR_EQ (addr, ADDR (1, ADDR_BITS))); + assert (foo_out.a == foo.a); + assert (foo_out.b == foo.b); + free (msg); + + printf ("ok\n"); + return 0; +} diff --git a/libviengoos/viengoos.h b/libviengoos/viengoos.h new file mode 100644 index 0000000..bc734ad --- /dev/null +++ b/libviengoos/viengoos.h @@ -0,0 +1 @@ +#include diff --git a/libviengoos/viengoos/activity.h b/libviengoos/viengoos/activity.h new file mode 100644 index 0000000..a180527 --- /dev/null +++ b/libviengoos/viengoos/activity.h @@ -0,0 +1,254 @@ +/* activity.h - Activity definitions. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GNU Hurd. If not, see + . */ + +#ifndef _VIENGOOS_ACTIVITY_H +#define _VIENGOOS_ACTIVITY_H 1 + +#include + +enum + { + RM_activity_policy = 700, + RM_activity_info, + }; + +struct activity_memory_policy +{ + uint16_t priority; + uint16_t weight; +}; + +#define ACTIVITY_MEMORY_POLICY(__amp_priority, __amp_weight) \ + (struct activity_memory_policy) { __amp_priority, __amp_weight } +#define ACTIVITY_MEMORY_POLICY_VOID ACTIVITY_MEMORY_POLICY(0, 0) + +struct activity_policy +{ + /* This policy is typically set by the parent to reflect how + available memory should be distributed among its immediate + children. It may only be set via an activity control + capability. */ + struct activity_memory_policy sibling_rel; + + /* This policy is typically set by the activity user and controls + how the memory allocated *directly* to this activity is managed + relative to the memory allocated to this activity's children. + That is, if the activity has been choosen as a victim, this + provides a policy to determine whether the memory allocated + directly to the activity or that to a child activity should be + evicted. */ + struct activity_memory_policy child_rel; + + /* Number of folios. Zero means no limit. (This does not mean that + there is no limit, just that this activity does not impose a + limit. The parent activity, for instance, may impose a limit.) + May only be set via an activity control capability. */ + uint32_t folios; +}; + +/* Activity statistics. These are approximate and in some cases + represent averages. */ +#define ACTIVITY_STATS_PERIODS 2 +struct activity_stats +{ + /* The period during which this statistic was generated. */ + uint32_t period; + + /* The maximum number of frames this activity could currently + allocate assuming other allocations do not otherwise change. + This implies stealing from others. */ + uint32_t available; + uint32_t available_local; + + /* Log2 the maximum amount of memory (in pages) that the user of + this activity ought to allocate in the next few seconds. If + negative, the amount of memory the activity ought to consider + freeing. */ + int8_t damping_factor; + + /* If pressure is non-zero, then this activity is causing PRESSURE. + + PRESSURE is calculated as follows: if + + 1) this activity is within its entitlement + 2) its working set is significantly smaller than its allocation + (as determined by the size of inactive relative to active), and + 3) other activities are being held back (i.e., paging) due to this + activity, + + then this represents the amount of memory it would be nice to see + this activity free. This activity will not be penalized by the + system if it does not yield memory. However, if the activity has + memory which is yielding a low return, it would be friendly of it + to return it. */ + uint8_t pressure; + uint8_t pressure_local; + + /* The number of clean and dirty frames that are accounted to this + activity. (Does not include frames scheduled for eviction.) The + total number of frames accounted to this activity is thus CLEAN + + DIRTY. */ + uint32_t clean; + uint32_t dirty; + /* Number of frames pending eviction. */ + uint32_t pending_eviction; + + + /* Based on recency information, the number of active frames + accounted to this activity and its children. The number of + inactive frames is approximately CLEAN + DIRTY - ACTIVE. */ + uint32_t active; + /* Likewise, but excluding its children. */ + uint32_t active_local; + + /* Number of frames that were active in the last period that become + inactive in this period. */ + uint32_t became_active; + /* Number of frames that were inactive in the last period that + become active in this period. */ + uint32_t became_inactive; + + + /* Number of frames that were not accounted to this activity in the + last period and are now accounted to it. */ + uint32_t claimed; + /* Number of frames that were accounted to this activity in the last + period and are no longer accounted to it. */ + uint32_t disowned; + + /* The number of frames that this activity referenced but which are + accounted to some other activity. */ + uint32_t freeloading; + /* The sum of the references by other processes to the frames that + are accounted to this activity. (A single frame may account + for multiple references.) */ + uint32_t freeloaded; + + + /* Number of frames that were accounted to this activity and + scheduled for eviction. */ + uint32_t evicted; + /* Number of frames that were accounted to this activity (not its + children), had the discarded bit set, and were discarded. */ + uint32_t discarded; + /* Number of frames paged-in on behalf of this activity. This does + not include pages marked empty that do not require disk + activity. */ + uint32_t pagedin; + /* Number of frames that were referenced before being completely + freed. (If evicted is significant and saved approximates + evicted, then the process is trashing.) */ + uint32_t saved; +}; + +#define ACTIVITY_POLICY(__ap_sibling_rel, __ap_child_rel, __ap_storage) \ + (struct activity_policy) { __ap_sibling_rel, __ap_child_rel, __ap_storage } +#define ACTIVITY_POLICY_VOID \ + ACTIVITY_POLICY(ACTIVITY_MEMORY_POLICY_VOID, \ + ACTIVITY_MEMORY_POLICY_VOID, \ + 0) + +#define RPC_STUB_PREFIX rm +#define RPC_ID_PREFIX RM + +#include + +enum +{ + ACTIVITY_POLICY_CHILD_REL_PRIORITY_SET = 1 << 0, + ACTIVITY_POLICY_CHILD_REL_WEIGHT_SET = 1 << 1, + ACTIVITY_POLICY_SIBLING_REL_PRIORITY_SET = 1 << 2, + ACTIVITY_POLICY_SIBLING_REL_WEIGHT_SET = 1 << 3, + ACTIVITY_POLICY_STORAGE_SET = 1 << 4, + + ACTIVITY_POLICY_CHILD_REL_SET = (ACTIVITY_POLICY_CHILD_REL_PRIORITY_SET + | ACTIVITY_POLICY_CHILD_REL_WEIGHT_SET), + + ACTIVITY_POLICY_SIBLING_REL_SET = (ACTIVITY_POLICY_SIBLING_REL_PRIORITY_SET + | ACTIVITY_POLICY_SIBLING_REL_WEIGHT_SET), +}; + +/* Get ACTIVITY's policy and set according to FLAGS and IN. */ +RPC (activity_policy, 2, 1, 0, + /* cap_t principal, cap_t activity */ + uintptr_t, flags, struct activity_policy, in, + /* Out: */ + struct activity_policy, out); + +enum + { + /* Return statistics. */ + activity_info_stats = 1 << 0, + /* Asynchronous change in availability. */ + activity_info_pressure = 1 << 1, + }; + +struct activity_info +{ + /* The returned event. */ + uintptr_t event; + union + { + /* If EVENT is activity_info_stats. */ + struct + { + /* The number of samples. */ + int count; + /* Samples are ordered by recency with the youngest towards the + start of the buffer. */ + struct activity_stats stats[ACTIVITY_STATS_PERIODS]; + } stats; + + /* If EVENT is activity_info_free. */ + struct + { + /* The number of pages the caller should try to free (negative) + or may allocate (positive). */ + int amount; + } pressure; + }; +}; + +/* Return some information about the activity ACTIVITY. FLAGS is a + bit-wise or of events the caller is interested. Only one event + will be returned. + + If FLAGS contains activity_info_stats, may return the next + statistic that comes at or after UNTIL_PERIOD. (This can be used + to register a callback that is sent when the statistics are next + available. For example, call with UNTIL_PERIOD equal to 0 to get + the current statistics and then examine the period field. Use this + as the base for the next call.) + + If FLAGS contains activity_info_free, may return an upcall + indicating that the activity must free some memory or will be such + subject to paging. In this case, the activity should try to free + at least the indicated number of pages as quickly as possible. */ +RPC (activity_info, 2, 1, 0, + /* cap_t principal, cap_t activity, */ + uintptr_t, flags, uintptr_t, until_period, + /* Out: */ + struct activity_info, info) + +#undef RPC_STUB_PREFIX +#undef RPC_ID_PREFIX +#undef RPC_TARGET + +#endif diff --git a/libviengoos/viengoos/addr-trans.h b/libviengoos/viengoos/addr-trans.h new file mode 100644 index 0000000..de49ce7 --- /dev/null +++ b/libviengoos/viengoos/addr-trans.h @@ -0,0 +1,190 @@ +/* addr-trans.h - Address translation functions. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GNU Hurd. If not, see + . */ + +#ifndef _VIENGOOS_ADDR_TRANS_H +#define _VIENGOOS_ADDR_TRANS_H + +#include +#include +#include + +/* Capabilities have two primary functions: they designate objects and + they participate in address translation. This structure controls + how the page table walker translates bits when passing through this + capability. */ + +#define CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS 22 +#define CAP_ADDR_TRANS_SUBPAGES_BITS 4 +#define CAP_ADDR_TRANS_GDEPTH_BITS 6 + +struct cap_addr_trans +{ + union + { + struct + { + /* The value of the guard and the subpage to use. + + A capability page is partitioned into 2^SUBPAGES_LOG2 subpages. + This value determines the number of subpage index bits and + maximum number of guard bits. The number of subpage index bits + is SUBPAGES_LOG2 and the number of guard bits is the remainder + (the guard lies in the upper bits; the subpage in the lower). + + If SUBPAGES_LOG2 is 0, there is a single subpage (covering the + entire page). This implies that there are no subpage bits (the + only valid offset is 0) and 21 possible guard bits. If + SUBPAGES_LOG2 is 0, there are 256 subpages, 8 subpage bits and a + maximum of 21-8=15 guard bits. */ + uint32_t guard_subpage: CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS; + /* The log2 of the subpages. The size of a subpage is thus 2^(8 - + SUBPAGES_LOG2). Values of SUBPAGES_LOG2 other than 0 are only + allowed for cap pages. */ + uint32_t subpages_log2: CAP_ADDR_TRANS_SUBPAGES_BITS; + /* Number of significant guard bits. The value of the GUARD is zero + extended if GDEPTH is greater than the number of available guard + bits. */ + uint32_t gdepth: CAP_ADDR_TRANS_GDEPTH_BITS; + }; + uint32_t raw; + }; +}; + +#define CAP_ADDR_TRANS_INIT { { .raw = 0 } } +#define CAP_ADDR_TRANS_VOID (struct cap_addr_trans) { { .raw = 0 } } + +/* The log2 number of subpages. */ +#define CAP_ADDR_TRANS_SUBPAGES_LOG2(cap_addr_trans_) \ + ((cap_addr_trans_).subpages_log2) + +/* The number of subpages. */ +#define CAP_ADDR_TRANS_SUBPAGES(cap_addr_trans_) \ + (1 << CAP_ADDR_TRANS_SUBPAGES_LOG2((cap_addr_trans_))) + +/* The designated subpage. */ +#define CAP_ADDR_TRANS_SUBPAGE(cap_addr_trans_) \ + ((cap_addr_trans_).guard_subpage \ + & (CAP_ADDR_TRANS_SUBPAGES ((cap_addr_trans_)) - 1)) + +/* The log2 of the size of the named subpage (in capability + units). */ +#define CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2(cap_addr_trans_) \ + (8 - (cap_addr_trans_).subpages_log2) + +/* The number of caps addressed by this capability. */ +#define CAP_ADDR_TRANS_SUBPAGE_SIZE(cap_addr_trans_) \ + (1 << CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 ((cap_addr_trans_))) + +/* The offset in capability units (with respect to the start of the + capability page) of the first capability in the designated + sub-page. */ +#define CAP_ADDR_TRANS_SUBPAGE_OFFSET(cap_addr_trans_) \ + (CAP_ADDR_TRANS_SUBPAGE ((cap_addr_trans_)) \ + * CAP_ADDR_TRANS_SUBPAGE_SIZE ((cap_addr_trans_))) + +/* The number of guard bits. */ +#define CAP_ADDR_TRANS_GUARD_BITS(cap_addr_trans_) ((cap_addr_trans_).gdepth) + +/* The value of the guard. */ +#define CAP_ADDR_TRANS_GUARD(cap_addr_trans_) \ + ((uint64_t) ((cap_addr_trans_).guard_subpage \ + >> (cap_addr_trans_).subpages_log2)) + +#define CATSGST_(test_, format, args...) \ + if (! (test_)) \ + { \ + r_ = false; \ + debug (1, format, ##args); \ + } + +/* Set CAP_ADDR_TRANS_P_'s guard and the subpage. Returns true on success + (parameters valid), false otherwise. */ +#define CAP_ADDR_TRANS_SET_GUARD_SUBPAGE(cap_addr_trans_p_, guard_, gdepth_, \ + subpage_, subpages_) \ + ({ bool r_ = true; \ + /* There must be at least 1 subpage. */ \ + CATSGST_ (((subpages_) > 0), \ + "subpages_ (%d) must be at least 1\n", (subpages_)); \ + CATSGST_ (((subpages_) & ((subpages_) - 1)) == 0, \ + "SUBPAGES_ (%d) must be a power of 2\n", (subpages_)); \ + int subpages_log2_ = vg_msb ((subpages_)) - 1; \ + CATSGST_ (subpages_log2_ <= 8, \ + "maximum subpages is 256 (%d)\n", (subpages_)); \ + CATSGST_ (0 <= (subpage_) && (subpage_) < (subpages_), \ + "subpage (%d) must be between 0 and SUBPAGES_ (%d) - 1\n", \ + (subpage_), (subpages_)); \ + \ + /* The number of required guard bits. */ \ + int gbits_ = vg_msb64 ((guard_)); \ + CATSGST_ (gbits_ <= (gdepth_), \ + "Significant guard bits (%d) must be less than depth (%d)\n", \ + gbits_, (gdepth_)); \ + CATSGST_ (gbits_ + subpages_log2_ <= CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS, \ + "Significant guard bits (%d) plus subpage bits (%d) > %d\n", \ + gbits_, subpages_log2_, CAP_ADDR_TRANS_GUARD_SUBPAGE_BITS); \ + \ + if (r_) \ + { \ + (cap_addr_trans_p_)->subpages_log2 = subpages_log2_; \ + (cap_addr_trans_p_)->gdepth = (gdepth_); \ + (cap_addr_trans_p_)->guard_subpage \ + = ((guard_) << subpages_log2_) | (subpage_); \ + } \ + r_; \ + }) + +/* Set *CAP_ADDR_TRANS_P_'s guard. Returns true on success (parameters + valid), false otherwise. */ +#define CAP_ADDR_TRANS_SET_GUARD(cap_addr_trans_p_, guard_, gdepth_) \ + ({ int subpage_ = CAP_ADDR_TRANS_SUBPAGE (*(cap_addr_trans_p_)); \ + int subpages_ = CAP_ADDR_TRANS_SUBPAGES (*(cap_addr_trans_p_)); \ + CAP_ADDR_TRANS_SET_GUARD_SUBPAGE ((cap_addr_trans_p_), \ + (guard_), (gdepth_), \ + (subpage_), (subpages_)); \ + }) + +/* Set *CAP_ADDR_TRANS_P_'s subpage. Returns true on success (parameters + valid), false otherwise. */ +#define CAP_ADDR_TRANS_SET_SUBPAGE(cap_addr_trans_p_, subpage_, subpages_) \ + ({ int gdepth_ = CAP_ADDR_TRANS_GUARD_BITS (*(cap_addr_trans_p_)); \ + int guard_ = CAP_ADDR_TRANS_GUARD (*(cap_addr_trans_p_)); \ + CAP_ADDR_TRANS_SET_GUARD_SUBPAGE ((cap_addr_trans_p_), \ + (guard_), (gdepth_), \ + (subpage_), (subpages_)); \ + }) + +/* Returns whether the capability address CAP_ADDR_TRANS is well-formed. */ +#define CAP_ADDR_TRANS_VALID(cap_addr_trans) \ + ({ bool r_ = true; \ + CATSGST_ (CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans) <= WORDSIZE, \ + "Invalid guard depth (%d)", \ + CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans)); \ + CATSGST_ (CAP_ADDR_TRANS_SUBPAGES_LOG2 (cap_addr_trans) <= 8, \ + "Invalid number of subpages (%d)", \ + CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans)); \ + CATSGST_ (vg_msb (CAP_ADDR_TRANS_GUARD (cap_addr_trans)) \ + <= CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans), \ + "Significant guard bits (%d) exceeds guard depth (%d)", \ + vg_msb (CAP_ADDR_TRANS_GUARD (cap_addr_trans)), \ + CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans)); \ + r_; \ + }) + +#endif diff --git a/libviengoos/viengoos/addr.h b/libviengoos/viengoos/addr.h new file mode 100644 index 0000000..badfcd9 --- /dev/null +++ b/libviengoos/viengoos/addr.h @@ -0,0 +1,179 @@ +/* addr.h - Address definitions. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _VIENGOOS_ADDR_H +#define _VIENGOOS_ADDR_H 1 + +#include +#include +#include + +#include + +/* Addresses are 64-bits wide and translate up to 63 bits. They are + composed of a depth and a prefix that is depth bits wide. + + The 64-bit field is packed as follows: the upper bits are encoded + in binary and represent the prefix, these are followed by a single + bit that is on, which is followed by a number encoded in unary. + The value of the unary number is 63 - depth. This allows easy + calculation of the depth and extraction of the prefix. Thus, + given: + + xxxxx100 + + The unary value is 2 yielding a depth of 63 - 2 = 61. These bits + are encoded in the upper DEPTH bits of the field. + + Leaves thus have a 1 in the least significant bit and nodes a + 0. */ +struct addr +{ + uint64_t raw; +}; +#define ADDR_BITS 63 +/* Client-side capability handle. */ +typedef struct addr addr_t; + +#define ADDR_FMT "%llx/%d" +#define ADDR_PRINTF(addr_) addr_prefix ((addr_)), addr_depth ((addr_)) + +/* Create an address given a prefix and a depth. */ +#define ADDR(prefix_, depth_) \ + ({ \ + uint64_t p_ = (prefix_); \ + uint64_t d_ = (depth_); \ + assert (0 <= d_ && d_ <= ADDR_BITS); \ + assert ((p_ & ((1 << (ADDR_BITS - d_)) - 1)) == 0); \ + assert (p_ < (1ULL << ADDR_BITS)); \ + (struct addr) { (p_ << 1ULL) | (1ULL << (ADDR_BITS - d_)) }; \ + }) + +/* Create an address given a prefix and a depth. Appropriate for use + as an initializer. */ +#define ADDR_INIT(prefix_, depth_) \ + { .raw = ((((prefix_) << 1) | 1) << (ADDR_BITS - (depth_))) } + +#define ADDR_VOID ((struct addr) { 0ULL }) +#define ADDR_EQ(a, b) (a.raw == b.raw) +#define ADDR_IS_VOID(a) (ADDR_EQ (a, ADDR_VOID)) + +/* Return ADDR_'s depth. */ +static inline int +addr_depth (addr_t addr) +{ + return ADDR_BITS - (vg_lsb64 (addr.raw) - 1); +} + +/* Return ADDR's prefix. */ +static inline uint64_t +addr_prefix (addr_t addr) +{ + /* (Clear the boundary bit and shift right 1.) */ + return (addr.raw & ~(1ULL << (ADDR_BITS - addr_depth (addr)))) >> 1; +} + +/* Extend the address ADDR by concatenating the lowest DEPTH bits of + PREFIX. */ +#if 0 +static inline addr_t +addr_extend (addr_t addr, uint64_t prefix, int depth) +{ + assertx (depth >= 0, "depth: %d", depth); + assertx (addr_depth (addr) + depth <= ADDR_BITS, + "addr: " ADDR_FMT "; depth: %d", ADDR_PRINTF (addr), depth); + assertx (prefix < (1ULL << depth), + "prefix: %llx; depth: %lld", prefix, 1ULL << depth); + return ADDR (addr_prefix (addr) + | (prefix << (ADDR_BITS - addr_depth (addr) - depth)), + addr_depth (addr) + depth); +} +#else +#define addr_extend(addr_, prefix_, depth_) \ + ({ \ + addr_t a__ = (addr_); \ + uint64_t p__ = (prefix_); \ + int d__ = (depth_); \ + assertx (d__ >= 0, "depth: %d", d__); \ + assertx (addr_depth ((a__)) + (d__) <= ADDR_BITS, \ + "addr: " ADDR_FMT "; depth: %d", ADDR_PRINTF (a__), d__); \ + assertx (p__ < (1ULL << d__), \ + "prefix: %llx; depth: %lld", p__, 1ULL << d__); \ + ADDR (addr_prefix ((a__)) \ + | ((p__) << (ADDR_BITS - addr_depth ((a__)) - (d__))), \ + addr_depth ((a__)) + (d__)); \ + }) +#endif + +/* Decrease the depth of ADDR by DEPTH. */ +static inline addr_t +addr_chop (addr_t addr, int depth) +{ + int d = addr_depth (addr) - depth; + assert (d >= 0); + + return ADDR (addr_prefix (addr) & ~((1ULL << (ADDR_BITS - d)) - 1), d); +} + +/* Return the last WIDTH bits of address's ADDR prefix. */ +static inline uint64_t +addr_extract (addr_t addr, int width) +{ + assert (width <= addr_depth (addr)); + + return (addr_prefix (addr) >> (ADDR_BITS - addr_depth (addr))) + & ((1ULL << width) - 1); +} + +/* Convert an address to a pointer. The address must name an object + mapped in the machine data instruction accessible part of the + address space. */ +#define ADDR_TO_PTR(addr_) \ + ({ \ + assert (addr_prefix ((addr_)) < ((uintptr_t) -1)); \ + assert (addr_depth ((addr_)) == ADDR_BITS); \ + (void *) (uintptr_t) addr_prefix ((addr_)); \ + }) + +/* Convert a pointer to an address. */ +#define PTR_TO_ADDR(ptr_) \ + (ADDR ((uintptr_t) (ptr_), ADDR_BITS)) + +/* Return the address of the page that would contain pointer PTR_. */ +#define PTR_TO_PAGE(ptr_) \ + addr_chop (ADDR ((uintptr_t) (ptr_), ADDR_BITS), PAGESIZE_LOG2) + +static inline addr_t +addr_add (addr_t addr, uint64_t count) +{ + int w = ADDR_BITS - addr_depth (addr); + + return ADDR (addr_prefix (addr) + (count << w), + addr_depth (addr)); +} + +static inline addr_t +addr_sub (addr_t addr, uint64_t count) +{ + return addr_add (addr, - count); +} + +#endif diff --git a/libviengoos/viengoos/cap.h b/libviengoos/viengoos/cap.h new file mode 100644 index 0000000..c15d66f --- /dev/null +++ b/libviengoos/viengoos/cap.h @@ -0,0 +1,730 @@ +/* cap.h - Capability definitions. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GNU Hurd. If not, see + . */ + +#ifndef _VIENGOOS_CAP_H +#define _VIENGOOS_CAP_H 1 + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Capabilities. + + Capabilities have three functions: a capability can designate an + object, it can participate in address translation, and it can be + used to control how the designated object should be managed. */ + +/* The types of objects designated by capabilities. */ +enum cap_type + { +#define CAP_TYPE_MIN cap_void + cap_void, + cap_page, + cap_rpage, + cap_cappage, + cap_rcappage, + cap_folio, + cap_activity, + cap_activity_control, + cap_thread, + cap_messenger, + cap_rmessenger, + cap_type_count, +#define CAP_TYPE_MAX (cap_type_count - 1) + }; + +static inline const char * +cap_type_string (enum cap_type type) +{ + switch (type) + { + case cap_void: + return "void"; + case cap_page: + return "page"; + case cap_rpage: + return "rpage"; + case cap_cappage: + return "cappage"; + case cap_rcappage: + return "rcappage"; + case cap_folio: + return "folio"; + case cap_activity: + return "activity"; + case cap_activity_control: + return "activity_control"; + case cap_thread: + return "thread"; + case cap_messenger: + return "messenger"; + case cap_rmessenger: + return "rmessenger"; + default: + return "unknown cap type"; + }; +} + +/* Return whether two types are compatible in the sense that two caps + with the given types can designate the same object. */ +static inline bool +cap_types_compatible (enum cap_type a, enum cap_type b) +{ + if (a == b) + return true; + + if (a == cap_page && b == cap_rpage) + return true; + if (a == cap_rpage && b == cap_page) + return true; + + if (a == cap_cappage && b == cap_rcappage) + return true; + if (a == cap_rcappage && b == cap_cappage) + return true; + + if (a == cap_activity && b == cap_activity_control) + return true; + if (a == cap_activity_control && b == cap_activity) + return true; + + if (a == cap_messenger && b == cap_rmessenger) + return true; + if (a == cap_rmessenger && b == cap_messenger) + return true; + + return false; +} + +/* Returns weather TYPE corresponds to a weak type. */ +static inline bool +cap_type_weak_p (enum cap_type type) +{ + switch (type) + { + case cap_rpage: + case cap_rcappage: + case cap_activity: + case cap_rmessenger: + return true; + + default: + return false; + } +} + +/* Returns the weakened type corresponding to TYPE. If type is + already a weak type, returns TYPE. */ +static inline enum cap_type +cap_type_weaken (enum cap_type type) +{ + switch (type) + { + case cap_page: + case cap_rpage: + return cap_rpage; + + case cap_cappage: + case cap_rcappage: + return cap_rcappage; + + case cap_activity_control: + case cap_activity: + return cap_activity; + + case cap_messenger: + case cap_rmessenger: + return cap_rmessenger; + + default: + return cap_void; + } +} + +/* Returns the strong type corresponding to TYPE. If type is already + a strong type, returns TYPE. */ +static inline enum cap_type +cap_type_strengthen (enum cap_type type) +{ + switch (type) + { + case cap_page: + case cap_rpage: + return cap_page; + + case cap_cappage: + case cap_rcappage: + return cap_cappage; + + case cap_activity_control: + case cap_activity: + return cap_activity_control; + + case cap_messenger: + case cap_rmessenger: + return cap_messenger; + + default: + return type; + } +} + +/* Object policy. */ + +/* The object priority is a signed 7-bit number (-64 -> 63). A lower + numeric value corresponds to a lower priority. */ +#define OBJECT_PRIORITY_BITS 7 +#define OBJECT_PRIORITY_LEVELS (1 << OBJECT_PRIORITY_BITS) +#define OBJECT_PRIORITY_MIN (-(1 << (OBJECT_PRIORITY_BITS - 1))) +#define OBJECT_PRIORITY_DEFAULT (0) +#define OBJECT_PRIORITY_MAX ((1 << (OBJECT_PRIORITY_BITS - 1)) - 1) + +struct object_policy +{ + union + { + struct + { + /* Whether a page is discardable (if so and the page is not + zero, trying to read the page from disk generates a first + fault fault). */ + int8_t discardable : 1; + + /* An object's priority. If can be used to override LRU + eviction. When a memory object is to be evicted, we select + the object with the lowest priority (higher value = lower + priority). */ + int8_t priority : OBJECT_PRIORITY_BITS; + }; + uint8_t raw; + }; +}; + +#define OBJECT_POLICY_INIT { { raw: 0 } } +#define OBJECT_POLICY(__op_discardable, __op_priority) \ + (struct object_policy) { { { (__op_discardable), (__op_priority) } } } +/* The default object policy: not discardable, managed by LRU. */ +#define OBJECT_POLICY_VOID \ + OBJECT_POLICY (false, OBJECT_PRIORITY_DEFAULT) +/* Synonym for OBJECT_POLICY_VOID. */ +#define OBJECT_POLICY_DEFAULT OBJECT_POLICY_VOID + +/* Capability properties. */ + +struct cap_properties +{ + struct object_policy policy; + struct cap_addr_trans addr_trans; +}; + +#define CAP_PROPERTIES_INIT \ + { OBJECT_POLICY_INIT, CAP_ADDR_TRANS_INIT } +#define CAP_PROPERTIES(__op_object_policy, __op_addr_trans) \ + (struct cap_properties) { __op_object_policy, __op_addr_trans } +#define CAP_PROPERTIES_VOID \ + CAP_PROPERTIES (OBJECT_POLICY_INIT, CAP_ADDR_TRANS_INIT) +#define CAP_PROPERTIES_DEFAULT CAP_PROPERTIES_VOID + +/* Capability representation. */ + +#ifdef RM_INTERN +/* An OID corresponds to a page on a volume. Only the least 54 bits + are significant. */ +typedef uint64_t oid_t; +#define OID_FMT "0x%llx" +#define OID_PRINTF(__op_oid) ((oid_t) (__op_oid)) +#endif + +#define CAP_VERSION_BITS 20 +#define CAP_TYPE_BITS 6 + +struct cap +{ +#ifdef RM_INTERN + /* For a description of how versioning works, refer to the comment + titled "Object versioning" in object.h. */ + uint32_t version : CAP_VERSION_BITS; + /* Whether the capability is weak. */ + uint32_t weak_p : 1; + + /* Whether the designated object may be discarded. */ + uint32_t discardable : 1; + /* The designated object's priority. */ + int32_t priority : OBJECT_PRIORITY_BITS; + + struct cap_addr_trans addr_trans; + + uint64_t type : CAP_TYPE_BITS; + + /* If the capability designates an object, the object id. */ + uint64_t oid : 64 - CAP_TYPE_BITS; +#else + /* The shadow object (only for cappages and folios). */ + struct object *shadow; + + uint32_t discardable : 1; + int32_t priority : OBJECT_PRIORITY_BITS; + + uint32_t type : CAP_TYPE_BITS; + + uint32_t pad0 : 32 - 1 - OBJECT_PRIORITY_BITS - CAP_TYPE_BITS; + + /* This capability's address description. */ + struct cap_addr_trans addr_trans; +#endif +}; + +#define CAP_VOID ((struct cap) { .type = cap_void }) + +/* Return CAP's policy. */ +#define CAP_POLICY_GET(__cpg_cap) \ + OBJECT_POLICY ((__cpg_cap).discardable, (__cpg_cap).priority) +/* Set CAP's policy to POLICY. */ +#define CAP_POLICY_SET(__cps_cap, __cps_policy) \ + do \ + { \ + (__cps_cap)->discardable = (__cps_policy).discardable; \ + (__cps_cap)->priority = (__cps_policy).priority; \ + } \ + while (0) + +/* Return CAP's properties. */ +#define CAP_PROPERTIES_GET(__cpg_cap) \ + CAP_PROPERTIES (CAP_POLICY_GET (__cpg_cap), \ + (__cpg_cap).addr_trans) +/* Set *CAP's properties to PROPERTIES. */ +#define CAP_PROPERTIES_SET(__cps_cap, __cps_properties) \ + do \ + { \ + CAP_POLICY_SET (__cps_cap, (__cps_properties).policy); \ + (__cps_cap)->addr_trans = (__cps_properties).addr_trans; \ + } \ + while (0) + +/* Convenience macros for printing capabilities. */ + +#ifdef RM_INTERN +#define CAP_FMT "{ " OID_FMT ".%d:%s %llx/%d; %d/%d }" +#define CAP_PRINTF(cap) \ + OID_PRINTF ((cap)->oid), (cap)->version, cap_type_string ((cap)->type), \ + CAP_GUARD ((cap)), CAP_GUARD_BITS ((cap)), \ + CAP_SUBPAGE ((cap)), CAP_SUBPAGES ((cap)) +#else +#define CAP_FMT "{ %s %llx/%d; %d/%d }" +#define CAP_PRINTF(cap) \ + cap_type_string ((cap)->type), \ + CAP_GUARD ((cap)), CAP_GUARD_BITS ((cap)), \ + CAP_SUBPAGE ((cap)), CAP_SUBPAGES ((cap)) +#endif + +/* Accessors corresponding to the CAP_ADDR_TRANS macros. */ +#define CAP_SUBPAGES_LOG2(cap_) \ + CAP_ADDR_TRANS_SUBPAGES_LOG2((cap_)->addr_trans) +#define CAP_SUBPAGES(cap_) CAP_ADDR_TRANS_SUBPAGES ((cap_)->addr_trans) +#define CAP_SUBPAGE(cap_) CAP_ADDR_TRANS_SUBPAGE((cap_)->addr_trans) +#define CAP_SUBPAGE_SIZE_LOG2(cap_) \ + CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 ((cap_)->addr_trans) +#define CAP_SUBPAGE_SIZE(cap_) \ + CAP_ADDR_TRANS_SUBPAGE_SIZE ((cap_)->addr_trans) +#define CAP_SUBPAGE_OFFSET(cap_) \ + CAP_ADDR_TRANS_SUBPAGE_OFFSET((cap_)->addr_trans) +#define CAP_GUARD_BITS(cap_) CAP_ADDR_TRANS_GUARD_BITS((cap_)->addr_trans) +#define CAP_GUARD(cap_) CAP_ADDR_TRANS_GUARD((cap_)->addr_trans) + +/* NB: Only updates the shadow guard; NOT the capability. If the + latter behavior is desired, use cap_copy_x instead. */ +#define CAP_SET_GUARD_SUBPAGE(cap_, guard_, gdepth_, subpage_, subpages_) \ + ({ bool r_ = true; \ + if ((subpages_) != 1 \ + && ! ((cap_)->type == cap_cappage || (cap_)->type == cap_rcappage)) \ + { \ + debug (1, "Subpages are only allow for cappages."); \ + r_ = false; \ + } \ + if (r_) \ + r_ = CAP_ADDR_TRANS_SET_GUARD_SUBPAGE (&(cap_)->addr_trans, \ + (guard_), (gdepth_), \ + (subpage_), (subpages_)); \ + r_; \ + }) + +#define CAP_SET_GUARD(cap_, guard_, gdepth_) \ + CAP_SET_GUARD_SUBPAGE ((cap_), (guard_), (gdepth_), \ + CAP_SUBPAGE ((cap_)), CAP_SUBPAGES ((cap_))) +#define CAP_SET_SUBPAGE(cap_, subpage_, subpages_) \ + CAP_SET_GUARD_SUBPAGE ((cap_), CAP_GUARD (cap_), CAP_GUARD_BITS (cap_), \ + (subpage_), (subpages_)) + +/* Capability-related methods. */ + +#define RPC_STUB_PREFIX rm +#define RPC_ID_PREFIX RM + +#include + +enum + { + RM_cap_copy = 300, + RM_cap_rubout, + RM_cap_read, + + RM_object_discarded_clear = 400, + RM_object_discard, + RM_object_status, + RM_object_reply_on_destruction, + RM_object_name, + }; + +enum +{ + /* Use subpage in CAP_ADDR_TRANS (must be a subset of subpage in + SOURCE). */ + CAP_COPY_COPY_ADDR_TRANS_SUBPAGE = 1 << 0, + /* Use guard in TARGET, not the guard in CAP_ADDR_TRANS. */ + CAP_COPY_COPY_ADDR_TRANS_GUARD = 1 << 1, + /* Use guard in SOURCE. */ + CAP_COPY_COPY_SOURCE_GUARD = 1 << 2, + + /* When copying the capability copies a weakened reference. */ + CAP_COPY_WEAKEN = 1 << 3, + + /* Set the discardable bit on the capability. */ + CAP_COPY_DISCARDABLE_SET = 1 << 4, + + /* Set the priority of the object. */ + CAP_COPY_PRIORITY_SET = 1 << 5, +}; + +/* Copy the capability in capability slot SOURCE to the slot at ADDR + in the object OBJECT. If OBJECT is ADDR_VOID, then the calling + thread's address space root is used. + + By default, preserves SOURCE's subpage specification and copies + TARGET's guard and policy. + + If CAP_COPY_COPY_SUBPAGE is set, then uses the subpage + specification in CAP_PROPERTIES. If CAP_COPY_COPY_ADDR_TRANS_GUARD + is set, uses the guard description in CAP_PROPERTIES. + + If CAP_COPY_COPY_SOURCE_GUARD is set, uses the guard description in + source. Otherwise, preserves the guard in TARGET. + + If CAP_COPY_WEAKEN is set, saves a weakened version of SOURCE + (e.g., if SOURCE's type is cap_page, a cap_rpage is saved). + + If CAP_COPY_DISCARDABLE_SET is set, then sets the discardable bit + based on the value in PROPERTIES. Otherwise, copies SOURCE's + value. + + If CAP_COPY_PRIORITY_SET is set, then sets the priority based on + the value in properties. Otherwise, copies SOURCE's value. */ +RPC(cap_copy, 5, 0, 0, + /* cap_t activity, cap_t object, */ addr_t, addr, + cap_t, source_object, addr_t, source_addr, + uintptr_t, flags, struct cap_properties, properties) + +/* Overwrite the capability slot at ADDR in the object OBJECT with a + void capability. */ +RPC(cap_rubout, 1, 0, 0, + /* cap_t activity, cap_t object, */ addr_t, addr) + +/* Returns the public bits of the capability at address ADDR in OBJECT + in TYPE and CAP_PROPERTIES. */ +RPC(cap_read, 1, 2, 0, + /* cap_t activity, cap_t object, */ addr_t, addr, + /* Out: */ + uintptr_t, type, struct cap_properties, properties) + +/* Clear the discarded bit of the object at ADDR in object OBJECT. */ +RPC(object_discarded_clear, 1, 0, 0, + /* cap_t activity, cap_t object, */ addr_t, addr) + +/* If the object designated by OBJECT is in memory, discard it. + OBJECT must have write authority. This does not set the object's + discarded bit and thus does not result in a fault. Instead, the + next access will see, e.g., zero-filled memory. */ +RPC(object_discard, 0, 0, 0 + /* cap_t activity, cap_t object, */) + +enum +{ + object_dirty = 1 << 0, + object_referenced = 1 << 1, +}; + +/* Returns whether OBJECT is dirty. If CLEAR is set, the dirty bit is + clear. An object's dirty bit is set when the object is modified. + (Note: this is not the state of a frame but an indication of + whether the object has been modified since the last time it the + dirty bit was cleared.) */ +RPC (object_status, 1, 1, 0, + /* addr_t activity, addr_t object, */ bool, clear, + uintptr_t, status) + +/* Returns the object's return code in RETURN_CODE on object + destruction. */ +RPC (object_reply_on_destruction, 0, 1, 0, + /* cap_t principal, cap_t object, */ + /* Out: */ + uintptr_t, return_code); + +struct object_name +{ + char name[12]; +}; + +/* Give object OBJECT a name. This is only used for debugging + purposes and is only supported by some objects, in particular, + activities and threads. */ +RPC (object_name, 1, 0, 0, + /* cap_t activity, cap_t object, */ struct object_name, name); + + +#undef RPC_STUB_PREFIX +#undef RPC_ID_PREFIX + +/* An object. */ + +/* The number of capabilities per page. */ +enum + { + CAPPAGE_SLOTS = PAGESIZE / 16, + }; +/* The log2 of the number of capabilities per page. */ +enum + { + CAPPAGE_SLOTS_LOG2 = PAGESIZE_LOG2 - 4, + }; + +struct object +{ + union + { + char data[PAGESIZE]; + struct cap caps[CAPPAGE_SLOTS]; + }; +}; + +#ifdef RM_INTERN +typedef struct activity *activity_t; +#else +typedef addr_t activity_t; +#endif + +#ifndef RM_INTERN +/* Return the address of cap CAP's shadow object. */ +static inline void * +cap_get_shadow (const struct cap *cap) +{ + return cap->shadow; +} + +/* Set CAP's shadow object to SHADOW. */ +static inline void +cap_set_shadow (struct cap *cap, void *shadow) +{ + cap->shadow = shadow; +} +#endif + +/* Given cap CAP, return the corresponding object, or NULL, if there + is none. */ +#ifdef RM_INTERN +extern struct object *cap_to_object (activity_t activity, struct cap *cap); +#else +static inline struct object * +cap_to_object (activity_t activity, struct cap *cap) +{ + return cap_get_shadow (cap); +} +#endif + +/* Wrapper for the cap_copy method. Also updates shadow + capabilities. */ +static inline bool +cap_copy_x (activity_t activity, + addr_t target_address_space, struct cap *target, addr_t target_addr, + addr_t source_address_space, struct cap source, addr_t source_addr, + int flags, struct cap_properties properties) +{ + /* By default, we preserve SOURCE's subpage specification. */ + int subpage = CAP_SUBPAGE (&source); + int subpages = CAP_SUBPAGES (&source); + + if ((flags & CAP_COPY_COPY_ADDR_TRANS_SUBPAGE)) + /* Copy the subpage descriptor from PROPERTIES.ADDR_TRANS. */ + { + if (CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans) != 1 + && (source.type != cap_cappage + && source.type != cap_rcappage)) + /* A subpage descriptor is only valid for + cappages. */ + { + debug (1, "subpages (%d) specified for non-cappage " + "cap " CAP_FMT, + CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans), + CAP_PRINTF (&source)); + return false; + } + + if (! + (/* Start of PROPERTIES.ADDR_TRANS must be at or after start of + SOURCE. */ + subpage * (256 / subpages) + <= (CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans) * + (256 / CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans))) + /* End of PROPERTIES.ADDR_TRANS must be before or at end of + SOURCE. */ + && (((CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans) + 1) * + (256 / CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans))) + <= (subpage + 1) * (256 / subpages)))) + /* The subpage descriptor does not narrow the + rights. */ + { + debug (1, "specified subpage (%d/%d) not a subset " + " of source " CAP_FMT, + CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans), + CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans), + CAP_PRINTF (&source)); + return false; + } + + subpage = CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans); + subpages = CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans); + } + + /* By default, we preserve the guard in TARGET. */ + int guard = CAP_GUARD (target); + int gbits = CAP_GUARD_BITS (target); + + if ((flags & CAP_COPY_COPY_ADDR_TRANS_GUARD)) + /* Copy guard from PROPERTIES.ADDR_TRANS. */ + { + guard = CAP_ADDR_TRANS_GUARD (properties.addr_trans); + gbits = CAP_ADDR_TRANS_GUARD_BITS (properties.addr_trans); + } + else if ((flags & CAP_COPY_COPY_SOURCE_GUARD)) + /* Copy guard from SOURCE. */ + { + guard = CAP_GUARD (&source); + gbits = CAP_GUARD_BITS (&source); + } + + int type = source.type; + if ((flags & CAP_COPY_WEAKEN)) + type = cap_type_weaken (type); + +#ifdef RM_INTERN + /* Changing a capability can change how addresses are translated. + In this case, we need to shoot down all cached translations. */ + bool changes_translation = false; + + if (target->oid != source.oid) + { + debug (5, "OID mismatch, changes translation"); + changes_translation = true; + } + else if (target->version != source.version) + { + debug (5, "Version mismatch, changes translation"); + changes_translation = true; + } + + if (subpage != CAP_SUBPAGE (target) || subpages != CAP_SUBPAGES (target)) + { + debug (5, "Subpage specification differs %d/%d -> %d/%d.", + subpage, subpages, CAP_SUBPAGE (target), CAP_SUBPAGES (target)); + changes_translation = true; + } + + if (guard != CAP_GUARD (target) + || gbits != CAP_GUARD_BITS (target)) + { + debug (5, "Guard changed invalidating translation " + "0x%x/%d -> %llx/%d", + guard, gbits, CAP_GUARD (target), CAP_GUARD_BITS (target)); + changes_translation = true; + } + + if (type != target->type) + { + debug (5, "Type changed, invalidating translation"); + changes_translation = true; + } + + if (changes_translation) + { + extern void cap_shootdown (struct activity *activity, struct cap *cap); + + debug (5, "Translation changed: " CAP_FMT " -> " CAP_FMT, + CAP_PRINTF (target), CAP_PRINTF (&source)); + + cap_shootdown (activity, target); + } +#endif + + if (! CAP_ADDR_TRANS_SET_GUARD_SUBPAGE (&properties.addr_trans, + guard, gbits, + subpage, subpages)) + return false; + +#ifndef RM_INTERN + assert (! ADDR_IS_VOID (target_addr)); + assert (! ADDR_IS_VOID (source_addr)); + + error_t err = rm_cap_copy (activity, target_address_space, target_addr, + source_address_space, source_addr, + flags, properties); + assert (err == 0); +#endif + + *target = source; + target->addr_trans = properties.addr_trans; + target->type = type; + + if ((flags & CAP_COPY_DISCARDABLE_SET)) + target->discardable = properties.policy.discardable; + + if ((flags & CAP_COPY_PRIORITY_SET)) + target->priority = properties.policy.priority; + + return true; +} + +/* Copy the capability SOURCE to capability TARGET. Preserves + SOURCE's subpage specification and TARGET's guard. Copies SOURCE's + policy. */ +static inline bool +cap_copy (activity_t activity, + addr_t target_as, struct cap *target, addr_t target_addr, + addr_t source_as, struct cap source, addr_t source_addr) +{ + return cap_copy_x (activity, target_as, target, target_addr, + source_as, source, source_addr, + CAP_COPY_DISCARDABLE_SET | CAP_COPY_PRIORITY_SET, + CAP_PROPERTIES_GET (source)); +} + +#endif diff --git a/libviengoos/viengoos/folio.h b/libviengoos/viengoos/folio.h new file mode 100644 index 0000000..4172e5d --- /dev/null +++ b/libviengoos/viengoos/folio.h @@ -0,0 +1,441 @@ +/* folio.h - Folio definitions. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GNU Hurd. If not, see + . */ + +#ifndef _VIENGOOS_FOLIO_H +#define _VIENGOOS_FOLIO_H 1 + +#include +#include +#include +#include + +/* Number of user objects per folio. */ +enum + { + FOLIO_OBJECTS = 128, + }; +enum + { + FOLIO_OBJECTS_LOG2 = 7, + }; + +/* User settable folio policy. */ + +/* The range of valid folio priorities. A lower numerical value + corresponds to a lower priority. */ +#define FOLIO_PRIORITY_BITS 15 +#define FOLIO_PRIORITY_MIN (-(1 << (FOLIO_PRIORITY_BITS - 1))) +#define FOLIO_PRIORITY_LRU (0) +#define FOLIO_PRIORITY_MAX ((1 << (FOLIO_PRIORITY_BITS - 1)) - 1) + +/* The folio group range. */ +#define FOLIO_GROUP_BITS 15 +#define FOLIO_GROUP_NONE 0 +#define FOLIO_GROUP_MIN 0 +#define FOLIO_GROUP_MAX ((1 << FOLIO_BITS) - 1) + +struct folio_policy +{ + union + { + struct + { + /* Whether a folio is discardable. If an activity reaches it + quota, rather than returning an out of memory error, the + system may reclaim storage with the discardable bit set. It + performs the equivalent of calling folio_free on the + folio. */ + int32_t discardable : 1; + + /* The following are only used if DISCARABLE is true. */ + + /* Folios can belong to a group. When one folio is discarded, + all folios in that group are discarded, unless GROUP is + FOLIO_GROUP_NONE. */ + uint32_t group : FOLIO_GROUP_BITS; + + /* By default, the system tries to discard folios according to + an LRU policy. This can be overridden using this field. In + this case, folios from the lowest priority group are + discarded. */ + int32_t priority : FOLIO_PRIORITY_BITS; + }; + uint32_t raw; + }; +}; + +#define FOLIO_POLICY_INIT { { raw: 0 } } +#define FOLIO_POLICY_VOID (struct folio_policy) FOLIO_POLICY_INIT +/* The default policy is not discardable. */ +#define FOLIO_POLICY_DEFAULT FOLIO_POLICY_VOID + +/* The format of the first page of a folio. This page is followed (on + disk) by FOLIO_OBJECTS pages. */ +struct folio +{ +#ifdef RM_INTERN + /* Folios are the unit of storage accounting. Every folio belongs + to exactly one activity. To track what folios belong to a + particular activity, each folio is attached to a doubly-linked + list originating at its owner activity. */ + struct cap activity; + struct cap next; + struct cap prev; + + /* The storage policy. */ + struct folio_policy policy; + + struct + { + /* Each object in the folio Disk version of each object. */ + uint32_t version : CAP_VERSION_BITS; + + /* Whether a page has any content (i.e., if it is not + uninitialized). */ + uint32_t content : 1; + + /* The object's memory policy when accessed via the folio. */ + uint32_t discardable : 1; + int32_t priority : OBJECT_PRIORITY_BITS; + } misc[1 + FOLIO_OBJECTS]; + + /* The type. */ + uint8_t types[FOLIO_OBJECTS]; + + /* Bit array indicating whether the an object has a non-empty wait + queue. */ + uint8_t wait_queues_p[(1 + FOLIO_OBJECTS + (8 - 1)) / 8]; + + uint8_t discarded[(FOLIO_OBJECTS + (8 - 1)) / 8]; + + /* User reference and dirty bits. Optionally reset on read. Set + respectively when an object is referenced or modified. Flushing + the object to disk does not clear this. */ + uint8_t dirty[(1 + FOLIO_OBJECTS + (8 - 1)) / 8]; + uint8_t referenced[(1 + FOLIO_OBJECTS + (8 - 1)) / 8]; + + /* Head of the list of objects waiting for some event on this + object. An element of this array is only valid if the + corresponding element of WAIT_QUEUES_P is true. The list is a + circular list. HEAD->PREV points to the tail. TAIL->NEXT points + to the OBJECT (NOT HEAD). */ + oid_t wait_queues[1 + FOLIO_OBJECTS]; + + uint64_t checksums[1 + FOLIO_OBJECTS][2]; +#else + /* User-space folio. */ + struct cap objects[FOLIO_OBJECTS]; +#endif +}; + +#ifdef RM_INTERN +typedef struct folio *folio_t; +#else +typedef addr_t folio_t; +#endif + +/* OBJECT is from -1 to FOLIO_OBJECTS. */ +static inline enum cap_type +folio_object_type (struct folio *folio, int object) +{ +#ifdef RM_INTERN + assert (object >= -1 && object < FOLIO_OBJECTS); + + if (object == -1) + return cap_folio; + return folio->types[object]; +#else + assert (object >= 0 && object < FOLIO_OBJECTS); + return folio->objects[object].type; +#endif +} + +static inline void +folio_object_type_set (struct folio *folio, int object, enum cap_type type) +{ + assert (object >= 0 && object < FOLIO_OBJECTS); + +#ifdef RM_INTERN + folio->types[object] = type; +#else + folio->objects[object].type = type; +#endif +} + +static inline struct object_policy +folio_object_policy (struct folio *folio, int object) +{ + struct object_policy policy; + +#ifdef RM_INTERN + assert (object >= -1 && object < FOLIO_OBJECTS); + + policy.discardable = folio->misc[object + 1].discardable; + policy.priority = folio->misc[object + 1].priority; +#else + assert (object >= 0 && object < FOLIO_OBJECTS); + + policy.discardable = folio->objects[object].discardable; + policy.priority = folio->objects[object].priority; +#endif + + return policy; +} + +static inline void +folio_object_policy_set (struct folio *folio, int object, + struct object_policy policy) +{ +#ifdef RM_INTERN + assert (object >= -1 && object < FOLIO_OBJECTS); + + folio->misc[object + 1].discardable = policy.discardable; + folio->misc[object + 1].priority = policy.priority; +#else + assert (object >= 0 && object < FOLIO_OBJECTS); + + folio->objects[object].discardable = policy.discardable; + folio->objects[object].priority = policy.priority; +#endif +} + +#ifdef RM_INTERN +#include + +static inline bool +folio_object_wait_queue_p (struct folio *folio, int object) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + return bit_test (folio->wait_queues_p, object + 1); +} + +static inline void +folio_object_wait_queue_p_set (struct folio *folio, int object, + bool valid) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + bit_set_to (folio->wait_queues_p, sizeof (folio->wait_queues_p), + object + 1, valid); +} + +static inline oid_t +folio_object_wait_queue (struct folio *folio, int object) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + return folio->wait_queues[object + 1]; +} + +static inline void +folio_object_wait_queue_set (struct folio *folio, int object, + oid_t head) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + folio->wait_queues[object + 1] = head; +} + +static inline uint32_t +folio_object_version (struct folio *folio, int object) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + return folio->misc[object + 1].version; +} + +static inline void +folio_object_version_set (struct folio *folio, int object, + uint32_t version) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + folio->misc[object + 1].version = version; +} + +static inline bool +folio_object_content (struct folio *folio, int object) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + return folio->misc[object + 1].content; +} + +static inline void +folio_object_content_set (struct folio *folio, int object, + bool content) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + folio->misc[object + 1].content = content; +} + +static inline bool +folio_object_discarded (struct folio *folio, int object) +{ + assert (object >= 0 && object < FOLIO_OBJECTS); + + return bit_test (folio->discarded, object); +} + +static inline void +folio_object_discarded_set (struct folio *folio, int object, bool valid) +{ + assert (object >= 0 && object < FOLIO_OBJECTS); + + bit_set_to (folio->discarded, sizeof (folio->discarded), + object, valid); +} + +static inline bool +folio_object_referenced (struct folio *folio, int object) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + return bit_test (folio->referenced, object + 1); +} + +static inline void +folio_object_referenced_set (struct folio *folio, int object, bool p) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + bit_set_to (folio->referenced, sizeof (folio->referenced), object + 1, p); +} + +static inline bool +folio_object_dirty (struct folio *folio, int object) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + return bit_test (folio->dirty, object + 1); +} + +static inline void +folio_object_dirty_set (struct folio *folio, int object, bool p) +{ + assert (object >= -1 && object < FOLIO_OBJECTS); + + bit_set_to (folio->dirty, sizeof (folio->dirty), object + 1, p); +} +#endif /* RM_INTERN */ + +/* Return a cap designating folio FOLIO's OBJECT'th object. */ +#ifdef RM_INTERN +/* This needs to be a macro as we use object_to_object_desc which is + made available by object.h but object.h includes this file. */ +#define folio_object_cap(__foc_folio, __foc_object) \ + ({ \ + struct cap __foc_cap; \ + \ + __foc_cap.type = folio_object_type (__foc_folio, __foc_object); \ + __foc_cap.version = folio_object_version (__foc_folio, \ + __foc_object); \ + \ + struct cap_properties __foc_cap_properties \ + = CAP_PROPERTIES (folio_object_policy (__foc_folio, __foc_object), \ + CAP_ADDR_TRANS_VOID); \ + CAP_PROPERTIES_SET (&__foc_cap, __foc_cap_properties); \ + \ + __foc_cap.oid \ + = object_to_object_desc ((struct object *) __foc_folio)->oid \ + + 1 + __foc_object; \ + \ + __foc_cap; \ + }) +#else +static inline struct cap +folio_object_cap (struct folio *folio, int object) +{ + assert (0 <= object && object < FOLIO_OBJECTS); + return folio->objects[object]; +} +#endif + +#define RPC_STUB_PREFIX rm +#define RPC_ID_PREFIX RM + +#include + +enum + { + RM_folio_alloc = 200, + RM_folio_free, + RM_folio_object_alloc, + RM_folio_policy + }; + +/* Allocate a folio against ACTIVITY. Return a capability in the + caller's cspace in slot FOLIO. POLICY specifies the storage + policy. */ +RPC(folio_alloc, 1, 0, 1, + /* cap_t, principal, cap_t, activity, */ + struct folio_policy, policy, cap_t, folio) + +/* Free the folio designated by FOLIO. */ +RPC(folio_free, 0, 0, 0 + /* cap_t, principal, cap_t, folio */) + +/* Destroys the INDEXth object in folio FOLIO and allocate in its + place an object of tye TYPE. If TYPE is CAP_VOID, any existing + object is destroyed, however, no object is instantiated in its + place. POLICY specifies the object's policy when accessed via the + folio. If an object is destroyed and there are waiters, they are + passed the return code RETURN_CODE. + + Returns a capability to the allocated object in OBJECT. Returns a + weak capability to the object in OBJECT_WEAK. */ +RPC(folio_object_alloc, 4, 0, 2, + /* cap_t, principal, cap_t, folio, */ + uintptr_t, index, uintptr_t, type, + struct object_policy, policy, uintptr_t, return_code, + /* Out: */ + cap_t, object, cap_t, object_weak) + +/* Flags for folio_policy. */ +enum +{ + FOLIO_POLICY_DELIVER = 1 << 0, + + FOLIO_POLICY_DISCARDABLE_SET = 1 << 1, + FOLIO_POLICY_GROUP_SET = 1 << 2, + FOLIO_POLICY_PRIORITY_SET = 1 << 3, + + FOLIO_POLICY_SET = (FOLIO_POLICY_DISCARDABLE_SET + | FOLIO_POLICY_GROUP_SET + | FOLIO_POLICY_PRIORITY_SET) +}; + +/* Get and set the management policy for folio FOLIO. + + If FOLIO_POLICY_DELIVER is set in FLAGS, then return FOLIO's + current paging policy in OLD. Then, if any of the set flags are + set, set the corresponding values based on the value of POLICY. */ +RPC(folio_policy, 2, 1, 0, + /* cap_t, principal, cap_t, folio, */ + uintptr_t, flags, struct folio_policy, policy, + /* Out: */ + struct folio_policy, old) + +#undef RPC_STUB_PREFIX +#undef RPC_ID_PREFIX + +#endif diff --git a/libviengoos/viengoos/futex.h b/libviengoos/viengoos/futex.h new file mode 100644 index 0000000..3f77b6d --- /dev/null +++ b/libviengoos/viengoos/futex.h @@ -0,0 +1,219 @@ +/* futex.h - Futex definitions. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Hurd. If not, see + . */ + +#ifndef _HURD_FUTEX_H +#define _HURD_FUTEX_H 1 + +#include +#include +#include +#include +#define __need_timespec +#include + +/* The interface to the kernel futex implementation. This is only + here because glibc really wants futexes. If this project gets + sufficient momentum, the kernel futex implementation should be + replaced with a more microkernel friendly approach to locks. */ + +enum + { + RM_futex = 800, + }; + +#define RPC_STUB_PREFIX rm +#define RPC_ID_PREFIX RM + +#include + +/* Operations. */ +enum + { + FUTEX_WAIT, + FUTEX_WAKE, + FUTEX_WAKE_OP, + FUTEX_CMP_REQUEUE, +#if 0 + /* We don't support these operations. The first is deprecated and + the second requires FDs which the kernel doesn't support. + Although we could return EOPNOTSUPP, commenting them out + catches any uses at compile-time. */ + FUTEX_REQUEUE, + FUTEX_FD, +#endif + }; + +enum + { + FUTEX_OP_SET = 0, + FUTEX_OP_ADD = 1, + FUTEX_OP_OR = 2, + FUTEX_OP_ANDN = 3, + FUTEX_OP_XOR = 4 + }; + +enum + { + FUTEX_OP_CMP_EQ = 0, + FUTEX_OP_CMP_NE = 1, + FUTEX_OP_CMP_LT = 2, + FUTEX_OP_CMP_LE = 3, + FUTEX_OP_CMP_GT = 4, + FUTEX_OP_CMP_GE = 5 + }; + +union futex_val2 +{ + struct timespec timespec; + int value; +}; + +union futex_val3 +{ + int value; + struct + { + int cmparg: 12; + int oparg: 12; + int cmp: 4; + int op: 4; + }; +}; +#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE \ + (union futex_val3) { { 1, 0, FUTEX_OP_CMP_GT, FUTEX_OP_SET } } + +RPC (futex, 7, 1, 0, + /* cap_t principal, cap_t thread, */ + void *, addr1, int, op, int, val1, + bool, timeout, union futex_val2, val2, + void *, addr2, union futex_val3, val3, + /* Out: */ + long, out); + +#undef RPC_STUB_PREFIX +#undef RPC_ID_PREFIX + +#ifndef RM_INTERN +#include + +struct futex_return +{ + error_t err; + long ret; +}; + +static inline struct futex_return +__attribute__((always_inline)) +futex_using (struct hurd_message_buffer *mb, + void *addr1, int op, int val1, struct timespec *timespec, + void *addr2, int val3) +{ + union futex_val2 val2; + if (timespec) + val2.timespec = *timespec; + else + __builtin_memset (&val2, 0, sizeof (val2)); + + error_t err; + long ret = 0; /* Elide gcc warning. */ + if (mb) + err = rm_futex_using (mb, + ADDR_VOID, ADDR_VOID, + addr1, op, val1, !! timespec, val2, addr2, + (union futex_val3) val3, &ret); + else + err = rm_futex (ADDR_VOID, ADDR_VOID, + addr1, op, val1, !! timespec, val2, addr2, + (union futex_val3) val3, &ret); + return (struct futex_return) { err, ret }; +} + +/* Standard futex signatures. See futex documentation, e.g., Futexes + are Tricky by Ulrich Drepper. */ +static inline struct futex_return +__attribute__((always_inline)) +futex (void *addr1, int op, int val1, struct timespec *timespec, + void *addr2, int val3) +{ + return futex_using (NULL, addr1, op, val1, timespec, addr2, val3); +} + + +/* If *F is VAL, wait until woken. */ +static inline long +__attribute__((always_inline)) +futex_wait_using (struct hurd_message_buffer *mb, int *f, int val) +{ + struct futex_return ret; + ret = futex_using (mb, f, FUTEX_WAIT, val, NULL, 0, 0); + if (ret.err) + { + errno = ret.err; + return -1; + } + return ret.ret; +} + +static inline long +__attribute__((always_inline)) +futex_wait (int *f, int val) +{ + return futex_wait_using (NULL, f, val); +} + + +/* If *F is VAL, wait until woken. */ +static inline long +__attribute__((always_inline)) +futex_timed_wait (int *f, int val, struct timespec *timespec) +{ + struct futex_return ret; + ret = futex (f, FUTEX_WAIT, val, timespec, 0, 0); + if (ret.err) + { + errno = ret.err; + return -1; + } + return ret.ret; +} + + +/* Signal NWAKE waiters waiting on futex F. */ +static inline long +__attribute__((always_inline)) +futex_wake_using (struct hurd_message_buffer *mb, int *f, int nwake) +{ + struct futex_return ret; + ret = futex_using (mb, f, FUTEX_WAKE, nwake, NULL, 0, 0); + if (ret.err) + { + errno = ret.err; + return -1; + } + return ret.ret; +} + +static inline long +__attribute__((always_inline)) +futex_wake (int *f, int nwake) +{ + return futex_wake_using (NULL, f, nwake); +} +#endif /* !RM_INTERN */ + +#endif diff --git a/libviengoos/viengoos/ipc.h b/libviengoos/viengoos/ipc.h new file mode 100644 index 0000000..67c2bad --- /dev/null +++ b/libviengoos/viengoos/ipc.h @@ -0,0 +1,297 @@ +/* ipc.h - Interprocess communication interface. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Hurd. If not, see + . */ + +#ifndef _VIENGOOS_IPC_H +#define _VIENGOOS_IPC_H 1 + +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_L4 +#include +#endif + +/* IPC flags. */ +enum + { + /* IPC includes a receive phase. */ + VG_IPC_RECEIVE = 1 << 0, + /* Don't unblock the receive buffer if there is no message queued + for delivery. */ + VG_IPC_RECEIVE_NONBLOCKING = 1 << 1, + /* Activate the thread on message receipt. */ + VG_IPC_RECEIVE_ACTIVATE = 1 << 2, + /* Set the receive messenger's thread to the caller. */ + VG_IPC_RECEIVE_SET_THREAD_TO_CALLER = 1 << 3, + /* Set the receive messener's address space root to the + caller's. */ + VG_IPC_RECEIVE_SET_ASROOT_TO_CALLERS = 1 << 4, + /* Whether to receive the message inline. */ + VG_IPC_RECEIVE_INLINE = 1 << 5, + /* Whether to receive any capabilities inline when receiving a + message inline (i.e., when VG_IPC_RECEIVE_INLINE is set). */ + VG_IPC_RECEIVE_INLINE_CAP1 = 1 << 6, + + /* IPC includes a send phase. */ + VG_IPC_SEND = 1 << 7, + /* If the object is blocked, return EWOULDBLOCK. */ + VG_IPC_SEND_NONBLOCKING = 1 << 8, + /* Activate the thread on message transfer. */ + VG_IPC_SEND_ACTIVATE = 1 << 9, + /* Set the send messenger's thread to the caller. */ + VG_IPC_SEND_SET_THREAD_TO_CALLER = 1 << 10, + /* Set the sender messener's address space root to the + caller's. */ + VG_IPC_SEND_SET_ASROOT_TO_CALLERS = 1 << 11, + /* Whether to send the message inline. */ + VG_IPC_SEND_INLINE = 1 << 12, + + /* Which inline data to transfer when sending a message. Inline + data is ignored if the send buffer is not ADDR_VOID. */ + VG_IPC_SEND_INLINE_WORD1 = 1 << 13, + VG_IPC_SEND_INLINE_WORD2 = 1 << 14, + VG_IPC_SEND_INLINE_CAP1 = 1 << 15, + + + /* The IPC includes a return phase. */ + VG_IPC_RETURN = 1 << 16, + + }; + +#ifndef RM_INTERN +/* An IPC consists of three phases: the receive phase, the send phase + and the return phase. All three phases are optional. Each phase + is executed after the previous phase has completed. If a phase + does not complete successfully, the phase is aborted and the + remaining phases are not executed. + + + RECEIVE PHASE + + If FLAGS contains VG_IPC_RECEIVE, the IPC includes a receive phase. + + If RECV_BUF is not ADDR_VOID, associates RECV_BUF with + RECV_MESSENGER. + + If FLAGS contains VG_IPC_RECEIVE_NONBLOCKING: + + Unblocks RECV_MESSENGER if RECV_MESSENGER has a messenger waiting + to deliver a message. Otherwise, returns EWOUDBLOCK. + + Otherwise: + + Unblocks RECV_MESSENGER. + + Resources are charged to RECV_ACTIVITY. + + If VG_IPC_RECEIVE_ACTIVATE is set, an activation is sent to the + thread associated with RECV_MESSENGER when RECV_MESSENGER receives + a message. + + + SEND PHASE + + If FLAGS contains VG_IPC_SEND, the IPC includes a send phase. + + If SEND_MESSENGER is ADDR_VOID, an implicit messenger is allocated + and VG_IPC_SEND_NONBLOCKING is assumed to be on. + + If SEND_BUF is not ADDR_VOID, assocaiates SEND_BUF with + SEND_MESSENGER. Otherwise, associates inline data (INLINE_WORD1, + INLINE_WORD2 and INLINE_CAP) according to the inline flags with + SEND_MESSENGER. + + If FLAGS contains VG_IPC_SEND_NONBLOCKING: + + If TARGET_MESSENGER is blocked, returns ETIMEDOUT. + + Otherwise: + + Blocks SEND_MESSENGER and enqueues it on TARGET_MESSENGER. + + When TARGET_MESSENGER becomes unblocked, SEND_MESSENGER delivers + its message to TARGET_MESSENGER. + + Resources are charged to SEND_ACTIVITY. + + If VG_IPC_SEND_ACTIVATE is set, an activation is sent to the thread + associated with SEND_MESSENGER when SEND_MESSENGER's message is + transferred to TARGET_MESSENGER (or, when TARGET_MESSENGER is + destroyed). + + + RETURN PHASE + + If FLAGS contains VG_IPC_RETURN, the IPC returns. Otherwise, the + calling thread is suspended until it is next activated. */ +static inline error_t +vg_ipc_full (uintptr_t flags, + addr_t recv_activity, addr_t recv_messenger, addr_t recv_buf, + addr_t recv_inline_cap, + addr_t send_activity, addr_t target_messenger, + addr_t send_messenger, addr_t send_buf, + uintptr_t send_inline_word1, uintptr_t send_inline_word2, + addr_t send_inline_cap) +{ + error_t err = 0; + +#ifdef USE_L4 + l4_msg_tag_t tag = l4_niltag; + l4_msg_tag_set_label (&tag, 8194); + + l4_msg_t msg; + l4_msg_clear (msg); + l4_msg_set_msg_tag (msg, tag); + + void msg_append_addr (addr_t addr) + { + int i; + for (i = 0; i < sizeof (addr_t) / sizeof (uintptr_t); i ++) + l4_msg_append_word (msg, ((uintptr_t *) &addr)[i]); + } + + l4_msg_append_word (msg, flags); + + msg_append_addr (recv_activity); + msg_append_addr (recv_messenger); + msg_append_addr (recv_buf); + msg_append_addr (recv_inline_cap); + + msg_append_addr (send_activity); + msg_append_addr (target_messenger); + + msg_append_addr (send_messenger); + msg_append_addr (send_buf); + + l4_msg_append_word (msg, send_inline_word1); + l4_msg_append_word (msg, send_inline_word2); + msg_append_addr (send_inline_cap); + + l4_msg_load (msg); + l4_accept (l4_map_grant_items (L4_COMPLETE_ADDRESS_SPACE)); + + bool call = true; + + while (1) + { + extern struct hurd_startup_data *__hurd_startup_data; + + if (call) + tag = l4_call (__hurd_startup_data->rm); + else + tag = l4_receive (__hurd_startup_data->rm); + + if (likely (l4_ipc_failed (tag))) + { + if (((l4_error_code () >> 1) & 0x7) == 3) + { + if (l4_error_code () & 1) + /* IPC was interrupted in the receive phase, i.e., we + got a response. */ + break; + else + call = false; + } + else + return EHOSTDOWN; + } + else + { + assert (l4_untyped_words (tag) == 1); + l4_msg_store (tag, msg); + /* Potential error performing IPC (or VG_RETURN specified). */ + err = l4_msg_word (msg, 1); + break; + } + } +#else +# warning vg_ipc not ported to this architecture. +#endif + + return err; +} + +static inline error_t +vg_ipc (uintptr_t flags, + addr_t recv_activity, addr_t recv_messenger, addr_t recv_buf, + addr_t send_activity, addr_t target_messenger, + addr_t send_messenger, addr_t send_buf) +{ + return vg_ipc_full (flags, + recv_activity, recv_messenger, recv_buf, ADDR_VOID, + send_activity, target_messenger, + send_messenger, send_buf, + 0, 0, ADDR_VOID); +} + +static inline error_t +vg_ipc_short (uintptr_t flags, + addr_t recv_activity, addr_t recv_messenger, addr_t recv_cap, + addr_t send_activity, addr_t target_messenger, + addr_t send_messenger, + uintptr_t inline_word1, uintptr_t inline_word2, + addr_t inline_cap) +{ + return vg_ipc_full (flags, + recv_activity, recv_messenger, ADDR_VOID, recv_cap, + send_activity, target_messenger, + send_messenger, ADDR_VOID, + inline_word1, inline_word2, inline_cap); +} + +static inline error_t +vg_send (uintptr_t flags, addr_t send_activity, addr_t target_messenger, + addr_t send_messenger, addr_t send_buf) +{ + return vg_ipc_full (flags | VG_IPC_SEND | VG_IPC_SEND_ACTIVATE, + ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, + send_activity, target_messenger, + send_messenger, send_buf, + 0, 0, ADDR_VOID); +} + +static inline error_t +vg_reply (uintptr_t flags, addr_t send_activity, addr_t target_messenger, + addr_t send_messenger, addr_t send_buf) +{ + return vg_ipc_full (flags | VG_IPC_SEND | VG_IPC_SEND_NONBLOCKING, + ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, + send_activity, target_messenger, send_messenger, send_buf, + 0, 0, ADDR_VOID); +} + +/* Suspend the caller until the next activation. */ +static inline error_t +vg_suspend (void) +{ + return vg_ipc_full (0, + ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, + ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, + 0, 0, ADDR_VOID); +} + +#endif + +#endif diff --git a/libviengoos/viengoos/message.h b/libviengoos/viengoos/message.h new file mode 100644 index 0000000..bff1e9a --- /dev/null +++ b/libviengoos/viengoos/message.h @@ -0,0 +1,229 @@ +/* message.h - Message buffer definitions. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Hurd. If not, see + . */ + +#ifndef _VIENGOOS_MESSAGE_H +#define _VIENGOOS_MESSAGE_H 1 + +#include +#include +#include +#include + +/* A message. + + When handing a message structure to a messenger, it must start at + the beginning of a page and it cannot extend past the end of that + page. */ +struct vg_message +{ + union + { + struct + { + /* The number of capability addresses in the message. */ + uint16_t cap_count; + /* The number of bytes of data transferred in this message. */ + uint16_t data_count; + + addr_t caps[/* cap_count */]; + // char data[data_count]; + }; + + char raw[PAGESIZE]; + }; +}; + + +/* Clear the msg so that it references no capabilities and + contains no data. */ +static inline void +vg_message_clear (struct vg_message *msg) +{ + msg->cap_count = 0; + msg->data_count = 0; +} + + +/* Return the number of capabilities referenced by MSG. */ +static inline int +vg_message_cap_count (struct vg_message *msg) +{ + int max = (PAGESIZE - __builtin_offsetof (struct vg_message, caps)) + / sizeof (addr_t); + + int count = msg->cap_count; + if (count > max) + count = max; + + return count; +} + +/* Return the number of bytes of data in MSG. */ +static inline int +vg_message_data_count (struct vg_message *msg) +{ + int max = PAGESIZE + - vg_message_cap_count (msg) * sizeof (addr_t) + - __builtin_offsetof (struct vg_message, caps); + + int count = msg->data_count; + if (count > max) + count = max; + + return count; +} + + +/* Return the start of the capability address array in msg MSG. */ +static inline addr_t * +vg_message_caps (struct vg_message *msg) +{ + return msg->caps; +} + +/* Return capability IDX in msg MSG. */ +static inline addr_t +vg_message_cap (struct vg_message *msg, int idx) +{ + assert (idx < msg->cap_count); + + return msg->caps[idx]; +} + + +/* Return the start of the data in msg MSG. */ +static inline char * +vg_message_data (struct vg_message *msg) +{ + return (void *) msg + + __builtin_offsetof (struct vg_message, caps) + + msg->cap_count * sizeof (addr_t); +} + +/* Return data word WORD in msg MSG. */ +static inline uintptr_t +vg_message_word (struct vg_message *msg, int word) +{ + assert (word < msg->data_count / sizeof (uintptr_t)); + + return ((uintptr_t *) vg_message_data (msg))[word]; +} + + +/* Append the array of capability addresses CAPS to the msg MSG. + There must be sufficient room in the message buffer. */ +static inline void +vg_message_append_caps (struct vg_message *msg, int cap_count, addr_t *caps) +{ + assert ((void *) vg_message_data (msg) - (void *) msg + + vg_message_data_count (msg) + cap_count * sizeof (*caps) + <= PAGESIZE); + + __builtin_memmove (&msg->caps[msg->cap_count + cap_count], + &msg->caps[msg->cap_count], + msg->data_count); + + __builtin_memcpy (&msg->caps[msg->cap_count], + caps, + cap_count * sizeof (addr_t)); + + msg->cap_count += cap_count; +} + +/* Append the capability address CAP to the msg MSG. There must be + sufficient room in the message buffer. */ +static inline void +vg_message_append_cap (struct vg_message *msg, addr_t cap) +{ + vg_message_append_caps (msg, 1, &cap); +} + + +/* Append DATA to the msg MSG. There must be sufficient room in the + message buffer. */ +static inline void +vg_message_append_data (struct vg_message *msg, int bytes, char *data) +{ + int dstart = __builtin_offsetof (struct vg_message, caps) + + msg->cap_count * sizeof (addr_t); + int dend = dstart + msg->data_count; + + int new_dend = dend + bytes; + assert (new_dend <= PAGESIZE); + + msg->data_count += bytes; + __builtin_memcpy ((void *) msg + dend, data, bytes); +} + +/* Append the word WORD to the msg MSG. There must be + sufficient room in the message buffer. */ +static inline void +vg_message_append_word (struct vg_message *msg, uintptr_t word) +{ + vg_message_append_data (msg, sizeof (word), (char *) &word); +} + +/* Return data word WORD in msg MSG. */ +static inline void +vg_message_word_set (struct vg_message *msg, int pos, uintptr_t word) +{ + if (msg->data_count < pos * sizeof (uintptr_t)) + msg->data_count = pos * sizeof (uintptr_t); + + ((uintptr_t *) vg_message_data (msg))[pos] = word; +} + +#include + +static inline void +vg_message_dump (struct vg_message *message) +{ + s_printf ("%d bytes, %d caps\n", + vg_message_data_count (message), + vg_message_cap_count (message)); + + char d2h[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F' }; + unsigned char *data = vg_message_data (message); + + int i = 0; + while (i < vg_message_data_count (message)) + { + s_printf ("%d: ", i); + + int j, k; + for (j = 0, k = 0; + i < vg_message_data_count (message) && j < 4 * 8; + j ++, i ++) + { + s_printf ("%c%c", d2h[data[i] >> 4], d2h[data[i] & 0xf]); + if (j % 4 == 3) + s_printf (" "); + } + s_printf ("\n"); + } + + for (i = 0; i < vg_message_cap_count (message); i ++) + s_printf ("cap %d: " ADDR_FMT "\n", + i, ADDR_PRINTF (vg_message_cap (message, i))); +} + + +#endif /* _VIENGOOS_MESSAGE_H */ diff --git a/libviengoos/viengoos/messenger.h b/libviengoos/viengoos/messenger.h new file mode 100644 index 0000000..fbdc5ff --- /dev/null +++ b/libviengoos/viengoos/messenger.h @@ -0,0 +1,87 @@ +/* messenger.h - Messenger buffer definitions. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Hurd. If not, see + . */ + +#ifndef _VIENGOOS_MESSENGER_H +#define _VIENGOOS_MESSENGER_H 1 + +#include +#include + +/* A messenger references a message buffer. It can transfer a message + (contained in its message buffer) to another messenger. It can + also receive a message from another messenger. A messenger can + block waiting to deliver a message to or receive a message from + another messenger. + + To send a message, a payload is loaded into a message buffer and + associated with a messenger. The messenger is then enqueued on + another messenger. When the latter messenger is unblocked, the + message is delivered. + + To avoid messages from being overwritten, messengers are blocked on + message delivery and must be explicitly unblocked before another + message is sent. */ +#ifdef RM_INTERN +struct messenger; +typedef struct messenger *vg_messenger_t; +#else +typedef addr_t vg_messenger_t; +#endif + +#define VG_MESSENGER_INLINE_WORDS 2 +#define VG_MESSENGER_INLINE_CAPS 1 + +/* Number of user-settable capability slots at the start of the + messenger structure. */ +enum + { + /* The thread to activate. */ + VG_MESSENGER_THREAD_SLOT = 0, + /* The address space root relative to which all capability + addresses in the message buffer will be resolved. */ + VG_MESSENGER_ASROOT_SLOT, + /* The assocaited message buffer. */ + VG_MESSENGER_BUFFER_SLOT, + /* The activity that was delivered with the last message. */ + VG_MESSENGER_ACTIVITY_SLOT, + + VG_MESSENGER_SLOTS = 4, + }; +#define VG_MESSENGER_SLOTS_LOG2 2 + +enum + { + VG_messenger_id = 900, + }; + +#define RPC_STUB_PREFIX vg +#define RPC_ID_PREFIX VG + +#include + +/* Set MESSENGER's ID to ID and return the old ID in OLD. */ +RPC(messenger_id, 1, 1, 0, + /* cap_t activity, cap_t messenger, */ + uint64_t, id, uint64_t, old) + +#undef RPC_STUB_PREFIX vg +#undef RPC_ID_PREFIX VG + +#endif /* _VIENGOOS_MESSENGER_H */ diff --git a/libviengoos/viengoos/misc.h b/libviengoos/viengoos/misc.h new file mode 100644 index 0000000..e367c19 --- /dev/null +++ b/libviengoos/viengoos/misc.h @@ -0,0 +1,128 @@ +/* rm.h - Resource manager interface. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + . */ + +#ifndef _VIENGOOS_MISC_H +#define _VIENGOOS_MISC_H + +#include +#include +#include +#include +#include +#include +#include + +enum rm_method_id + { + RM_write = 100, + RM_read, + RM_as_dump, + RM_fault, + }; + +static inline const char * +rm_method_id_string (int id) +{ + switch (id) + { + case RM_write: + return "write"; + case RM_read: + return "read"; + case RM_as_dump: + return "as_dump"; + case RM_fault: + return "fault"; + case RM_folio_alloc: + return "folio_alloc"; + case RM_folio_free: + return "folio_free"; + case RM_folio_object_alloc: + return "folio_object_alloc"; + case RM_folio_policy: + return "folio_policy"; + case RM_cap_copy: + return "cap_copy"; + case RM_cap_rubout: + return "cap_rubout"; + case RM_cap_read: + return "cap_read"; + case RM_object_discarded_clear: + return "object_discarded_clear"; + case RM_object_discard: + return "object_discard"; + case RM_object_status: + return "object_status"; + case RM_object_reply_on_destruction: + return "object_reply_on_destruction"; + case RM_object_name: + return "object_name"; + case RM_thread_exregs: + return "thread_exregs"; + case RM_thread_id: + return "thread_id"; + case RM_thread_activation_collect: + return "thread_activation_collect"; + case RM_activity_policy: + return "activity_policy"; + case RM_activity_info: + return "activity_info"; + case RM_futex: + return "futex"; + default: + return "unknown method id"; + } +} + +#define RPC_STUB_PREFIX rm +#define RPC_ID_PREFIX RM + +#include + +struct io_buffer +{ + /* The length. */ + unsigned char len; + char data[(L4_NUM_BRS - 2) * sizeof (uintptr_t)]; +}; + +/* Echo the character CHR on the manager console. */ +RPC(write, 1, 0, 0, struct io_buffer, io) + +/* Read up to MAX characters from the console's input device. */ +RPC(read, 1, 1, 0, + int, max, struct io_buffer, io) + +/* Dump the address space rooted at ROOT. */ +RPC(as_dump, 0, 0, 0, + /* cap_t, principal, cap_t, object */) + +/* Fault up to COUNT pages starting at START. Returns the number + actually faulted in OCOUNT. */ +RPC(fault, 2, 1, 0, + /* cap_t, principal, cap_t thread, */ + uintptr_t, start, int, count, + /* Out: */ + int, ocount) + +#undef RPC_STUB_PREFIX +#undef RPC_ID_PREFIX + +#endif diff --git a/libviengoos/viengoos/rpc.h b/libviengoos/viengoos/rpc.h new file mode 100644 index 0000000..14feddd --- /dev/null +++ b/libviengoos/viengoos/rpc.h @@ -0,0 +1,1054 @@ +/* rpc.h - RPC template definitions. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + This file is part of the GNU Hurd. + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GNU Hurd. If not, see + . */ + +#define RPC_CONCAT2(a,b) a##b +#define RPC_CONCAT(a,b) RPC_CONCAT2(a,b) + +/* If RPC_STUB_PREFIX is defined, the prefix prepended plus an + underscore to all function names. If using, don't forget to #undef + after all uses to avoid potential redefinition errors. */ +#undef RPC_STUB_PREFIX_ +#ifndef RPC_STUB_PREFIX +#define RPC_STUB_PREFIX_(x) x +#else +#define RPC_STUB_PREFIX_(name) RPC_CONCAT(RPC_STUB_PREFIX,_##name) +#endif + +/* If RPC_STUB_PREFIX is defined, the prefix prepended plus an + underscore to all function names. If using, don't forget to #undef + after all uses to avoid potential redefinition errors. */ +#undef RPC_ID_PREFIX_ +#ifndef RPC_ID_PREFIX +#define RPC_ID_PREFIX_(x) x +#else +#define RPC_ID_PREFIX_(name) RPC_CONCAT(RPC_ID_PREFIX,_##name) +#endif + +#ifndef _HURD_RPC_H +#define _HURD_RPC_H + +#include +#include +#include +#include + +#ifdef RM_INTERN +extern struct vg_message *reply_buffer; + +/* We can't include messenger.h as it includes hurd/cap.h which in turn + includes this file. */ +struct messenger; +struct activity; +extern bool messenger_message_load (struct activity *activity, + struct messenger *target, + struct vg_message *message); +#else +# include +#endif +typedef addr_t cap_t; + +/* First we define some cpp help macros. */ +#define CPP_IFELSE_0(when, whennot) whennot +#define CPP_IFELSE_1(when, whennot) when +#define CPP_IFELSE_2(when, whennot) when +#define CPP_IFELSE_3(when, whennot) when +#define CPP_IFELSE_4(when, whennot) when +#define CPP_IFELSE_5(when, whennot) when +#define CPP_IFELSE_6(when, whennot) when +#define CPP_IFELSE_7(when, whennot) when +#define CPP_IFELSE_8(when, whennot) when +#define CPP_IFELSE_9(when, whennot) when +#define CPP_IFELSE_10(when, whennot) when +#define CPP_IFELSE_11(when, whennot) when +#define CPP_IFELSE_12(when, whennot) when +#define CPP_IFELSE_13(when, whennot) when +#define CPP_IFELSE_14(when, whennot) when +#define CPP_IFELSE_15(when, whennot) when +#define CPP_IFELSE_16(when, whennot) when +#define CPP_IFELSE_17(when, whennot) when +#define CPP_IFELSE_18(when, whennot) when +#define CPP_IFELSE_19(when, whennot) when +#define CPP_IFELSE_20(when, whennot) when +#define CPP_IFELSE_21(when, whennot) when +#define CPP_IFELSE_22(when, whennot) when +#define CPP_IFELSE_23(when, whennot) when +#define CPP_IFELSE_24(when, whennot) when +#define CPP_IFELSE_25(when, whennot) when + +#define CPP_IFELSE_(expr, when, whennot) \ + CPP_IFELSE_##expr(when, whennot) +#define CPP_IFELSE(expr, when, whennot) \ + CPP_IFELSE_(expr, when, whennot) +#define CPP_IF(expr, when) \ + CPP_IFELSE(expr, when,) +#define CPP_IFNOT(expr, whennot) \ + CPP_IFELSE(expr, , whennot) + +#define CPP_SUCC_0 1 +#define CPP_SUCC_1 2 +#define CPP_SUCC_2 3 +#define CPP_SUCC_3 4 +#define CPP_SUCC_4 5 +#define CPP_SUCC_5 6 +#define CPP_SUCC_6 7 +#define CPP_SUCC_7 8 +#define CPP_SUCC_8 9 +#define CPP_SUCC_9 10 +#define CPP_SUCC_10 11 +#define CPP_SUCC_11 12 +#define CPP_SUCC_12 13 +#define CPP_SUCC_13 14 +#define CPP_SUCC_14 15 +#define CPP_SUCC_15 16 +#define CPP_SUCC_16 17 +#define CPP_SUCC_17 18 +#define CPP_SUCC_18 19 +#define CPP_SUCC_19 20 +#define CPP_SUCC_20 21 +#define CPP_SUCC_21 22 +#define CPP_SUCC_22 23 +#define CPP_SUCC_23 24 +#define CPP_SUCC_24 25 +#define CPP_SUCC_25 26 + +#define CPP_SUCC_(x) CPP_SUCC_##x +#define CPP_SUCC(x) CPP_SUCC_(x) + +/* We'd like to define CPP_ADD as: + + #define CPP_ADD(x, y) \ + CPP_IFELSE(y, CPP_ADD(SUCC(x), SUCC(y)), y) + + This does not work as while a macro is being expanded, it becomes + ineligible for expansion. Thus, any references (including indirect + references) are not expanded. Repeated applications of a macro are, + however, allowed, and this is what the CPP_APPLY macro does. */ +#define CPP_APPLY1(x, y) x(y) +#define CPP_APPLY2(x, y) x(CPP_APPLY1(x, y)) +#define CPP_APPLY3(x, y) x(CPP_APPLY2(x, y)) +#define CPP_APPLY4(x, y) x(CPP_APPLY3(x, y)) +#define CPP_APPLY5(x, y) x(CPP_APPLY4(x, y)) +#define CPP_APPLY6(x, y) x(CPP_APPLY5(x, y)) +#define CPP_APPLY7(x, y) x(CPP_APPLY6(x, y)) +#define CPP_APPLY8(x, y) x(CPP_APPLY7(x, y)) +#define CPP_APPLY9(x, y) x(CPP_APPLY8(x, y)) +#define CPP_APPLY10(x, y) x(CPP_APPLY9(x, y)) +#define CPP_APPLY11(x, y) x(CPP_APPLY10(x, y)) +#define CPP_APPLY12(x, y) x(CPP_APPLY11(x, y)) +#define CPP_APPLY13(x, y) x(CPP_APPLY12(x, y)) +#define CPP_APPLY14(x, y) x(CPP_APPLY13(x, y)) +#define CPP_APPLY15(x, y) x(CPP_APPLY14(x, y)) +#define CPP_APPLY16(x, y) x(CPP_APPLY15(x, y)) +#define CPP_APPLY17(x, y) x(CPP_APPLY16(x, y)) +#define CPP_APPLY18(x, y) x(CPP_APPLY17(x, y)) +#define CPP_APPLY19(x, y) x(CPP_APPLY18(x, y)) +#define CPP_APPLY20(x, y) x(CPP_APPLY19(x, y)) +#define CPP_APPLY21(x, y) x(CPP_APPLY20(x, y)) +#define CPP_APPLY22(x, y) x(CPP_APPLY21(x, y)) +#define CPP_APPLY23(x, y) x(CPP_APPLY22(x, y)) +#define CPP_APPLY24(x, y) x(CPP_APPLY23(x, y)) +#define CPP_APPLY25(x, y) x(CPP_APPLY24(x, y)) + +#define CPP_ADD(x, y) \ + CPP_IFELSE(y, CPP_APPLY##y(CPP_SUCC, x), x) + +/* Apply a function to each of the first n arguments. + + + CPP_FOREACH(2, CPP_SAFE_DEREF, NULL, a, b) + + => + + ((a) ? *(a) : NULL), ((b) ? *(b) : NULL) + */ +#define CPP_FOREACH_0(func, cookie, ...) +#define CPP_FOREACH_1(func, cookie, element, ...) func(cookie, element) +#define CPP_FOREACH_2(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_1(func, cookie, __VA_ARGS__) +#define CPP_FOREACH_3(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_2(func, cookie, __VA_ARGS__) +#define CPP_FOREACH_4(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_3(func, cookie, __VA_ARGS__) +#define CPP_FOREACH_5(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_4(func, cookie, __VA_ARGS__) +#define CPP_FOREACH_6(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_5(func, cookie, __VA_ARGS__) +#define CPP_FOREACH_7(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_6(func, cookie, __VA_ARGS__) +#define CPP_FOREACH_8(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_7(func, cookie, __VA_ARGS__) +#define CPP_FOREACH_9(func, cookie, element, ...) func(cookie, element), CPP_FOREACH_8(func, cookie, __VA_ARGS__) + +#define CPP_FOREACH_(n, func, cookie, ...) \ + CPP_FOREACH_##n(func, cookie, __VA_ARGS__) +#define CPP_FOREACH(n, func, cookie, ...) \ + CPP_FOREACH_(n, func, cookie, __VA_ARGS__) + +/* Used in conjunction with CPP_FOREACH. Generates C code that + dereferences ELEMENT if it is not NULL, otherwise, returns + COOKIE. */ +#define CPP_SAFE_DEREF(cookie, element) ((element) ? *(element) : (cookie)) + + +/* CPP treats commas specially so we have to be smart about how we + insert them algorithmically. For instance, this won't work: + + #define COMMA , + CPP_IFELSE(x, COMMA, ) + + To optional insert a comma, use this function instead. When the + result is need, invoke the result. For instance: + + RPC_IF_COMMA(x) () + */ +#define RPC_COMMA() , +#define RPC_NOCOMMA() +#define RPC_IF_COMMA(x) CPP_IFELSE(x, RPC_COMMA, RPC_NOCOMMA) + +/* Append the argument __RLA_ARG, whose type is __RLA_TYPE, to the + message buffer MSG. */ +#define RPCLOADARG(__rla_type, __rla_arg) \ + { \ + if (__builtin_strcmp (#__rla_type, "cap_t") == 0) \ + { \ + union \ + { \ + __rla_type __rla_a; \ + RPC_GRAB2 (, 1, RPC_TYPE_SHIFT (1, struct cap *, cap_t, __rla_foo)); \ + cap_t __rla_cap; \ + } __rla_arg2 = { (__rla_arg) }; \ + vg_message_append_cap (msg, __rla_arg2.__rla_cap); \ + } \ + else \ + { \ + union \ + { \ + __rla_type __rla_a; \ + uintptr_t __rla_raw[(sizeof (__rla_type) + sizeof (uintptr_t) - 1) \ + / sizeof (uintptr_t)]; \ + } __rla_arg2 = { (__rla_arg) }; \ + int __rla_i; \ + for (__rla_i = 0; \ + __rla_i < sizeof (__rla_arg2) / sizeof (uintptr_t); \ + __rla_i ++) \ + vg_message_append_word (msg, __rla_arg2.__rla_raw[__rla_i]); \ + } \ + } + +#define RPCLOAD0(...) +#define RPCLOAD1(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD0(__VA_ARGS__) +#define RPCLOAD2(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD1(__VA_ARGS__) +#define RPCLOAD3(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD2(__VA_ARGS__) +#define RPCLOAD4(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD3(__VA_ARGS__) +#define RPCLOAD5(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD4(__VA_ARGS__) +#define RPCLOAD6(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD5(__VA_ARGS__) +#define RPCLOAD7(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD6(__VA_ARGS__) +#define RPCLOAD8(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD7(__VA_ARGS__) +#define RPCLOAD9(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD8(__VA_ARGS__) +#define RPCLOAD10(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD9(__VA_ARGS__) +#define RPCLOAD11(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD10(__VA_ARGS__) +#define RPCLOAD12(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD11(__VA_ARGS__) +#define RPCLOAD13(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD12(__VA_ARGS__) +#define RPCLOAD14(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD13(__VA_ARGS__) +#define RPCLOAD15(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD14(__VA_ARGS__) +#define RPCLOAD16(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD15(__VA_ARGS__) +#define RPCLOAD17(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD16(__VA_ARGS__) +#define RPCLOAD18(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD17(__VA_ARGS__) +#define RPCLOAD19(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD18(__VA_ARGS__) +#define RPCLOAD20(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD19(__VA_ARGS__) +#define RPCLOAD21(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD20(__VA_ARGS__) +#define RPCLOAD22(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD21(__VA_ARGS__) +#define RPCLOAD23(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD22(__VA_ARGS__) +#define RPCLOAD24(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD23(__VA_ARGS__) +#define RPCLOAD25(__rl_type, __rl_arg, ...) RPCLOADARG(__rl_type, __rl_arg) RPCLOAD24(__VA_ARGS__) +#define RPCLOAD_(__rl_count, ...) RPCLOAD##__rl_count (__VA_ARGS__) +#define RPCLOAD(__rl_count, ...) RPCLOAD_ (__rl_count, __VA_ARGS__) + +/* Store the next argument in the message MSG whose type is __RSA_TYPE + in *__RSA_ARG. */ +#define RPCSTOREARG(__rsa_type, __rsa_arg) \ + { \ + if (__builtin_strcmp (#__rsa_type, "cap_t") == 0) \ + { \ + union \ + { \ + __rsa_type *__rsa_a; \ + cap_t *__rsa_cap; \ + } __rsa_arg2; \ + __rsa_arg2.__rsa_a = __rsa_arg; \ + if (vg_message_cap_count (msg) > __rsu_cap_idx) \ + { \ + if (__rsa_arg) \ + *__rsa_arg2.__rsa_cap = vg_message_cap (msg, __rsu_cap_idx); \ + __rsu_cap_idx ++; \ + } \ + else \ + __rsu_err = EINVAL; \ + } \ + else \ + { \ + union \ + { \ + __rsa_type __rsa_a; \ + uintptr_t __rsa_raw[(sizeof (__rsa_type) + sizeof (uintptr_t) - 1) \ + / sizeof (uintptr_t)]; \ + } __rsa_arg2; \ + int __rsa_i; \ + for (__rsa_i = 0; \ + __rsa_i < sizeof (__rsa_arg2) / sizeof (uintptr_t); \ + __rsa_i ++) \ + if (vg_message_data_count (msg) / sizeof (uintptr_t) \ + > __rsu_data_idx) \ + __rsa_arg2.__rsa_raw[__rsa_i] \ + = vg_message_word (msg, __rsu_data_idx ++); \ + else \ + __rsu_err = EINVAL; \ + if (! __rsu_err && __rsa_arg) \ + *(__rsa_arg) = __rsa_arg2.__rsa_a; \ + } \ + } + +#define RPCSTORE0(...) +#define RPCSTORE1(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE0(__VA_ARGS__) +#define RPCSTORE2(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE1(__VA_ARGS__) +#define RPCSTORE3(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE2(__VA_ARGS__) +#define RPCSTORE4(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE3(__VA_ARGS__) +#define RPCSTORE5(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE4(__VA_ARGS__) +#define RPCSTORE6(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE5(__VA_ARGS__) +#define RPCSTORE7(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE6(__VA_ARGS__) +#define RPCSTORE8(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE7(__VA_ARGS__) +#define RPCSTORE9(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE8(__VA_ARGS__) +#define RPCSTORE10(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE9(__VA_ARGS__) +#define RPCSTORE11(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE10(__VA_ARGS__) +#define RPCSTORE12(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE11(__VA_ARGS__) +#define RPCSTORE13(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE12(__VA_ARGS__) +#define RPCSTORE14(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE13(__VA_ARGS__) +#define RPCSTORE15(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE14(__VA_ARGS__) +#define RPCSTORE16(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE15(__VA_ARGS__) +#define RPCSTORE17(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE16(__VA_ARGS__) +#define RPCSTORE18(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE17(__VA_ARGS__) +#define RPCSTORE19(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE18(__VA_ARGS__) +#define RPCSTORE20(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE19(__VA_ARGS__) +#define RPCSTORE21(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE20(__VA_ARGS__) +#define RPCSTORE22(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE21(__VA_ARGS__) +#define RPCSTORE23(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE22(__VA_ARGS__) +#define RPCSTORE24(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE23(__VA_ARGS__) +#define RPCSTORE25(__rs_type, __rs_arg, ...) \ + RPCSTOREARG(__rs_type, __rs_arg) RPCSTORE24(__VA_ARGS__) + +#define RPCSTORE_(__rs_count, ...) RPCSTORE##__rs_count (__VA_ARGS__) +#define RPCSTORE(__rs_count, ...) RPCSTORE_ (__rs_count, __VA_ARGS__) + +/* Marshal a request. */ +#define RPC_SEND_MARSHAL(id, icount, ...) \ + static inline void \ + __attribute__((always_inline)) \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_marshal) \ + (struct vg_message *msg, \ + RPC_GRAB2 (, icount, ##__VA_ARGS__) RPC_IF_COMMA(icount) () \ + cap_t reply_messenger) \ + { \ + vg_message_clear (msg); \ + /* Add the label. */ \ + vg_message_append_word (msg, RPC_ID_PREFIX_(id)); \ + /* Then load the arguments. */ \ + RPCLOAD (icount, ##__VA_ARGS__); \ + /* Finally, add the reply messenger. */ \ + vg_message_append_cap (msg, reply_messenger); \ + } + +/* Unmarshal a request. */ +#define RPC_SEND_UNMARSHAL(id, icount, ...) \ + static inline error_t \ + __attribute__((always_inline)) \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_unmarshal) \ + (struct vg_message *msg, \ + RPC_GRAB2 (*, icount, ##__VA_ARGS__) RPC_IF_COMMA(icount) () \ + cap_t *reply_messenger) \ + { \ + uintptr_t label = 0; \ + if (likely (vg_message_data_count (msg) >= sizeof (uintptr_t))) \ + label = vg_message_word (msg, 0); \ + if (label != RPC_ID_PREFIX_(id)) \ + { \ + debug (1, #id " has bad method id, %d, excepted %d", \ + label, RPC_ID_PREFIX_(id)); \ + return EINVAL; \ + } \ + \ + int __rsu_data_idx __attribute__ ((unused)) = 1; \ + int __rsu_cap_idx __attribute__ ((unused)) = 0; \ + error_t __rsu_err = 0; \ + RPCSTORE (icount, ##__VA_ARGS__); \ + if (unlikely (__rsu_err \ + || (__rsu_data_idx * sizeof (uintptr_t) \ + != vg_message_data_count (msg) \ + && __rsu_cap_idx + 1 != vg_message_cap_count (msg)))) \ + { \ + debug (1, #id " has wrong number of arguments: " \ + "got %d bytes and %d caps; expected %d/%d", \ + __rsu_data_idx * sizeof (uintptr_t), __rsu_cap_idx + 1, \ + vg_message_data_count (msg), \ + vg_message_cap_count (msg)); \ + return EINVAL; \ + } \ + \ + if (reply_messenger) \ + *reply_messenger = vg_message_cap (msg, __rsu_cap_idx); \ + return 0; \ + } + +/* Prepare a receive buffer. */ +#ifdef RM_INTERN +#define RPC_RECEIVE_MARSHAL(id, ret_cap_count, ...) +#else +#define RPC_RECEIVE_MARSHAL(id, ret_cap_count, ...) \ + static inline void \ + __attribute__((always_inline)) \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _receive_marshal) \ + (struct vg_message *msg RPC_IF_COMMA(ret_cap_count) () \ + RPC_GRAB2 (, ret_cap_count, ##__VA_ARGS__)) \ + { \ + vg_message_clear (msg); \ + /* Load the arguments. */ \ + RPCLOAD (ret_cap_count, ##__VA_ARGS__); \ + assert (vg_message_data_count (msg) == 0); \ + assert (vg_message_cap_count (msg) == ret_cap_count); \ + } +#endif + +/* Marshal a reply. */ +#define RPC_REPLY_MARSHAL(id, out_count, ret_cap_count, ...) \ + static inline void \ + __attribute__((always_inline)) \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_marshal) \ + (struct vg_message *msg \ + RPC_IF_COMMA (out_count) () \ + RPC_GRAB2 (, out_count, ##__VA_ARGS__) \ + RPC_IF_COMMA (ret_cap_count) () \ + RPC_GRAB2 (, ret_cap_count, \ + RPC_TYPE_SHIFT (ret_cap_count, struct cap *, \ + RPC_CHOP2 (out_count, __VA_ARGS__)))) \ + { \ + vg_message_clear (msg); \ + \ + /* The error code. */ \ + vg_message_append_word (msg, 0); \ + RPCLOAD (CPP_ADD (out_count, ret_cap_count), ##__VA_ARGS__); \ + \ + assert (vg_message_cap_count (msg) == ret_cap_count); \ + } + +/* Unmarshal a reply. */ +#define RPC_REPLY_UNMARSHAL(id, out_count, ret_cap_count, ...) \ + static inline error_t \ + __attribute__((always_inline)) \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_unmarshal) \ + (struct vg_message *msg \ + RPC_IF_COMMA (CPP_ADD (out_count, ret_cap_count)) () \ + RPC_GRAB2(*, CPP_ADD (out_count, ret_cap_count), ##__VA_ARGS__)) \ + { \ + /* The server error code. */ \ + error_t __rsu_err = EINVAL; \ + if (likely (vg_message_data_count (msg) >= sizeof (uintptr_t))) \ + __rsu_err = vg_message_word (msg, 0); \ + if (unlikely (__rsu_err)) \ + return __rsu_err; \ + \ + int __rsu_data_idx __attribute__ ((unused)) = 1; \ + int __rsu_cap_idx __attribute__ ((unused)) = 0; \ + RPCSTORE (CPP_ADD (out_count, ret_cap_count), ##__VA_ARGS__); \ + if (unlikely (__rsu_err \ + || (__rsu_data_idx * sizeof (uintptr_t) \ + != vg_message_data_count (msg) \ + || __rsu_cap_idx != vg_message_cap_count (msg)))) \ + { \ + debug (1, #id " has wrong number of arguments: " \ + "got %d bytes and %d caps; expected %d/%d", \ + __rsu_data_idx * sizeof (uintptr_t), __rsu_cap_idx, \ + vg_message_data_count (msg), \ + vg_message_cap_count (msg)); \ + return EINVAL; \ + } \ + return 0; \ + } + +/* RPC_ARGUMENTS takes a list of types and arguments and returns the first + COUNT arguments. (NB: the list may contain more than COUNT + arguments!). + + RPC_ARGUMENTS(2, &, int, i, int, j, double, d) + + => + + &i, &j +*/ +#define RPC_ARGUMENTS0(...) +#define RPC_ARGUMENTS1(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg RPC_ARGUMENTS0(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS2(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS1(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS3(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS2(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS4(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS3(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS5(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS4(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS6(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS5(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS7(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS6(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS8(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS7(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS9(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS8(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS10(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS9(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS11(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS10(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS12(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS11(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS13(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS12(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS14(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS13(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS15(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS14(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS16(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS15(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS17(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS16(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS18(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS17(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS19(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS18(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS20(__ra_prefix, __ra_type, __ra_arg, ...) __ra_prefix __ra_arg, RPC_ARGUMENTS19(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS_(__ra_count, __ra_prefix, ...) RPC_ARGUMENTS##__ra_count(__ra_prefix, __VA_ARGS__) +#define RPC_ARGUMENTS(__ra_count, __ra_prefix, ...) RPC_ARGUMENTS_(__ra_count, __ra_prefix, __VA_ARGS__) + +/* Given a list of arguments, returns the arguments minus the first + COUNT **pairs** of arguments. For example: + + RPC_CHOP2(1, int, i, int, j, double, d) + + => + + int, j, double, d + + */ +#define RPC_CHOP2_0(...) __VA_ARGS__ +#define RPC_CHOP2_1(__rc_a, __rc_b, ...) RPC_CHOP2_0(__VA_ARGS__) +#define RPC_CHOP2_2(__rc_a, __rc_b, ...) RPC_CHOP2_1(__VA_ARGS__) +#define RPC_CHOP2_3(__rc_a, __rc_b, ...) RPC_CHOP2_2(__VA_ARGS__) +#define RPC_CHOP2_4(__rc_a, __rc_b, ...) RPC_CHOP2_3(__VA_ARGS__) +#define RPC_CHOP2_5(__rc_a, __rc_b, ...) RPC_CHOP2_4(__VA_ARGS__) +#define RPC_CHOP2_6(__rc_a, __rc_b, ...) RPC_CHOP2_5(__VA_ARGS__) +#define RPC_CHOP2_7(__rc_a, __rc_b, ...) RPC_CHOP2_6(__VA_ARGS__) +#define RPC_CHOP2_8(__rc_a, __rc_b, ...) RPC_CHOP2_7(__VA_ARGS__) +#define RPC_CHOP2_9(__rc_a, __rc_b, ...) RPC_CHOP2_8(__VA_ARGS__) +#define RPC_CHOP2_10(__rc_a, __rc_b, ...) RPC_CHOP2_9(__VA_ARGS__) +#define RPC_CHOP2_11(__rc_a, __rc_b, ...) RPC_CHOP2_10(__VA_ARGS__) +#define RPC_CHOP2_12(__rc_a, __rc_b, ...) RPC_CHOP2_11(__VA_ARGS__) +#define RPC_CHOP2_13(__rc_a, __rc_b, ...) RPC_CHOP2_12(__VA_ARGS__) +#define RPC_CHOP2_14(__rc_a, __rc_b, ...) RPC_CHOP2_13(__VA_ARGS__) +#define RPC_CHOP2_15(__rc_a, __rc_b, ...) RPC_CHOP2_14(__VA_ARGS__) +#define RPC_CHOP2_16(__rc_a, __rc_b, ...) RPC_CHOP2_15(__VA_ARGS__) +#define RPC_CHOP2_17(__rc_a, __rc_b, ...) RPC_CHOP2_16(__VA_ARGS__) +#define RPC_CHOP2_18(__rc_a, __rc_b, ...) RPC_CHOP2_17(__VA_ARGS__) +#define RPC_CHOP2_19(__rc_a, __rc_b, ...) RPC_CHOP2_18(__VA_ARGS__) +#define RPC_CHOP2_20(__rc_a, __rc_b, ...) RPC_CHOP2_19(__VA_ARGS__) +#define RPC_CHOP2_21(__rc_a, __rc_b, ...) RPC_CHOP2_20(__VA_ARGS__) +#define RPC_CHOP2_22(__rc_a, __rc_b, ...) RPC_CHOP2_21(__VA_ARGS__) +#define RPC_CHOP2_23(__rc_a, __rc_b, ...) RPC_CHOP2_22(__VA_ARGS__) +#define RPC_CHOP2_24(__rc_a, __rc_b, ...) RPC_CHOP2_23(__VA_ARGS__) +#define RPC_CHOP2_25(__rc_a, __rc_b, ...) RPC_CHOP2_24(__VA_ARGS__) +#define RPC_CHOP2_(__rc_count, ...) RPC_CHOP2_##__rc_count (__VA_ARGS__) +#define RPC_CHOP2(__rc_count, ...) RPC_CHOP2_(__rc_count, __VA_ARGS__) + +/* Given a list of arguments, returns the first COUNT **pairs** of + arguments, the elements of each pair separated by SEP and each pair + separated by a comma. For example: + + For example: + + RPC_GRAB2(, 2, int, i, int, j, double, d) + + => + + int i, int j +*/ +#define RPC_GRAB2_0(__rg_sep, ...) +#define RPC_GRAB2_1(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b RPC_GRAB2_0(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_2(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_1(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_3(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_2(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_4(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_3(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_5(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_4(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_6(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_5(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_7(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_6(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_8(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_7(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_9(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_8(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_10(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_9(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_11(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_10(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_12(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_11(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_13(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_12(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_14(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_13(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_15(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_14(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_16(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_15(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_17(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_16(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_18(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_17(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_19(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_18(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_20(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_19(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_21(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_20(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_22(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_21(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_23(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_22(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_24(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_23(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_25(__rg_sep, __rg_a, __rg_b, ...) __rg_a __rg_sep __rg_b, RPC_GRAB2_24(__rg_sep, __VA_ARGS__) +#define RPC_GRAB2_(__rg_sep, __rg_count, ...) RPC_GRAB2_##__rg_count (__rg_sep, __VA_ARGS__) +#define RPC_GRAB2(__rg_sep, __rg_count, ...) RPC_GRAB2_(__rg_sep, __rg_count, __VA_ARGS__) + +#define RPC_GRAB_0(...) +#define RPC_GRAB_1(__rg_a, ...) __rg_a RPC_GRAB_0(__VA_ARGS__) +#define RPC_GRAB_2(__rg_a, ...) __rg_a, RPC_GRAB_1(__VA_ARGS__) +#define RPC_GRAB_3(__rg_a, ...) __rg_a, RPC_GRAB_2(__VA_ARGS__) +#define RPC_GRAB_4(__rg_a, ...) __rg_a, RPC_GRAB_3(__VA_ARGS__) +#define RPC_GRAB_5(__rg_a, ...) __rg_a, RPC_GRAB_4(__VA_ARGS__) +#define RPC_GRAB_6(__rg_a, ...) __rg_a, RPC_GRAB_5(__VA_ARGS__) +#define RPC_GRAB_7(__rg_a, ...) __rg_a, RPC_GRAB_6(__VA_ARGS__) +#define RPC_GRAB_8(__rg_a, ...) __rg_a, RPC_GRAB_7(__VA_ARGS__) +#define RPC_GRAB_9(__rg_a, ...) __rg_a, RPC_GRAB_8(__VA_ARGS__) +#define RPC_GRAB_10(__rg_a, ...) __rg_a, RPC_GRAB_9(__VA_ARGS__) +#define RPC_GRAB_11(__rg_a, ...) __rg_a, RPC_GRAB_10(__VA_ARGS__) +#define RPC_GRAB_12(__rg_a, ...) __rg_a, RPC_GRAB_11(__VA_ARGS__) +#define RPC_GRAB_13(__rg_a, ...) __rg_a, RPC_GRAB_12(__VA_ARGS__) +#define RPC_GRAB_14(__rg_a, ...) __rg_a, RPC_GRAB_13(__VA_ARGS__) +#define RPC_GRAB_15(__rg_a, ...) __rg_a, RPC_GRAB_14(__VA_ARGS__) +#define RPC_GRAB_16(__rg_a, ...) __rg_a, RPC_GRAB_15(__VA_ARGS__) +#define RPC_GRAB_17(__rg_a, ...) __rg_a, RPC_GRAB_16(__VA_ARGS__) +#define RPC_GRAB_18(__rg_a, ...) __rg_a, RPC_GRAB_17(__VA_ARGS__) +#define RPC_GRAB_19(__rg_a, ...) __rg_a, RPC_GRAB_18(__VA_ARGS__) +#define RPC_GRAB_20(__rg_a, ...) __rg_a, RPC_GRAB_19(__VA_ARGS__) +#define RPC_GRAB_21(__rg_a, ...) __rg_a, RPC_GRAB_20(__VA_ARGS__) +#define RPC_GRAB_22(__rg_a, ...) __rg_a, RPC_GRAB_21(__VA_ARGS__) +#define RPC_GRAB_23(__rg_a, ...) __rg_a, RPC_GRAB_22(__VA_ARGS__) +#define RPC_GRAB_24(__rg_a, ...) __rg_a, RPC_GRAB_23(__VA_ARGS__) +#define RPC_GRAB_25(__rg_a, ...) __rg_a, RPC_GRAB_24(__VA_ARGS__) +#define RPC_GRAB_(__rg_count, ...) RPC_GRAB_##__rg_count (__VA_ARGS__) +#define RPC_GRAB(__rg_count, ...) RPC_GRAB_(__rg_count, __VA_ARGS__) + +#define RPC_TYPE_SHIFT_0(...) +#define RPC_TYPE_SHIFT_1(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg RPC_TYPE_SHIFT_0(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_2(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_1(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_3(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_2(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_4(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_3(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_5(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_4(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_6(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_5(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_7(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_6(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_8(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_7(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_9(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_8(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_10(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_9(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_11(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_10(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_12(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_11(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_13(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_12(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_14(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_13(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_15(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_14(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_16(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_15(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_17(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_16(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_18(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_17(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_19(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_18(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_20(__ra_new_type, __ra_type, __ra_arg, ...) __ra_new_type, __ra_arg, RPC_TYPE_SHIFT_19(__ra_new_type, __VA_ARGS__) +#define RPC_TYPE_SHIFT_(__ra_count, __ra_new_type, ...) RPC_TYPE_SHIFT_##__ra_count(__ra_new_type, __VA_ARGS__) +#ifdef RM_INTERN +# define RPC_TYPE_SHIFT(__ra_count, __ra_new_type, ...) RPC_TYPE_SHIFT_(__ra_count, __ra_new_type, __VA_ARGS__) +#else +# define RPC_TYPE_SHIFT(__ra_count, __ra_new_type, ...) __VA_ARGS__ +#endif + +/* Ensure that there are X pairs of arguments. */ +#define RPC_INVALID_NUMBER_OF_ARGUMENTS_ +#define RPC_EMPTY_LIST_(x) RPC_INVALID_NUMBER_OF_ARGUMENTS_##x +#define RPC_EMPTY_LIST(x) RPC_EMPTY_LIST_(x) +#define RPC_ENSURE_ARGS(count, ...) \ + RPC_EMPTY_LIST (RPC_CHOP2 (count, __VA_ARGS__)) + +#define RPC_SEND_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ...) \ + RPC_SEND_MARSHAL(id, in_count, ##__VA_ARGS__) \ + RPC_SEND_UNMARSHAL(id, in_count, ##__VA_ARGS__) + +#define RPC_RECEIVE_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ...) \ + RPC_RECEIVE_MARSHAL(id, ret_cap_count, \ + RPC_CHOP2 (CPP_ADD (in_count, out_count), \ + ##__VA_ARGS__)) + +#define RPC_REPLY_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ...) \ + RPC_REPLY_MARSHAL(id, out_count, ret_cap_count, \ + RPC_CHOP2 (in_count, ##__VA_ARGS__)) \ + RPC_REPLY_UNMARSHAL(id, out_count, ret_cap_count, \ + RPC_CHOP2 (in_count, ##__VA_ARGS__)) + +#define RPC_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ...) \ + RPC_ENSURE_ARGS(CPP_ADD (CPP_ADD (in_count, out_count), \ + ret_cap_count), \ + ##__VA_ARGS__) \ + RPC_SEND_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, \ + ##__VA_ARGS__) \ + RPC_RECEIVE_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, \ + ##__VA_ARGS__) \ + RPC_REPLY_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, \ + ##__VA_ARGS__) + +/* Send a message. __RPC_REPY_MESSENGER designates the messenger that + should receive the reply. (Its buffer should have already been + prepared using, e.g., the corresponding receive_marshal + function.) */ +#ifndef RM_INTERN +#define RPC_SEND_(postfix, id, in_count, out_count, ret_cap_count, ...) \ + static inline error_t \ + __attribute__((always_inline)) \ + RPC_CONCAT(RPC_STUB_PREFIX_(id), postfix) \ + (cap_t __rpc_activity, cap_t __rpc_object \ + RPC_IF_COMMA (in_count) () \ + RPC_GRAB2 (, in_count, __VA_ARGS__), \ + cap_t __rpc_reply_messenger) \ + { \ + struct hurd_message_buffer *mb = hurd_message_buffer_alloc (); \ + mb->just_free = true; \ + \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_marshal) \ + (mb->request \ + RPC_IF_COMMA (in_count) () RPC_ARGUMENTS(in_count,, __VA_ARGS__), \ + __rpc_reply_messenger); \ + \ + error_t err = vg_send (VG_IPC_SEND_SET_THREAD_TO_CALLER \ + | VG_IPC_SEND_SET_ASROOT_TO_CALLERS, \ + __rpc_activity, __rpc_object, \ + mb->sender, ADDR_VOID); \ + \ + return err; \ + } +#else +#define RPC_SEND_(postfix, id, in_count, out_count, ret_cap_count, ...) +#endif + +/* Send a message. Abort if the target is not ready. */ +#ifndef RM_INTERN +#define RPC_SEND_NONBLOCKING_(postfix, id, in_count, out_count, ret_cap_count, ...) \ + static inline error_t \ + __attribute__((always_inline)) \ + RPC_CONCAT(RPC_STUB_PREFIX_(id), postfix) \ + (cap_t __rpc_activity, cap_t __rpc_object \ + RPC_IF_COMMA (in_count) () \ + RPC_GRAB2 (, in_count, __VA_ARGS__), \ + cap_t __rpc_reply_messenger) \ + { \ + struct hurd_message_buffer *mb = hurd_message_buffer_alloc (); \ + \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_marshal) \ + (mb->request \ + RPC_IF_COMMA (in_count) () RPC_ARGUMENTS(in_count,, __VA_ARGS__), \ + __rpc_reply_messenger); \ + \ + error_t err = vg_reply (VG_IPC_SEND_SET_THREAD_TO_CALLER \ + | VG_IPC_SEND_SET_ASROOT_TO_CALLERS, \ + __rpc_activity, __rpc_object, \ + mb->sender, ADDR_VOID); \ + \ + hurd_message_buffer_free (mb); \ + \ + return err; \ + } +#else +#define RPC_SEND_NONBLOCKING_(postfix, id, in_count, out_count, ret_cap_count, ...) +#endif + +/* Send a message and wait for a reply. */ +#ifndef RM_INTERN +#define RPC_(postfix, id, in_count, out_count, ret_cap_count, ...) \ + static inline error_t \ + __attribute__((always_inline)) \ + RPC_CONCAT (RPC_CONCAT (RPC_STUB_PREFIX_(id), _using), postfix) \ + (struct hurd_message_buffer *mb, \ + addr_t __rpc_activity, \ + addr_t __rpc_object \ + /* In arguments. */ \ + RPC_IF_COMMA (in_count) () \ + RPC_GRAB2 (, in_count, __VA_ARGS__) \ + /* Out arguments (data and caps). */ \ + RPC_IF_COMMA (CPP_ADD (out_count, ret_cap_count)) () \ + RPC_GRAB2 (*, CPP_ADD (out_count, ret_cap_count), \ + RPC_CHOP2 (in_count, __VA_ARGS__))) \ + { \ + /* Prepare the reply buffer. */ \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _receive_marshal) \ + (mb->reply \ + RPC_IF_COMMA (ret_cap_count) () \ + CPP_FOREACH(ret_cap_count, CPP_SAFE_DEREF, ADDR_VOID, \ + RPC_ARGUMENTS (ret_cap_count, , \ + RPC_CHOP2 (CPP_ADD (in_count, out_count), \ + __VA_ARGS__)))); \ + \ + /* Then the send buffer. */ \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _send_marshal) \ + (mb->request \ + RPC_IF_COMMA (in_count) () \ + RPC_ARGUMENTS (in_count,, __VA_ARGS__), \ + mb->receiver); \ + \ + hurd_activation_message_register (mb); \ + \ + /* We will be resumed via an activation. */ \ + error_t err = vg_ipc (VG_IPC_RECEIVE | VG_IPC_SEND \ + | VG_IPC_RECEIVE_ACTIVATE \ + | VG_IPC_SEND_SET_THREAD_TO_CALLER \ + | VG_IPC_SEND_SET_ASROOT_TO_CALLERS \ + | VG_IPC_RECEIVE_SET_THREAD_TO_CALLER \ + | VG_IPC_RECEIVE_SET_ASROOT_TO_CALLERS, \ + __rpc_activity, \ + mb->receiver_strong, ADDR_VOID, \ + __rpc_activity, __rpc_object, \ + mb->sender, ADDR_VOID); \ + if (err) \ + /* Error sending the IPC. */ \ + hurd_activation_message_unregister (mb); \ + else \ + err = RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_unmarshal) \ + (mb->reply \ + RPC_IF_COMMA (CPP_ADD (out_count, ret_cap_count)) () \ + RPC_ARGUMENTS (CPP_ADD (out_count, ret_cap_count),, \ + RPC_CHOP2 (in_count, ##__VA_ARGS__))); \ + \ + return err; \ + } \ + \ + static inline error_t \ + __attribute__((always_inline)) \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), postfix) \ + (addr_t __rpc_activity, \ + addr_t __rpc_object \ + /* In arguments. */ \ + RPC_IF_COMMA (in_count) () \ + RPC_GRAB2 (, in_count, __VA_ARGS__) \ + /* Out arguments (data and caps). */ \ + RPC_IF_COMMA (CPP_ADD (out_count, ret_cap_count)) () \ + RPC_GRAB2 (*, CPP_ADD (out_count, ret_cap_count), \ + RPC_CHOP2 (in_count, __VA_ARGS__))) \ + { \ + struct hurd_message_buffer *mb = hurd_message_buffer_alloc (); \ + \ + error_t err; \ + err = RPC_CONCAT (RPC_CONCAT (RPC_STUB_PREFIX_(id), _using), postfix) \ + (mb, __rpc_activity, __rpc_object \ + RPC_IF_COMMA (CPP_ADD (CPP_ADD (in_count, out_count), \ + ret_cap_count)) () \ + RPC_ARGUMENTS (CPP_ADD (CPP_ADD (in_count, out_count), \ + ret_cap_count),, __VA_ARGS__)); \ + \ + hurd_message_buffer_free (mb); \ + \ + return err; \ + } +#else +# define RPC_(postfix, id, in_count, out_count, ret_cap_count, ...) +#endif + +/* Send a reply to __RPC_TARGET. If __RPC_TARGET does not accept the + message immediately, abort sending. */ +#ifndef RM_INTERN +#define RPC_REPLY_(id, in_count, out_count, ret_cap_count, ...) \ + static inline error_t \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply) \ + (addr_t __rpc_activity, \ + addr_t __rpc_target \ + /* Out data. */ \ + RPC_IF_COMMA (out_count) () \ + RPC_GRAB2 (, out_count, RPC_CHOP2 (in_count, ##__VA_ARGS__)) \ + /* Return capabilities. */ \ + RPC_IF_COMMA (ret_cap_count) () \ + RPC_GRAB2 (, ret_cap_count, \ + RPC_CHOP2 (CPP_ADD (in_count, out_count), \ + ##__VA_ARGS__))) \ + { \ + struct hurd_message_buffer *mb = hurd_message_buffer_alloc (); \ + \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_marshal) \ + (mb->request \ + /* Out data. */ \ + RPC_IF_COMMA (out_count) () \ + RPC_ARGUMENTS(out_count,, RPC_CHOP2 (in_count, __VA_ARGS__)) \ + /* Out capabilities. */ \ + RPC_IF_COMMA (ret_cap_count) () \ + RPC_ARGUMENTS(ret_cap_count,, \ + RPC_CHOP2 (CPP_ADD (in_count, out_count), \ + __VA_ARGS__))); \ + \ + error_t err = vg_reply (VG_IPC_SEND_SET_THREAD_TO_CALLER \ + | VG_IPC_SEND_SET_ASROOT_TO_CALLERS, \ + __rpc_activity, __rpc_target, \ + mb->sender, ADDR_VOID); \ + \ + hurd_message_buffer_free (mb); \ + \ + return err; \ + } +#else +#define RPC_REPLY_(id, in_count, out_count, ret_cap_count, ...) \ + static inline error_t \ + __attribute__((always_inline)) \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply) \ + (struct activity *__rpc_activity, \ + struct messenger *__rpc_target \ + /* Out data. */ \ + RPC_IF_COMMA (out_count) () \ + RPC_GRAB2 (, out_count, RPC_CHOP2 (in_count, ##__VA_ARGS__)) \ + /* Return capabilities. */ \ + RPC_IF_COMMA (ret_cap_count) () \ + RPC_GRAB2 (, ret_cap_count, \ + RPC_TYPE_SHIFT (ret_cap_count, struct cap, \ + RPC_CHOP2 (CPP_ADD (in_count, out_count), \ + ##__VA_ARGS__)))) \ + { \ + RPC_CONCAT (RPC_STUB_PREFIX_(id), _reply_marshal) \ + (reply_buffer \ + /* Out data. */ \ + RPC_IF_COMMA (out_count) () \ + RPC_ARGUMENTS(out_count,, RPC_CHOP2 (in_count, ##__VA_ARGS__)) \ + /* Out capabilities. */ \ + RPC_IF_COMMA (ret_cap_count) () \ + RPC_ARGUMENTS (ret_cap_count, &, \ + RPC_CHOP2 (CPP_ADD (in_count, out_count), \ + ##__VA_ARGS__))); \ + \ + bool ret = messenger_message_load (__rpc_activity, \ + __rpc_target, reply_buffer); \ + \ + return ret ? 0 : EWOULDBLOCK; \ + } +#endif + +/* RPC template. ID is the method name. IN_COUNT is the number of + arguments. OUT_COUNT is the number of out arguments. + RET_CAP_COUNT is the number of capabilities that are returned. The + remaining arguments correspond to pairs of types and argument + names. + + Consider: + + RPC(method, 2, 1, 1, + // In (data and capability) parameters + int, foo, cap_t, bar, + // Out data parameters + int bam, + // Out capabilities + cap_t xyzzy) + + This will generate marshalling and unmarshalling functions as well + as send, reply and call functions. For instance, the signature for + the correspond send marshal function is: + + error_t method_send_marshal (struct vg_message *message, + int foo, cap_t bar, cap_t reply) + + that of the send unmarshal function is: + + error_t method_send_unmarshal (struct vg_message *message, + int *foo, cap_t *bar, cap_t *reply) + + that of the receive marshal function is: + + error_t method_receive_marshal (struct vg_message *message, + cap_t xyzzy) + + + that of the reply marshal function is: + + error_t method_reply_marshal (struct vg_message *message, + int bam, cap_t xyzzy) + + that of the reply unmarshal function is: + + error_t method_reply_unmarshal (struct vg_message *message, + int *bam, cap_t *xyzzy) + + Functions to send requests and replies as well as to produce calls + are also generated. + + error_t method_call (cap_t activity, cap_t object, + int foo, cap_t bar, int *bam, cap_t *xyzzy) + + Note that *XYZZY must be initialize with the location of a + capability slot to store the returned capability. *XYZZY is set to + ADDR_VOID if the sender did not provide a capability. + + To send a message and not wait for a reply, a function with the + following prototype is generated: + + error_t method_send (cap_t activity, cap_t object, + int foo, cap_t bar, + cap_t reply_messenger) + + To reply to a request, a function with the following prototype is + generated: + + error_t method_reply (cap_t activity, cap_t reply_messenger, + int bam, cap_t xyzzy) +*/ + +#define RPC(id, in_count, out_count, ret_cap_count, ...) \ + RPC_MARSHAL_GEN_(id, in_count, out_count, ret_cap_count, ##__VA_ARGS__) \ + \ + RPC_(, id, in_count, out_count, ret_cap_count, ##__VA_ARGS__) \ + RPC_SEND_(_send, id, in_count, out_count, ret_cap_count, \ + ##__VA_ARGS__) \ + RPC_SEND_NONBLOCKING_(_send_nonblocking, \ + id, in_count, out_count, ret_cap_count, \ + ##__VA_ARGS__) \ + RPC_REPLY_(id, in_count, out_count, ret_cap_count, ##__VA_ARGS__) + +/* Marshal a reply consisting of the error code ERR in *MSG. */ +static inline void +__attribute__((always_inline)) +rpc_error_reply_marshal (struct vg_message *msg, error_t err) +{ + vg_message_clear (msg); + vg_message_append_word (msg, err); +} + +/* Reply to the target TARGET with error code ERROR. */ +#ifdef RM_INTERN +static inline error_t +__attribute__((always_inline)) +rpc_error_reply (struct activity *activity, struct messenger *target, + error_t err) +{ + rpc_error_reply_marshal (reply_buffer, err); + bool ret = messenger_message_load (activity, target, reply_buffer); + return ret ? 0 : EWOULDBLOCK; +} +#else +static inline error_t +__attribute__((always_inline)) +rpc_error_reply (cap_t activity, cap_t target, error_t err) +{ + return vg_ipc_short (VG_IPC_SEND_NONBLOCKING | VG_IPC_SEND_INLINE + | VG_IPC_SEND_INLINE_WORD1, + ADDR_VOID, ADDR_VOID, ADDR_VOID, + ADDR_VOID, target, + ADDR_VOID, err, 0, ADDR_VOID); +} +#endif + +#endif diff --git a/libviengoos/viengoos/thread.h b/libviengoos/viengoos/thread.h new file mode 100644 index 0000000..d8a69eb --- /dev/null +++ b/libviengoos/viengoos/thread.h @@ -0,0 +1,281 @@ +/* thread.h - Thread definitions. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield . + + GNU Hurd is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GNU Hurd. If not, see + . */ + +#ifndef __have_vg_thread_id_t +# define __have_vg_thread_id_t + +# ifdef USE_L4 +# include +typedef l4_thread_id_t vg_thread_id_t; +# define vg_niltid l4_nilthread +# define VG_THREAD_ID_FMT "%x" +# else +# include +typedef uint64_t vg_thread_id_t; +# define vg_niltid -1 +# define VG_THREAD_ID_FMT "%llx" +# endif + +#endif /* !__have_vg_thread_id_t */ + +#if defined(__need_vg_thread_id_t) +# undef __need_vg_thread_id_t +#else + +#ifndef _VIENGOOS_THREAD_H +#define _VIENGOOS_THREAD_H 1 + +#include +#include +#include +#include + +/* The user thread control block. */ +struct vg_utcb +{ + /* Generic data. */ + struct + { + union + { + struct + { + union + { + struct + { + /* Whether the thread is in activated mode. If so, any + activations that arrive during this time will be queued + or dropped. */ + uintptr_t activated_mode : 1; + /* Set by the kernel to indicated that there is a pending + message. */ + uintptr_t pending_message : 1; + /* Set by the kernel to indicate whether the thread was + interrupted while the EIP is in the transition range. */ + uintptr_t interrupt_in_transition : 1; + }; + uintptr_t mode; + }; + + /* The value of the IP and SP when the thread was running. */ + uintptr_t saved_ip; + uintptr_t saved_sp; + + uintptr_t activation_handler_sp; + uintptr_t activation_handler_ip; + uintptr_t activation_handler_end; + + /* The protected payload of the capability that invoked the + messenger that caused this activation. */ + uint64_t protected_payload; + /* The messenger's id. */ + uint64_t messenger_id; + + uintptr_t inline_words[VG_MESSENGER_INLINE_WORDS]; + addr_t inline_caps[VG_MESSENGER_INLINE_CAPS]; + + union + { + struct + { + int inline_word_count : 2; + int inline_cap_count : 1; + }; + int inline_data : 3; + }; + }; + + char data[256]; + }; + }; + + /* Architecture-specific data. */ + struct + { + union + { + struct + { + }; + + char data[256]; + }; + }; +}; + +/* A thread object's user accessible capability slots. */ +enum + { + /* Root of the address space. */ + THREAD_ASPACE_SLOT = 0, + /* The activity the thread is bound to. */ + THREAD_ACTIVITY_SLOT = 1, + /* The messenger to post exceptions to. */ + THREAD_EXCEPTION_MESSENGER = 2, + /* The user thread control block. Must be a cap_page. */ + THREAD_UTCB = 3, + + /* Total number of capability slots in a thread object. This must + be a power of 2. */ + THREAD_SLOTS = 4, + }; +#define THREAD_SLOTS_LOG2 2 + +enum +{ + HURD_EXREGS_SET_UTCB = 0x2000, + HURD_EXREGS_SET_EXCEPTION_MESSENGER = 0x1000, + HURD_EXREGS_SET_ASPACE = 0x800, + HURD_EXREGS_SET_ACTIVITY = 0x400, + HURD_EXREGS_SET_SP = _L4_XCHG_REGS_SET_SP, + HURD_EXREGS_SET_IP = _L4_XCHG_REGS_SET_IP, + HURD_EXREGS_SET_SP_IP = _L4_XCHG_REGS_SET_SP | _L4_XCHG_REGS_SET_IP, + HURD_EXREGS_SET_EFLAGS = _L4_XCHG_REGS_SET_FLAGS, + HURD_EXREGS_SET_USER_HANDLE = _L4_XCHG_REGS_SET_USER_HANDLE, + HURD_EXREGS_SET_REGS = (HURD_EXREGS_SET_UTCB + | HURD_EXREGS_SET_EXCEPTION_MESSENGER + | HURD_EXREGS_SET_ASPACE + | HURD_EXREGS_SET_ACTIVITY + | HURD_EXREGS_SET_SP + | HURD_EXREGS_SET_IP + | HURD_EXREGS_SET_EFLAGS + | HURD_EXREGS_SET_USER_HANDLE), + + HURD_EXREGS_GET_REGS = _L4_XCHG_REGS_DELIVER, + + HURD_EXREGS_START = _L4_XCHG_REGS_SET_HALT, + HURD_EXREGS_STOP = _L4_XCHG_REGS_SET_HALT | _L4_XCHG_REGS_HALT, + + HURD_EXREGS_ABORT_SEND = _L4_XCHG_REGS_CANCEL_SEND, + HURD_EXREGS_ABORT_RECEIVE = _L4_XCHG_REGS_CANCEL_RECV, + HURD_EXREGS_ABORT_IPC = HURD_EXREGS_ABORT_SEND | _L4_XCHG_REGS_CANCEL_RECV, +}; + +enum + { + RM_thread_exregs = 600, + RM_thread_id, + RM_thread_activation_collect, + }; + +#ifdef RM_INTERN +struct thread; +typedef struct thread *thread_t; +#else +typedef addr_t thread_t; +#endif + +#define RPC_STUB_PREFIX rm +#define RPC_ID_PREFIX RM + +#include + +struct hurd_thread_exregs_in +{ + uintptr_t aspace_cap_properties_flags; + struct cap_properties aspace_cap_properties; + + uintptr_t sp; + uintptr_t ip; + uintptr_t eflags; + uintptr_t user_handle; +}; + +struct hurd_thread_exregs_out +{ + uintptr_t sp; + uintptr_t ip; + uintptr_t eflags; + uintptr_t user_handle; +}; + +/* l4_exregs wrapper. */ +RPC (thread_exregs, 6, 1, 4, + /* cap_t principal, cap_t thread, */ + uintptr_t, control, struct hurd_thread_exregs_in, in, + cap_t, aspace, cap_t, activity, cap_t, utcb, cap_t, exception_messenger, + /* Out: */ + struct hurd_thread_exregs_out, out, + cap_t, aspace_out, cap_t, activity_out, cap_t, utcb_out, + cap_t, exception_messenger_out) + +static inline error_t +thread_start (addr_t thread) +{ + struct hurd_thread_exregs_in in; + struct hurd_thread_exregs_out out; + + return rm_thread_exregs (ADDR_VOID, thread, + HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC, + in, ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, + &out, NULL, NULL, NULL, NULL); +} + +static inline error_t +thread_start_sp_ip (addr_t thread, uintptr_t sp, uintptr_t ip) +{ + struct hurd_thread_exregs_in in; + struct hurd_thread_exregs_out out; + + in.sp = sp; + in.ip = ip; + + return rm_thread_exregs (ADDR_VOID, thread, + HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC + | HURD_EXREGS_SET_SP_IP, + in, ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, + &out, NULL, NULL, NULL, NULL); +} + +static inline error_t +thread_stop (addr_t thread) +{ + struct hurd_thread_exregs_in in; + struct hurd_thread_exregs_out out; + + return rm_thread_exregs (ADDR_VOID, thread, + HURD_EXREGS_STOP | HURD_EXREGS_ABORT_IPC, + in, ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID, + &out, NULL, NULL, NULL, NULL); +} + +/* Return the unique integer associated with thread THREAD. */ +RPC(thread_id, 0, 1, 0, + /* cap_t, principal, cap_t, thread, */ + vg_thread_id_t, tid) + +/* Cause the delivery of a pending message, if any. */ +RPC(thread_activation_collect, 0, 0, 0 + /* cap_t principal, cap_t thread */) + +#undef RPC_STUB_PREFIX +#undef RPC_ID_PREFIX + +static inline vg_thread_id_t +vg_myself (void) +{ + vg_thread_id_t tid; + error_t err = rm_thread_id (ADDR_VOID, ADDR_VOID, &tid); + if (err) + return vg_niltid; + return tid; +} + +#endif /* _VIENGOOS_THREAD_H */ +#endif /* __need_vg_thread_id_t */ diff --git a/newlib/addon/newlib/libc/sys/hurd/pipefile.c b/newlib/addon/newlib/libc/sys/hurd/pipefile.c index 1d01beb..f34d1a9 100644 --- a/newlib/addon/newlib/libc/sys/hurd/pipefile.c +++ b/newlib/addon/newlib/libc/sys/hurd/pipefile.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "fd.h" diff --git a/ruth/ruth.c b/ruth/ruth.c index 3cf48b2..656a25e 100644 --- a/ruth/ruth.c +++ b/ruth/ruth.c @@ -22,17 +22,17 @@ #include #endif +#include +#include +#include +#include #include #include -#include -#include -#include +#include #include #include #include #include -#include -#include #include #include @@ -1068,6 +1068,8 @@ main (int argc, char *argv[]) assert (! "Didn't fault!?"); } assert (faulted); + + printf ("ok.\n"); } debug (1, DEBUG_BOLD ("\n\nAll tests ran successfully to completion!\n\n")); diff --git a/viengoos/ChangeLog b/viengoos/ChangeLog index a2e5496..ea0d57a 100644 --- a/viengoos/ChangeLog +++ b/viengoos/ChangeLog @@ -1,3 +1,10 @@ +2008-12-17 Neal H. Walfield + + * rm.h: Move from here... + * ../libviengoos/viengoos/misc.h: ... to here. Update users. + * headers.m4: Don't link rm.h to hurd/rm.h. + * Makefile.am (viengoos_SOURCES): Remove rm.h. + 2008-12-16 Neal H. Walfield * thread.c (thread_activate): Don't update diff --git a/viengoos/Makefile.am b/viengoos/Makefile.am index c3d37df..d132605 100644 --- a/viengoos/Makefile.am +++ b/viengoos/Makefile.am @@ -41,7 +41,6 @@ viengoos_SOURCES = $(ARCH_SOURCES) \ panic.c \ sigma0.h sigma0.c \ zalloc.h zalloc.c \ - rm.h \ viengoos.h viengoos.c \ boot-modules.h boot-modules.c \ memory.h memory.c \ diff --git a/viengoos/activity.c b/viengoos/activity.c index acd8645..220b362 100644 --- a/viengoos/activity.c +++ b/viengoos/activity.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include "activity.h" #include "thread.h" diff --git a/viengoos/activity.h b/viengoos/activity.h index 983395a..745486f 100644 --- a/viengoos/activity.h +++ b/viengoos/activity.h @@ -21,7 +21,7 @@ #ifndef RM_ACTIVITY_H #define RM_ACTIVITY_H -#include +#include #include "cap.h" #include "object.h" diff --git a/viengoos/cap.c b/viengoos/cap.c index 2a9ae66..b765ae3 100644 --- a/viengoos/cap.c +++ b/viengoos/cap.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include "cap.h" #include "object.h" diff --git a/viengoos/cap.h b/viengoos/cap.h index deb8c59..609e4a1 100644 --- a/viengoos/cap.h +++ b/viengoos/cap.h @@ -22,7 +22,7 @@ #define RM_CAP_H #include -#include +#include /* The number of slots in a capability object of the given type. */ extern const int cap_type_num_slots[]; diff --git a/viengoos/headers.m4 b/viengoos/headers.m4 index 091ed24..ba32755 100644 --- a/viengoos/headers.m4 +++ b/viengoos/headers.m4 @@ -1,5 +1,5 @@ # headers.m4 - Autoconf snippets to install links for header files. -# Copyright 2007 Free Software Foundation, Inc. +# Copyright 2007, 2008 Free Software Foundation, Inc. # Written by Neal H. Walfield . # # This file is free software; as a special exception the author gives @@ -10,7 +10,7 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -AC_CONFIG_LINKS([sysroot/include/hurd/rm.h:viengoos/rm.h]) +# AC_CONFIG_LINKS([]) AC_CONFIG_COMMANDS_POST([ mkdir -p sysroot/lib viengoos && diff --git a/viengoos/messenger.c b/viengoos/messenger.c index fbcd58f..4e109a2 100644 --- a/viengoos/messenger.c +++ b/viengoos/messenger.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include "messenger.h" diff --git a/viengoos/messenger.h b/viengoos/messenger.h index abbf8ff..2ab669c 100644 --- a/viengoos/messenger.h +++ b/viengoos/messenger.h @@ -24,9 +24,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #ifndef NDEBUG #include "../viengoos/list.h" diff --git a/viengoos/object.c b/viengoos/object.c index c91ff45..5d11edd 100644 --- a/viengoos/object.c +++ b/viengoos/object.c @@ -22,9 +22,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/viengoos/object.h b/viengoos/object.h index 47f36b2..e8855f0 100644 --- a/viengoos/object.h +++ b/viengoos/object.h @@ -25,8 +25,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/viengoos/rm.h b/viengoos/rm.h deleted file mode 100644 index bef530e..0000000 --- a/viengoos/rm.h +++ /dev/null @@ -1,128 +0,0 @@ -/* rm.h - Resource manager interface. - Copyright (C) 2007, 2008 Free Software Foundation, Inc. - Written by Neal H. Walfield . - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 3 of the - License, or (at your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - . */ - -#ifndef RM_RM_H -#define RM_RM_H - -#include -#include -#include -#include -#include -#include -#include - -enum rm_method_id - { - RM_write = 100, - RM_read, - RM_as_dump, - RM_fault, - }; - -static inline const char * -rm_method_id_string (int id) -{ - switch (id) - { - case RM_write: - return "write"; - case RM_read: - return "read"; - case RM_as_dump: - return "as_dump"; - case RM_fault: - return "fault"; - case RM_folio_alloc: - return "folio_alloc"; - case RM_folio_free: - return "folio_free"; - case RM_folio_object_alloc: - return "folio_object_alloc"; - case RM_folio_policy: - return "folio_policy"; - case RM_cap_copy: - return "cap_copy"; - case RM_cap_rubout: - return "cap_rubout"; - case RM_cap_read: - return "cap_read"; - case RM_object_discarded_clear: - return "object_discarded_clear"; - case RM_object_discard: - return "object_discard"; - case RM_object_status: - return "object_status"; - case RM_object_reply_on_destruction: - return "object_reply_on_destruction"; - case RM_object_name: - return "object_name"; - case RM_thread_exregs: - return "thread_exregs"; - case RM_thread_id: - return "thread_id"; - case RM_thread_activation_collect: - return "thread_activation_collect"; - case RM_activity_policy: - return "activity_policy"; - case RM_activity_info: - return "activity_info"; - case RM_futex: - return "futex"; - default: - return "unknown method id"; - } -} - -#define RPC_STUB_PREFIX rm -#define RPC_ID_PREFIX RM - -#include - -struct io_buffer -{ - /* The length. */ - unsigned char len; - char data[(L4_NUM_BRS - 2) * sizeof (uintptr_t)]; -}; - -/* Echo the character CHR on the manager console. */ -RPC(write, 1, 0, 0, struct io_buffer, io) - -/* Read up to MAX characters from the console's input device. */ -RPC(read, 1, 1, 0, - int, max, struct io_buffer, io) - -/* Dump the address space rooted at ROOT. */ -RPC(as_dump, 0, 0, 0, - /* cap_t, principal, cap_t, object */) - -/* Fault up to COUNT pages starting at START. Returns the number - actually faulted in OCOUNT. */ -RPC(fault, 2, 1, 0, - /* cap_t, principal, cap_t thread, */ - uintptr_t, start, int, count, - /* Out: */ - int, ocount) - -#undef RPC_STUB_PREFIX -#undef RPC_ID_PREFIX - -#endif diff --git a/viengoos/server.c b/viengoos/server.c index 9a46efa..764ba25 100644 --- a/viengoos/server.c +++ b/viengoos/server.c @@ -20,15 +20,15 @@ #include #include -#include +#include #include #include -#include -#include -#include +#include +#include +#include #include #include -#include +#include #include "server.h" diff --git a/viengoos/thread.c b/viengoos/thread.c index 19fca5b..ec8080f 100644 --- a/viengoos/thread.c +++ b/viengoos/thread.c @@ -21,10 +21,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include diff --git a/viengoos/thread.h b/viengoos/thread.h index 3bcb91d..f869d0b 100644 --- a/viengoos/thread.h +++ b/viengoos/thread.h @@ -23,8 +23,8 @@ #include #include -#include -#include +#include +#include /* Forward. */ struct activity; diff --git a/viengoos/viengoos.c b/viengoos/viengoos.c index 8730f64..ccab7a5 100644 --- a/viengoos/viengoos.c +++ b/viengoos/viengoos.c @@ -39,7 +39,7 @@ int ss_lock_trace_count; #include #include -#include +#include #include #include -- cgit v1.2.3