static void
zonelow_expand(u32 size, u32 align)
{
- u32 oldpos = GET_PMMVAR(ZoneLow.cur);
- u32 newpos = ALIGN_DOWN(oldpos - size, align);
- u32 bottom = GET_PMMVAR(ZoneLow.bottom);
- if (newpos >= bottom && newpos <= oldpos)
- // Space already present.
- return;
+ u32 oldpos, newpos, bottom;
+ for (;;) {
+ oldpos = GET_PMMVAR(ZoneLow.cur);
+ newpos = ALIGN_DOWN(oldpos - size, align);
+ bottom = GET_PMMVAR(ZoneLow.bottom);
+ if (newpos >= bottom && newpos <= oldpos)
+ // Space already present.
+ return;
+ // Make sure to not move ebda while an optionrom is running.
+ if (likely(!wait_preempt()))
+ break;
+ }
u16 ebda_seg = get_ebda_seg();
u32 ebda_pos = (u32)MAKE_FLATPTR(ebda_seg, 0);
u8 ebda_size = GET_EBDA2(ebda_seg, size);
dprintf(1, "Done preempt - %d checks\n", PreemptCount);
}
+// Check if preemption is on, and wait for it to complete if so.
+int
+wait_preempt(void)
+{
+ if (MODESEGMENT || !CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS
+ || !CanPreempt)
+ return 0;
+ while (CanPreempt)
+ yield();
+ return 1;
+}
+
extern void yield_preempt(void);
#if MODESEGMENT == 0
// Try to execute 32bit threads.
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
#define NULL ((void*)0)
#define __weak __attribute__((weak))
void mutex_unlock(struct mutex_s *mutex);
void start_preempt(void);
void finish_preempt(void);
+int wait_preempt(void);
void check_preempt(void);
// output.c