Rev 3185 | Rev 3188 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3185 | Rev 3187 | ||
|---|---|---|---|
| Line 56... | Line 56... | ||
| 56 | #include <mm/as.h> |
56 | #include <mm/as.h> |
| 57 | #include <panic.h> |
57 | #include <panic.h> |
| 58 | #include <debug.h> |
58 | #include <debug.h> |
| 59 | #include <adt/list.h> |
59 | #include <adt/list.h> |
| 60 | #include <synch/spinlock.h> |
60 | #include <synch/spinlock.h> |
| - | 61 | #include <synch/mutex.h> |
|
| - | 62 | #include <synch/condvar.h> |
|
| 61 | #include <arch/asm.h> |
63 | #include <arch/asm.h> |
| 62 | #include <arch.h> |
64 | #include <arch.h> |
| 63 | #include <print.h> |
65 | #include <print.h> |
| 64 | #include <align.h> |
66 | #include <align.h> |
| 65 | #include <mm/slab.h> |
67 | #include <mm/slab.h> |
| Line 101... | Line 103... | ||
| 101 | zone_t *info[ZONES_MAX]; |
103 | zone_t *info[ZONES_MAX]; |
| 102 | } zones_t; |
104 | } zones_t; |
| 103 | 105 | ||
| 104 | static zones_t zones; |
106 | static zones_t zones; |
| 105 | 107 | ||
| - | 108 | /* |
|
| - | 109 | * Synchronization primitives used to sleep when there is no memory |
|
| - | 110 | * available. |
|
| - | 111 | */ |
|
| - | 112 | mutex_t zones_mtx; |
|
| - | 113 | condvar_t zones_cv; |
|
| - | 114 | int new_freed_mem = false; |
|
| 106 | 115 | ||
| 107 | /********************/ |
116 | /********************/ |
| 108 | /* Helper functions */ |
117 | /* Helper functions */ |
| 109 | /********************/ |
118 | /********************/ |
| 110 | 119 | ||
| Line 989... | Line 998... | ||
| 989 | zone = find_free_zone_and_lock(order, pzone); |
998 | zone = find_free_zone_and_lock(order, pzone); |
| 990 | } |
999 | } |
| 991 | } |
1000 | } |
| 992 | if (!zone) { |
1001 | if (!zone) { |
| 993 | /* |
1002 | /* |
| 994 | * TODO: Sleep until frames are available again. |
1003 | * Sleep until some frames are available again. |
| 995 | */ |
1004 | */ |
| - | 1005 | if (flags & FRAME_ATOMIC) { |
|
| 996 | interrupts_restore(ipl); |
1006 | interrupts_restore(ipl); |
| 997 | - | ||
| 998 | if (flags & FRAME_ATOMIC) |
- | |
| 999 | return 0; |
1007 | return 0; |
| - | 1008 | } |
|
| 1000 | 1009 | ||
| - | 1010 | #ifdef CONFIG_DEBUG |
|
| - | 1011 | printf("Thread %" PRIu64 " falling asleep, low memory.\n", THREAD->tid); |
|
| - | 1012 | #endif |
|
| - | 1013 | ||
| - | 1014 | mutex_lock(&zones_mtx); |
|
| - | 1015 | if (!new_freed_mem) |
|
| 1001 | panic("Sleep not implemented.\n"); |
1016 | condvar_wait(&zones_cv, &zones_mtx); |
| - | 1017 | new_freed_mem = false; |
|
| - | 1018 | mutex_unlock(&zones_mtx); |
|
| - | 1019 | ||
| - | 1020 | #ifdef CONFIG_DEBUG |
|
| - | 1021 | printf("Thread %" PRIu64 " woken up, memory available.\n", THREAD->tid); |
|
| - | 1022 | #endif |
|
| - | 1023 | ||
| - | 1024 | interrupts_restore(ipl); |
|
| 1002 | goto loop; |
1025 | goto loop; |
| 1003 | } |
1026 | } |
| 1004 | 1027 | ||
| 1005 | v = zone_frame_alloc(zone, order); |
1028 | v = zone_frame_alloc(zone, order); |
| 1006 | v += zone->base; |
1029 | v += zone->base; |
| Line 1026... | Line 1049... | ||
| 1026 | ipl_t ipl; |
1049 | ipl_t ipl; |
| 1027 | zone_t *zone; |
1050 | zone_t *zone; |
| 1028 | pfn_t pfn = ADDR2PFN(frame); |
1051 | pfn_t pfn = ADDR2PFN(frame); |
| 1029 | 1052 | ||
| 1030 | ipl = interrupts_disable(); |
1053 | ipl = interrupts_disable(); |
| 1031 | 1054 | ||
| 1032 | /* |
1055 | /* |
| 1033 | * First, find host frame zone for addr. |
1056 | * First, find host frame zone for addr. |
| 1034 | */ |
1057 | */ |
| 1035 | zone = find_zone_and_lock(pfn,NULL); |
1058 | zone = find_zone_and_lock(pfn, NULL); |
| 1036 | ASSERT(zone); |
1059 | ASSERT(zone); |
| 1037 | 1060 | ||
| 1038 | zone_frame_free(zone, pfn-zone->base); |
1061 | zone_frame_free(zone, pfn - zone->base); |
| 1039 | 1062 | ||
| 1040 | spinlock_unlock(&zone->lock); |
1063 | spinlock_unlock(&zone->lock); |
| - | 1064 | ||
| - | 1065 | /* |
|
| - | 1066 | * Signal that some memory has been freed. |
|
| - | 1067 | */ |
|
| - | 1068 | mutex_lock(&zones_mtx); |
|
| - | 1069 | new_freed_mem = true; |
|
| - | 1070 | condvar_broadcast(&zones_cv); |
|
| - | 1071 | mutex_unlock(&zones_mtx); |
|
| - | 1072 | ||
| 1041 | interrupts_restore(ipl); |
1073 | interrupts_restore(ipl); |
| 1042 | } |
1074 | } |
| 1043 | 1075 | ||
| 1044 | /** Add reference to frame. |
1076 | /** Add reference to frame. |
| 1045 | * |
1077 | * |
| Line 1114... | Line 1146... | ||
| 1114 | 1146 | ||
| 1115 | /* Black list first frame, as allocating NULL would |
1147 | /* Black list first frame, as allocating NULL would |
| 1116 | * fail in some places */ |
1148 | * fail in some places */ |
| 1117 | frame_mark_unavailable(0, 1); |
1149 | frame_mark_unavailable(0, 1); |
| 1118 | } |
1150 | } |
| - | 1151 | ||
| - | 1152 | mutex_initialize(&zones_mtx, MUTEX_ACTIVE); /* mimic spinlock */ |
|
| - | 1153 | condvar_initialize(&zones_cv); |
|
| 1119 | } |
1154 | } |
| 1120 | 1155 | ||
| 1121 | 1156 | ||
| 1122 | /** Return total size of all zones. */ |
1157 | /** Return total size of all zones. */ |
| 1123 | uint64_t zone_total_size(void) |
1158 | uint64_t zone_total_size(void) |